|
|
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.