📄 mail-loadsave.c
字号:
/* TradeClient <http://tradeclient.sourceforge.net> * $Id: mail-loadsave.c,v 1.32 2001/03/20 22:19:33 ttabner Exp $ * * Copyright (C) 1999-2000 Bynari Inc. * Copyright (C) 2001 Project TradeClient * * LGPL * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library * General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "puma.h"#define EOW '\04'#define IO_CHUNK (64*1024)#define fw( v, n, f ) fwrite( &v, sizeof(v), n, f ) ;#define fws( v, n, f ) fwrite( v, (strlen(v)+1), n, f ) ;Folder *folder_list=NULL;int folder_add_new (char *name, unsigned long size) { Folder *newfolder, *flist=folder_list; if (flist==NULL) { flist=(Folder *)calloc (1, sizeof(Folder)); folder_list=flist; flist->prev=NULL; flist->next=NULL; flist->id=0; flist->flags=0; flist->asize=size; flist->name=strdup(name); flist->parent=NULL; flist->msglst=NULL; return flist->id; } else { newfolder=(Folder *)calloc (1, sizeof(Folder)); while (flist->next!=NULL) { flist=flist->next; } newfolder->prev=flist; flist->next=newfolder; newfolder->next=NULL; newfolder->id=flist->id+1; newfolder->flags=0; newfolder->asize=size; newfolder->name=strdup(name); newfolder->parent=NULL; newfolder->msglst=NULL; return newfolder->id; } return -1;}int folder_create (char *name, char *parent) { char *home; char *tmp; int id; int fd; Folder *fl; home=(char *)calloc(1024, sizeof(char)); snprintf (home, 1024, "$(HOME)"); env_srch_rep(home); tmp=(char *)calloc(1024, sizeof(char)); snprintf (tmp, 1024, "%s/.tradeclient/%s", home, name); fd=open (tmp, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); close (fd); id=folder_add_new (name, 0); fl=folder_seek (id); fl->parent=parent; fl->unread=0; fl->total=0; fl->flags=CAN_STORE_NEW_MAIL | CAN_HAVE_SUBFOLDERS; free (home); free (tmp); return fl->id;}Folder *folder_first () { return folder_list;}Folder *folder_seek (int id) { Folder *seek=folder_list; if( id != -1 ) { while (seek) { if (seek->id==id) return seek; seek=seek->next; } } return NULL;}int folder_seek_by_name (char *name) { Folder *seek=folder_list; if (!name) return -1; while (seek) { if((seek->name)&&(name)){ if (strcmp(seek->name,name)==0) return seek->id; seek=seek->next; } } return -1;}void folder_free (Folder *seek) { free (seek->name); free (seek->parent); message_list_destroy (seek); seek->prev=NULL; seek->next=NULL; free (seek);}void folder_delete (int id) { Folder *seek=folder_seek (id); Folder *ntmp, *ptmp; if (seek!=NULL) { if (seek==folder_list) folder_list=folder_list->next; ntmp=seek->next; ptmp=seek->prev; if (ntmp) ntmp->prev=ptmp; if (ptmp) ptmp->next=ntmp; folder_free (seek); }}int message_add_new (Folder *fl, unsigned long seek, unsigned long size, unsigned long hsize, unsigned long flags, unsigned long time, char *folder) { Message *newmsg, *mlist=fl->msglst; Folder *vfl; if (mlist==NULL) { mlist=(Message *)calloc (1, sizeof(Message)); fl->msglst=mlist; mlist->prev=NULL; mlist->next=NULL; mlist->id=0; mlist->seek=seek; mlist->size=size; mlist->hsize=hsize; mlist->flags=flags; mlist->folder=strdup (folder); mlist->from=NULL; mlist->subject=NULL; mlist->date=NULL; mlist->time=time; mlist->text=NULL; mlist->texttime=0; vfl=folder_seek (folder_seek_by_name (mlist->folder)); if (!vfl) { printf ("Error! Unable to find folder '%s'\n", mlist->folder); } else { vfl->total++; if (flags & MESSAGE_UNREAD) vfl->unread++; } return mlist->id; } else { newmsg=(Message *)calloc (1, sizeof(Message)); while (mlist->next!=NULL) { mlist=mlist->next; } newmsg->prev=mlist; mlist->next=newmsg; newmsg->next=NULL; newmsg->id=mlist->id+1; newmsg->seek=seek; newmsg->size=size; newmsg->hsize=hsize; newmsg->flags=flags; newmsg->folder=strdup (folder); newmsg->from=NULL; newmsg->subject=NULL; newmsg->date=NULL; newmsg->time=time; newmsg->text=NULL; newmsg->texttime=0; vfl=folder_seek (folder_seek_by_name (newmsg->folder)); if (!vfl) { printf ("Error! Unable to find folder '%s'\n", newmsg->folder); } else { vfl->total++; if (flags & MESSAGE_UNREAD) vfl->unread++; } return newmsg->id; } return -1;}Message *message_seek (Folder *fl, int id) { Message *seek ; if( (fl != NULL) || (id != -1) ) { seek = fl->msglst ; while (seek) { if (seek->id==id) return seek; seek=seek->next; } } return NULL;}void message_free (Message *msg) { if (msg!=NULL) { msg->prev=NULL; msg->next=NULL; msg->id=0; msg->seek=0; msg->size=0; msg->hsize=0; msg->flags=0; if (msg->folder!=NULL) free (msg->folder); if (msg->rfolder!=NULL) free (msg->rfolder); if (msg->from!=NULL) free (msg->from); if (msg->subject!=NULL) free (msg->subject); if (msg->priority!=NULL) free (msg->priority); if (msg->replyto!=NULL) free (msg->replyto); if (msg->sensitivity!=NULL) free (msg->sensitivity); if (msg->replyby!=NULL) free (msg->replyby); if (msg->expiry!=NULL) free (msg->expiry); if (msg->keywords!=NULL) free (msg->keywords); if (msg->date!=NULL) free (msg->date); if (msg->text) free (msg->text); if (msg->uidl) { free (msg->uidl); } free (msg); }}void message_delete (Folder *fl, int id) { Message *seek=message_seek (fl, id); Message *tmp; if (seek!=NULL) { if (seek==fl->msglst) { fl->msglst=seek->next; if (fl->msglst) fl->msglst->prev=NULL; } if (seek->next!=NULL) { tmp=seek->next; tmp->prev=seek->prev; } if (seek->prev!=NULL) { tmp=seek->prev; tmp->next=seek->next; } message_free (seek); }}void message_list_destroy (Folder *fl) { Message *seek=fl->msglst; Message *tmp; if (seek!=NULL) { while (seek->next) { tmp=seek->next; message_free (seek); seek=tmp; } }}void folders_read () { DIR *tdir; struct dirent *de; struct stat *st=(struct stat *)calloc(1, sizeof(struct stat)); char *dir; char *tmps=(char *)calloc(1024, sizeof(char)); dir=(char *)calloc(1024, sizeof(char)); snprintf (dir, 1024, "$(HOME)/.tradeclient"); env_srch_rep (dir); tdir=opendir (dir); if (tdir==NULL) { mkdir(dir, S_IREAD | S_IWRITE | S_IEXEC); tdir=opendir (dir); } while ((de=readdir(tdir))) { if (de->d_name[0]!='.') { snprintf (tmps, 1024, "%s/%s", dir, de->d_name); stat (tmps, st); if (S_ISREG(st->st_mode)) { folder_add_new (de->d_name, st->st_size); } } } closedir (tdir); free (st); free (dir); free (tmps);}unsigned long assemble_long (unsigned char *snum) { unsigned long ret=0; unsigned long tmpi=0; tmpi=snum[0]; ret=ret|((tmpi<<24)&0xFF000000); tmpi=snum[1]; ret=ret|((tmpi<<16)&0x00FF0000); tmpi=snum[2]; ret=ret|((tmpi<<8) &0x0000FF00); tmpi=snum[3]; ret=ret| (tmpi &0x000000FF); return ret;}char *disassemble_long (unsigned long num) { char *ret=(char *)calloc(5, sizeof(char));#if DEBUG > 7 char *bits=bits32(num); printf ("bits befor=%s\n", bits); free (bits);#endif ret[0]=(num&0xff000000)>>24; ret[1]=(num&0x00ff0000)>>16; ret[2]=(num&0x0000ff00)>>8; ret[3]=(num&0x000000ff);#if DEBUG > 7 bits=bits8(((int)ret[0])); printf ("bits after=%s", bits); free (bits); bits=bits8(((int)ret[1])); printf ("%s", bits); free (bits); bits=bits8(((int)ret[2])); printf ("%s", bits); free (bits); bits=bits8(((int)ret[3])); printf ("%s\n", bits); free (bits);#endif return ret;}/* * Completely new index functions to replace the completely lame index code * that was previously in place. I can't for the life of me imagine why * anyone would do byte at a time I/O and not expect to get slammed for it!!! * Additionally, some dummy decided that we'll have distinct indecies, but * maintain everything in memory in a single list. Duh! * * At any rate, this will be a new implemention of the current logic (highly * optimized) with only minor departures. Once the current implementation * is better understood, and give allows, the optimizations will be complete, * which should yield MUCH better results. The next thing to do here is to * optimize the folder opening code. Between these two, things should be * TONS faster when dealing with large folders. * * This function returns the number of index nodes that were written out. */#if 0intnew_index_write( pfile *pf, Folder *fl ){ int ret ; FILE *f ; Message *msg ; ret = 0 ; f = pf -> fs ; msg = (Message *)NULL ; /* * Write the index version that we are using. Versions < 2 are crap. * Version 2 is ALL good. Version 3 should be full implementation of a good index scheme by then. * Notice that we null terminate and make it 5-bytes long now. */ fws( "0002\x00", 1, f ) ; /* Okay, write the name of the parent folder, if there is a parent. Notice the NULL is also written. */ if( fl -> parent ) { fws( fl -> parent, 1, f ) ; } else fws( "", 1, f ) ; /* * Now, write the current value of FLAGS. I personally don't care if different * platforms can share index files. In theory, they can be rebuilt for each message * store, so it's a totally lame idea that simply wastes more CPU. */ fw( fl -> flags, 1, f ) ; msg = fl -> msglst ; while( msg ) { /* Write out various msg attributes */ fw( msg -> seek, 1, f ) ; fw( msg -> size, 1, f ) ; fw( msg -> hsize, 1, f ) ; fw( msg -> flags, 1, f ) ; fw( msg -> time, 1, f ) ; /* Folder name that this message belongs to --hhmmmm */ fws( msg -> folder, 1, f ) ; fws( msg -> subject, 1, f ) ; fws( msg -> date, 1, f ) ; fws( msg -> uidl, 1, f ) ; /* Not really sure why the UIDL is indexed at the moment. */ ret++ ; msg = msg -> next ; } return ret ;}#endifvoid index_write (pfile *pf, Folder *fl) { char *sep=(char *)calloc(2, sizeof(char)); char *snum; Message *mseek; sep[0]=EOW; if (fl->parent) fwrite (fl->parent, strlen(fl->parent), 1, pf->fs); fwrite (sep, 1, 1, pf->fs); fwrite ("0006", 4, 1, pf->fs); snum=disassemble_long (fl->flags); fwrite (snum, 4, 1, pf->fs); free (snum); mseek=fl->msglst; while (mseek) { snum=disassemble_long (mseek->seek); fwrite (snum, 4, sizeof (char), pf->fs); free (snum); snum=disassemble_long (mseek->size); fwrite (snum, 4, sizeof (char), pf->fs); free (snum); snum=disassemble_long (mseek->hsize); fwrite (snum, 4, sizeof (char), pf->fs); free (snum); snum=disassemble_long (mseek->flags); fwrite (snum, 4, sizeof (char), pf->fs); free (snum); snum=disassemble_long (mseek->time); fwrite (snum, 4, sizeof (char), pf->fs); free (snum); fwrite (mseek->folder, strlen(mseek->folder), 1, pf->fs); fwrite (sep, 1, 1, pf->fs); if (mseek->from) fwrite (mseek->from, strlen(mseek->from), 1, pf->fs); fwrite (sep, 1, 1, pf->fs); if (mseek->subject) fwrite (mseek->subject, strlen(mseek->subject), 1, pf->fs); fwrite (sep, 1, 1, pf->fs); if (mseek->priority) fwrite (mseek->priority, strlen(mseek->priority), 1, pf->fs); fwrite (sep, 1, 1, pf->fs); if (mseek->replyto) fwrite (mseek->replyto, strlen(mseek->replyto), 1, pf->fs); fwrite (sep, 1, 1, pf->fs); if (mseek->sensitivity) fwrite (mseek->sensitivity, strlen(mseek->sensitivity), 1, pf->fs); fwrite (sep, 1, 1, pf->fs); if (mseek->expiry) fwrite (mseek->expiry, strlen(mseek->expiry), 1, pf->fs); fwrite (sep, 1, 1, pf->fs); if (mseek->replyby) fwrite (mseek->replyby, strlen(mseek->replyby), 1, pf->fs); fwrite (sep, 1, 1, pf->fs); if (mseek->keywords) fwrite (mseek->keywords, strlen(mseek->keywords), 1, pf->fs); fwrite (sep, 1, 1, pf->fs); if (mseek->date) fwrite (mseek->date, strlen(mseek->date), 1, pf->fs); fwrite (sep, 1, 1, pf->fs); if (mseek->uidl) fwrite (mseek->uidl, strlen(mseek->uidl), 1, pf->fs); fwrite (sep, 1, 1, pf->fs);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -