|
|
1.1 ! root 1: /* mail.cpp */ ! 2: ! 3: /* Synchronet mail-related routines */ ! 4: ! 5: /* $Id: mail.cpp,v 1.4 2000/11/04 12:03:50 rswindell Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #include "sbbs.h" ! 39: ! 40: /****************************************************************************/ ! 41: /* Returns the number of pieces of mail waiting for usernumber */ ! 42: /* If sent is non-zero, it returns the number of mail sent by usernumber */ ! 43: /* If usernumber is 0, it returns all mail on the system */ ! 44: /****************************************************************************/ ! 45: int DLLCALL getmail(scfg_t* cfg, int usernumber, BOOL sent) ! 46: { ! 47: char str[128]; ! 48: int i=0; ! 49: long l; ! 50: idxrec_t idx; ! 51: smb_t smb; ! 52: ! 53: sprintf(smb.file,"%smail",cfg->data_dir); ! 54: smb.retry_time=cfg->smb_retry_time; ! 55: sprintf(str,"%s.sid",smb.file); ! 56: l=flength(str); ! 57: if(l<sizeof(idxrec_t)) ! 58: return(0); ! 59: if(!usernumber) ! 60: return(l/sizeof(idxrec_t)); /* Total system e-mail */ ! 61: if(smb_open(&smb)!=0) ! 62: return(0); ! 63: while(!smb_feof(smb.sid_fp)) { ! 64: if(!smb_fread(&idx,sizeof(idxrec_t),smb.sid_fp)) ! 65: break; ! 66: if(idx.attr&MSG_DELETE) ! 67: continue; ! 68: if((!sent && idx.to==usernumber) ! 69: || (sent && idx.from==usernumber)) ! 70: i++; ! 71: } ! 72: smb_close(&smb); ! 73: return(i); ! 74: } ! 75: ! 76: ! 77: /***************************/ ! 78: /* Delete file attachments */ ! 79: /***************************/ ! 80: void sbbs_t::delfattach(uint to, char *title) ! 81: { ! 82: char str[128],str2[128],*tp,*sp,*p; ! 83: ! 84: strcpy(str,title); ! 85: tp=str; ! 86: while(1) { ! 87: p=strchr(tp,SP); ! 88: if(p) *p=0; ! 89: sp=strrchr(tp,'/'); /* sp is slash pointer */ ! 90: if(!sp) sp=strrchr(tp,'\\'); ! 91: if(sp) tp=sp+1; ! 92: sprintf(str2,"%sfile/%04u.in/%s" /* str2 is path/fname */ ! 93: ,cfg.data_dir,to,tp); ! 94: remove(str2); ! 95: if(!p) ! 96: break; ! 97: tp=p+1; } ! 98: sprintf(str,"%sfile/%04u.in",cfg.data_dir,to); ! 99: rmdir(str); /* remove the dir if it's empty */ ! 100: } ! 101: ! 102: ! 103: /****************************************************************************/ ! 104: /* Deletes all mail messages for usernumber that have been marked 'deleted' */ ! 105: /* smb_locksmbhdr() should be called prior to this function */ ! 106: /****************************************************************************/ ! 107: int sbbs_t::delmail(uint usernumber, int which) ! 108: { ! 109: ulong i,l,now; ! 110: idxrec_t HUGE16 *idxbuf; ! 111: smbmsg_t msg; ! 112: ! 113: now=time(NULL); ! 114: if((i=smb_getstatus(&smb))!=0) { ! 115: errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error); ! 116: return(2); } ! 117: if(!smb.status.total_msgs) ! 118: return(0); ! 119: if((idxbuf=(idxrec_t *)LMALLOC(smb.status.total_msgs*sizeof(idxrec_t)))==NULL) { ! 120: errormsg(WHERE,ERR_ALLOC,smb.file,smb.status.total_msgs*sizeof(idxrec_t)); ! 121: return(-1); } ! 122: if((i=smb_open_da(&smb))!=0) { ! 123: errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); ! 124: LFREE(idxbuf); ! 125: return(i); } ! 126: if((i=smb_open_ha(&smb))!=0) { ! 127: smb_close_da(&smb); ! 128: errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); ! 129: LFREE(idxbuf); ! 130: return(i); } ! 131: smb_rewind(smb.sid_fp); ! 132: for(l=0;l<smb.status.total_msgs;) { ! 133: if(!smb_fread(&msg.idx,sizeof(idxrec_t),smb.sid_fp)) ! 134: break; ! 135: if(which==MAIL_ALL && !(msg.idx.attr&MSG_PERMANENT) ! 136: && smb.status.max_age && now>msg.idx.time ! 137: && (now-msg.idx.time)/(24L*60L*60L)>smb.status.max_age) ! 138: msg.idx.attr|=MSG_DELETE; ! 139: if(msg.idx.attr&MSG_DELETE && !(msg.idx.attr&MSG_PERMANENT) ! 140: && ((which==MAIL_SENT && usernumber==msg.idx.from) ! 141: || (which==MAIL_YOUR && usernumber==msg.idx.to) ! 142: || (which==MAIL_ANY ! 143: && (usernumber==msg.idx.to || usernumber==msg.idx.from)) ! 144: || which==MAIL_ALL)) { ! 145: /* Don't need to lock message because base is locked */ ! 146: // if(which==MAIL_ALL && !online) ! 147: // lprintf(" #%lu",msg.idx.number); ! 148: if((i=smb_getmsghdr(&smb,&msg))!=0) ! 149: errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error); ! 150: else { ! 151: if(msg.hdr.attr!=msg.idx.attr) { ! 152: msg.hdr.attr=msg.idx.attr; ! 153: if((i=smb_putmsghdr(&smb,&msg))!=0) ! 154: errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); } ! 155: if((i=smb_freemsg(&smb,&msg))!=0) ! 156: errormsg(WHERE,ERR_REMOVE,smb.file,i,smb.last_error); ! 157: if(msg.hdr.auxattr&MSG_FILEATTACH) ! 158: delfattach(msg.idx.to,msg.subj); ! 159: smb_freemsgmem(&msg); } ! 160: continue; } ! 161: idxbuf[l]=msg.idx; ! 162: l++; } ! 163: smb_rewind(smb.sid_fp); ! 164: smb_fsetlength(smb.sid_fp,0); ! 165: for(i=0;i<l;i++) ! 166: smb_fwrite(&idxbuf[i],sizeof(idxrec_t),smb.sid_fp); ! 167: LFREE(idxbuf); ! 168: smb.status.total_msgs=l; ! 169: smb_putstatus(&smb); ! 170: smb_fflush(smb.sid_fp); ! 171: smb_close_ha(&smb); ! 172: smb_close_da(&smb); ! 173: return(0); ! 174: } ! 175: ! 176: ! 177: /***********************************************/ ! 178: /* Tell the user that so-and-so read your mail */ ! 179: /***********************************************/ ! 180: void sbbs_t::telluser(smbmsg_t* msg) ! 181: { ! 182: char str[256]; ! 183: uint usernumber,n; ! 184: node_t node; ! 185: ! 186: if(msg->from_net.type) ! 187: return; ! 188: if(msg->from_ext) ! 189: usernumber=atoi(msg->from_ext); ! 190: else { ! 191: usernumber=matchuser(&cfg,msg->from); ! 192: if(!usernumber) ! 193: return; } ! 194: for(n=1;n<=cfg.sys_nodes;n++) { /* Tell user */ ! 195: getnodedat(n,&node,0); ! 196: if(node.useron==usernumber ! 197: && (node.status==NODE_INUSE ! 198: || node.status==NODE_QUIET)) { ! 199: sprintf(str ! 200: ,text[UserReadYourMailNodeMsg] ! 201: ,cfg.node_num,useron.alias); ! 202: putnmsg(n,str); ! 203: break; } } ! 204: if(n>cfg.sys_nodes) { ! 205: now=time(NULL); ! 206: sprintf(str,text[UserReadYourMail] ! 207: ,useron.alias,timestr(&now)); ! 208: putsmsg(&cfg,usernumber,str); } ! 209: } ! 210: ! 211: /****************************************************************************/ ! 212: /* Loads mail waiting for user number 'usernumber' into the mail array of */ ! 213: /* of pointers to mail_t (message numbers and attributes) */ ! 214: /* smb_open(&smb) must be called prior */ ! 215: /****************************************************************************/ ! 216: mail_t* DLLCALL loadmail(smb_t* smb, ulong* msgs, uint usernumber ! 217: ,int which, long mode) ! 218: { ! 219: ulong l=0; ! 220: idxrec_t idx; ! 221: mail_t* mail=NULL; ! 222: ! 223: if(msgs==NULL) ! 224: return(NULL); ! 225: ! 226: *msgs=0; ! 227: ! 228: if(smb==NULL) ! 229: return(NULL); ! 230: ! 231: if(smb_locksmbhdr(smb)!=0) /* Be sure noone deletes or */ ! 232: return(NULL); /* adds while we're reading */ ! 233: ! 234: smb_rewind(smb->sid_fp); ! 235: while(!smb_feof(smb->sid_fp)) { ! 236: if(!smb_fread(&idx,sizeof(idxrec_t),smb->sid_fp)) ! 237: break; ! 238: if((which==MAIL_SENT && idx.from!=usernumber) ! 239: || (which==MAIL_YOUR && idx.to!=usernumber) ! 240: || (which==MAIL_ANY && idx.from!=usernumber && idx.to!=usernumber)) ! 241: continue; ! 242: if(idx.attr&MSG_DELETE && !(mode&LM_INCDEL)) /* Don't included deleted msgs */ ! 243: continue; ! 244: if(mode&LM_UNREAD && idx.attr&MSG_READ) ! 245: continue; ! 246: if((mail=(mail_t *)REALLOC(mail,sizeof(mail_t)*(l+1))) ! 247: ==NULL) { ! 248: smb_unlocksmbhdr(smb); ! 249: return(NULL); ! 250: } ! 251: mail[l].offset=idx.offset; ! 252: mail[l].number=idx.number; ! 253: mail[l].to=idx.to; ! 254: mail[l].from=idx.from; ! 255: mail[l].subj=idx.subj; ! 256: mail[l].time=idx.time; ! 257: mail[l].attr=idx.attr; ! 258: l++; } ! 259: smb_unlocksmbhdr(smb); ! 260: *msgs=l; ! 261: return(mail); ! 262: } ! 263: ! 264: extern "C" void DLLCALL freemail(mail_t* mail) ! 265: { ! 266: FREE(mail); ! 267: } ! 268: ! 269: /************************************************************************/ ! 270: /* Deletes all mail waiting for user number 'usernumber' */ ! 271: /************************************************************************/ ! 272: void sbbs_t::delallmail(uint usernumber) ! 273: { ! 274: int i; ! 275: ulong l,msgs,deleted=0; ! 276: mail_t *mail; ! 277: smbmsg_t msg; ! 278: ! 279: if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) { ! 280: errormsg(WHERE,ERR_OPEN,"MAIL",i); ! 281: return; } ! 282: sprintf(smb.file,"%smail",cfg.data_dir); ! 283: smb.retry_time=cfg.smb_retry_time; ! 284: if((i=smb_open(&smb))!=0) { ! 285: errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); ! 286: smb_stack(&smb,SMB_STACK_POP); ! 287: return; } ! 288: ! 289: mail=loadmail(&smb,&msgs,usernumber,MAIL_ANY,0); ! 290: if(!msgs) { ! 291: smb_close(&smb); ! 292: smb_stack(&smb,SMB_STACK_POP); ! 293: return; } ! 294: if((i=smb_locksmbhdr(&smb))!=0) { /* Lock the base, so nobody */ ! 295: smb_close(&smb); ! 296: smb_stack(&smb,SMB_STACK_POP); ! 297: FREE(mail); ! 298: errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); /* messes with the index */ ! 299: return; } ! 300: for(l=0;l<msgs;l++) { ! 301: msg.idx.offset=0; /* search by number */ ! 302: if(loadmsg(&msg,mail[l].number)) { /* message still there */ ! 303: msg.hdr.attr|=MSG_DELETE; ! 304: msg.hdr.attr&=~MSG_PERMANENT; ! 305: msg.idx.attr=msg.hdr.attr; ! 306: if((i=smb_putmsg(&smb,&msg))!=0) ! 307: errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); ! 308: else ! 309: deleted++; ! 310: smb_freemsgmem(&msg); ! 311: smb_unlockmsghdr(&smb,&msg); } } ! 312: ! 313: if(msgs) ! 314: FREE(mail); ! 315: if(deleted && cfg.sys_misc&SM_DELEMAIL) ! 316: delmail(usernumber,MAIL_ANY); ! 317: smb_unlocksmbhdr(&smb); ! 318: smb_close(&smb); ! 319: smb_stack(&smb,SMB_STACK_POP); ! 320: } ! 321:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.