|
|
1.1 root 1: #line 1 "MAIL.C"
2:
3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
4:
5: #include "sbbs.h"
6:
7: /****************************************************************************/
8: /* Returns the number of pieces of mail waiting for usernumber */
9: /* If sent is non-zero, it returns the number of mail sent by usernumber */
10: /* If usernumber is 0, it returns all mail on the system */
11: /****************************************************************************/
12: int getmail(int usernumber, char sent)
13: {
14: char str[128];
15: int i=0;
16: long l;
17: idxrec_t idx;
18:
19: smb_stack(&smb,SMB_STACK_PUSH);
20: sprintf(smb.file,"%sMAIL",data_dir);
21: smb.retry_time=smb_retry_time;
22: sprintf(str,"%s.SID",smb.file);
23: l=flength(str);
24: if(l<sizeof(idxrec_t))
25: return(0);
26: if(!usernumber) {
27: smb_stack(&smb,SMB_STACK_POP);
28: return(l/sizeof(idxrec_t)); } /* Total system e-mail */
29: if(smb_open(&smb)) {
30: smb_stack(&smb,SMB_STACK_POP);
31: return(0); }
32: while(!feof(smb.sid_fp)) {
33: if(!fread(&idx,sizeof(idxrec_t),1,smb.sid_fp))
34: break;
35: if(idx.attr&MSG_DELETE)
36: continue;
37: if((!sent && idx.to==usernumber)
38: || (sent && idx.from==usernumber))
39: i++; }
40: smb_close(&smb);
41: smb_stack(&smb,SMB_STACK_POP);
42: return(i);
43: }
44:
45: /***************************/
46: /* Delete file attachments */
47: /***************************/
48: void delfattach(uint to, char *title)
49: {
50: char str[128],str2[128],*tp,*sp,*p;
51: uint i;
52:
53: strcpy(str,title);
54: tp=str;
55: while(1) {
56: p=strchr(tp,SP);
57: if(p) *p=0;
58: sp=strrchr(tp,'/'); /* sp is slash pointer */
59: if(!sp) sp=strrchr(tp,'\\');
60: if(sp) tp=sp+1;
61: sprintf(str2,"%sFILE\\%04u.IN\\%s" /* str2 is path/fname */
62: ,data_dir,to,tp);
63: remove(str2);
64: if(!p)
65: break;
66: tp=p+1; }
67: sprintf(str,"%sFILE\\%04u.IN",data_dir,to);
68: rmdir(str); /* remove the dir if it's empty */
69: }
70:
71:
72: /****************************************************************************/
73: /* Deletes all mail messages for usernumber that have been marked 'deleted' */
74: /* smb_locksmbhdr() should be called prior to this function */
75: /****************************************************************************/
76: int delmail(uint usernumber, int which)
77: {
78: ulong i,l,now;
79: idxrec_t HUGE16 *idxbuf;
80: smbmsg_t msg;
81:
82: now=time(NULL);
83: if((i=smb_getstatus(&smb))!=0) {
84: errormsg(WHERE,ERR_READ,smb.file,i);
85: return(2); }
86: if(!smb.status.total_msgs)
87: return(0);
88: if((idxbuf=(idxrec_t *)LMALLOC(smb.status.total_msgs*sizeof(idxrec_t)))==NULL) {
89: errormsg(WHERE,ERR_ALLOC,smb.file,smb.status.total_msgs*sizeof(idxrec_t));
90: return(-1); }
91: if((i=smb_open_da(&smb))!=0) {
92: errormsg(WHERE,ERR_OPEN,smb.file,i);
93: LFREE(idxbuf);
94: return(i); }
95: if((i=smb_open_ha(&smb))!=0) {
96: smb_close_da(&smb);
97: errormsg(WHERE,ERR_OPEN,smb.file,i);
98: LFREE(idxbuf);
99: return(i); }
100: rewind(smb.sid_fp);
101: for(l=0;l<smb.status.total_msgs;) {
102: if(!fread(&msg.idx,sizeof(idxrec_t),1,smb.sid_fp))
103: break;
104: if(which==MAIL_ALL && !(msg.idx.attr&MSG_PERMANENT)
105: && smb.status.max_age && now>msg.idx.time
106: && (now-msg.idx.time)/(24L*60L*60L)>smb.status.max_age)
107: msg.idx.attr|=MSG_DELETE;
108: if(msg.idx.attr&MSG_DELETE && !(msg.idx.attr&MSG_PERMANENT)
109: && ((which==MAIL_SENT && usernumber==msg.idx.from)
110: || (which==MAIL_YOUR && usernumber==msg.idx.to)
111: || (which==MAIL_ANY
112: && (usernumber==msg.idx.to || usernumber==msg.idx.from))
113: || which==MAIL_ALL)) {
114: /* Don't need to lock message because base is locked */
115: if(which==MAIL_ALL && !online)
116: lprintf(" #%lu",msg.idx.number);
117: if((i=smb_getmsghdr(&smb,&msg))!=0)
118: errormsg(WHERE,ERR_READ,smb.file,i);
119: else {
120: if(msg.hdr.attr!=msg.idx.attr) {
121: msg.hdr.attr=msg.idx.attr;
122: if((i=smb_putmsghdr(&smb,&msg))!=0)
123: errormsg(WHERE,ERR_WRITE,smb.file,i); }
124: if((i=smb_freemsg(&smb,&msg))!=0)
125: errormsg(WHERE,ERR_REMOVE,smb.file,i);
126: if(msg.hdr.auxattr&MSG_FILEATTACH)
127: delfattach(msg.idx.to,msg.subj);
128: smb_freemsgmem(&msg); }
129: continue; }
130: idxbuf[l]=msg.idx;
131: l++; }
132: rewind(smb.sid_fp);
133: chsize(fileno(smb.sid_fp),0);
134: for(i=0;i<l;i++)
135: fwrite(&idxbuf[i],sizeof(idxrec_t),1,smb.sid_fp);
136: LFREE(idxbuf);
137: smb.status.total_msgs=l;
138: smb_putstatus(&smb);
139: fflush(smb.sid_fp);
140: smb_close_ha(&smb);
141: smb_close_da(&smb);
142: return(0);
143: }
144:
145:
146: /***********************************************/
147: /* Tell the user that so-and-so read your mail */
148: /***********************************************/
149: void telluser(smbmsg_t msg)
150: {
151: char str[256],*p;
152: uint usernumber,n;
153: node_t node;
154:
155: if(msg.from_net.type)
156: return;
157: if(msg.from_ext)
158: usernumber=atoi(msg.from_ext);
159: else {
160: usernumber=matchuser(msg.from);
161: if(!usernumber)
162: return; }
163: for(n=1;n<=sys_nodes;n++) { /* Tell user */
164: getnodedat(n,&node,0);
165: if(node.useron==usernumber
166: && (node.status==NODE_INUSE
167: || node.status==NODE_QUIET)) {
168: sprintf(str
169: ,text[UserReadYourMailNodeMsg]
170: ,node_num,useron.alias);
171: putnmsg(n,str);
172: break; } }
173: if(n>sys_nodes) {
174: now=time(NULL);
175: sprintf(str,text[UserReadYourMail]
176: ,useron.alias,timestr(&now));
177: putsmsg(usernumber,str); }
178: }
179:
180: /****************************************************************************/
181: /* Loads mail waiting for user number 'usernumber' into the mail array of */
182: /* of pointers to mail_t (message numbers and attributes) */
183: /* smb_open(&smb) must be called prior */
184: /****************************************************************************/
185: ulong loadmail(mail_t **mail, uint usernumber, int which, int mode)
186: {
187: int i;
188: ulong l=0;
189: idxrec_t idx;
190:
191: if((i=smb_locksmbhdr(&smb))!=0) { /* Be sure noone deletes or */
192: errormsg(WHERE,ERR_LOCK,smb.file,i); /* adds while we're reading */
193: return(0); }
194: (*mail)=NULL;
195: rewind(smb.sid_fp);
196: while(!feof(smb.sid_fp)) {
197: if(!fread(&idx,sizeof(idxrec_t),1,smb.sid_fp))
198: break;
199: if((which==MAIL_SENT && idx.from!=usernumber)
200: || (which==MAIL_YOUR && idx.to!=usernumber)
201: || (which==MAIL_ANY && idx.from!=usernumber && idx.to!=usernumber))
202: continue;
203: if(idx.attr&MSG_DELETE) {
204: if(mode&LM_QWK) /* Don't included deleted msgs */
205: continue; /* in QWK packet */
206: if(!(sys_misc&SM_SYSVDELM)) /* Noone can view deleted msgs */
207: continue;
208: if(!SYSOP /* not sysop */
209: && !(sys_misc&SM_USRVDELM)) /* users can't view deleted msgs */
210: continue; }
211: if(mode&LM_UNREAD && idx.attr&MSG_READ)
212: continue;
213: if(((*mail)=(mail_t *)REALLOC((*mail),sizeof(mail_t)*(l+1)))
214: ==NULL) {
215: smb_unlocksmbhdr(&smb);
216: errormsg(WHERE,ERR_ALLOC,smb.file,sizeof(mail_t)*(l+1));
217: return(i); }
218: (*mail)[l].offset=idx.offset;
219: (*mail)[l].number=idx.number;
220: (*mail)[l].to=idx.to;
221: (*mail)[l].from=idx.from;
222: (*mail)[l].subj=idx.subj;
223: (*mail)[l].time=idx.time;
224: (*mail)[l].attr=idx.attr;
225: l++; }
226: smb_unlocksmbhdr(&smb);
227: return(l);
228: }
229:
230: /************************************************************************/
231: /* Deletes all mail waiting for user number 'usernumber' */
232: /************************************************************************/
233: void delallmail(uint usernumber)
234: {
235: int i;
236: ulong l,msgs,deleted=0;
237: mail_t *mail;
238: smbmsg_t msg;
239:
240: if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) {
241: errormsg(WHERE,ERR_OPEN,"MAIL",i);
242: return; }
243: sprintf(smb.file,"%sMAIL",data_dir);
244: smb.retry_time=smb_retry_time;
245: if((i=smb_open(&smb))!=0) {
246: errormsg(WHERE,ERR_OPEN,smb.file,i);
247: smb_stack(&smb,SMB_STACK_POP);
248: return; }
249:
250: msgs=loadmail(&mail,usernumber,MAIL_ANY,0);
251: if(!msgs) {
252: smb_close(&smb);
253: smb_stack(&smb,SMB_STACK_POP);
254: return; }
255: if((i=smb_locksmbhdr(&smb))!=0) { /* Lock the base, so nobody */
256: smb_close(&smb);
257: smb_stack(&smb,SMB_STACK_POP);
258: FREE(mail);
259: errormsg(WHERE,ERR_LOCK,smb.file,i); /* messes with the index */
260: return; }
261: for(l=0;l<msgs;l++) {
262: msg.idx.offset=0; /* search by number */
263: if(loadmsg(&msg,mail[l].number)) { /* message still there */
264: msg.hdr.attr|=MSG_DELETE;
265: msg.hdr.attr&=~MSG_PERMANENT;
266: msg.idx.attr=msg.hdr.attr;
267: if((i=smb_putmsg(&smb,&msg))!=0)
268: errormsg(WHERE,ERR_WRITE,smb.file,i);
269: else
270: deleted++;
271: smb_freemsgmem(&msg);
272: smb_unlockmsghdr(&smb,&msg); } }
273:
274: if(msgs)
275: FREE(mail);
276: if(deleted && sys_misc&SM_DELEMAIL)
277: delmail(usernumber,MAIL_ANY);
278: smb_unlocksmbhdr(&smb);
279: smb_close(&smb);
280: smb_stack(&smb,SMB_STACK_POP);
281: }
282:
283: /****************************************************************************/
284: /* Reads mail waiting for usernumber. */
285: /****************************************************************************/
286: void readmail(uint usernumber, int which)
287: {
288: char str[256],str2[256],str3[256],done=0,domsg=1
289: ,*buf,*p,*tp,*sp,ch;
290: int file,msgs,curmsg,i,j,k,n,m,mismatches=0,act;
291: long length,l;
292: ulong last;
293: file_t fd;
294: mail_t *mail;
295: smbmsg_t msg;
296:
297: msg.total_hfields=0; /* init to NULL, cause not allocated yet */
298:
299: fd.dir=total_dirs+1; /* temp dir for file attachments */
300:
301: if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) {
302: errormsg(WHERE,ERR_OPEN,"MAIL",i);
303: return; }
304: sprintf(smb.file,"%sMAIL",data_dir);
305: smb.retry_time=smb_retry_time;
306: if((i=smb_open(&smb))!=0) {
307: smb_stack(&smb,SMB_STACK_POP);
308: errormsg(WHERE,ERR_OPEN,smb.file,i);
309: return; }
310:
311: msgs=loadmail(&mail,usernumber,which,0);
312: if(!msgs) {
313: if(which==MAIL_SENT)
314: bputs(text[NoMailSent]);
315: else if(which==MAIL_ALL)
316: bputs(text[NoMailOnSystem]);
317: else
318: bputs(text[NoMailWaiting]);
319: smb_close(&smb);
320: smb_stack(&smb,SMB_STACK_POP);
321: return; }
322:
323: last=smb.status.last_msg;
324:
325: if(which==MAIL_SENT)
326: act=NODE_RSML;
327: else if(which==MAIL_ALL)
328: act=NODE_SYSP;
329: else
330: act=NODE_RMAL;
331: action=act;
332: if(msgs>1 && which!=MAIL_ALL) {
333: if(which==MAIL_SENT)
334: bputs(text[MailSentLstHdr]);
335: else
336: bputs(text[MailWaitingLstHdr]);
337:
338: for(curmsg=0;curmsg<msgs && !msgabort();curmsg++) {
339: if(msg.total_hfields)
340: smb_freemsgmem(&msg);
341: msg.total_hfields=0;
342: msg.idx.offset=mail[curmsg].offset;
343: if(!loadmsg(&msg,mail[curmsg].number))
344: continue;
345: smb_unlockmsghdr(&smb,&msg);
346: bprintf(text[MailWaitingLstFmt],curmsg+1
347: ,which==MAIL_SENT ? msg.to
348: : (msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP ? text[Anonymous]
349: : msg.from
350: ,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_READ ? ' '
351: : msg.from_net.type || msg.to_net.type ? 'N':'*'
352: ,msg.subj);
353: smb_freemsgmem(&msg);
354: msg.total_hfields=0; }
355:
356: ASYNC;
357: if(!(sys_status&SS_ABORT)) {
358: bprintf(text[StartWithN],1L);
359: if((curmsg=getnum(msgs))>0)
360: curmsg--;
361: else if(curmsg==-1) {
362: FREE(mail);
363: smb_close(&smb);
364: smb_stack(&smb,SMB_STACK_POP);
365: return; } }
366: sys_status&=~SS_ABORT; }
367: else {
368: curmsg=0;
369: if(which==MAIL_ALL)
370: domsg=0; }
371: if(which==MAIL_SENT)
372: logline("E","Read sent mail");
373: else if(which==MAIL_ALL)
374: logline("S+","Read all mail");
375: else
376: logline("E","Read mail");
377: if(useron.misc&RIP) {
378: strcpy(str,which==MAIL_YOUR ? "MAILREAD" : which==MAIL_ALL ?
379: "ALLMAIL" : "SENTMAIL");
380: menu(str); }
381: while(online && !done) {
382: action=act;
383:
384: if(msg.total_hfields)
385: smb_freemsgmem(&msg);
386: msg.total_hfields=0;
387:
388: msg.idx.offset=mail[curmsg].offset;
389: msg.idx.number=mail[curmsg].number;
390: msg.idx.to=mail[curmsg].to;
391: msg.idx.from=mail[curmsg].from;
392: msg.idx.subj=mail[curmsg].subj;
393:
394: if((i=smb_locksmbhdr(&smb))!=0) {
395: errormsg(WHERE,ERR_LOCK,smb.file,i);
396: break; }
397:
398: if((i=smb_getstatus(&smb))!=0) {
399: smb_unlocksmbhdr(&smb);
400: errormsg(WHERE,ERR_READ,smb.file,i);
401: break; }
402: smb_unlocksmbhdr(&smb);
403:
404: if(smb.status.last_msg!=last) { /* New messages */
405: last=smb.status.last_msg;
406: FREE(mail);
407: msgs=loadmail(&mail,usernumber,which,0); /* So re-load */
408: if(!msgs)
409: break;
410: for(curmsg=0;curmsg<msgs;curmsg++)
411: if(mail[curmsg].number==msg.idx.number)
412: break;
413: if(curmsg>=msgs)
414: curmsg=(msgs-1);
415: continue; }
416:
417: if(!loadmsg(&msg,mail[curmsg].number)) { /* Message header gone */
418: if(mismatches>5) { /* We can't do this too many times in a row */
419: errormsg(WHERE,ERR_CHK,"message number",mail[curmsg].number);
420: break; }
421: FREE(mail);
422: msgs=loadmail(&mail,usernumber,which,0);
423: if(!msgs)
424: break;
425: if(curmsg>(msgs-1))
426: curmsg=(msgs-1);
427: mismatches++;
428: continue; }
429: smb_unlockmsghdr(&smb,&msg);
430: msg.idx.attr=msg.hdr.attr;
431:
432: mismatches=0;
433:
434: if(domsg && !(sys_status&SS_ABORT)) {
435:
436: show_msg(msg
437: ,msg.from_ext && msg.idx.from==1 && !msg.from_net.type
438: ? 0:P_NOATCODES);
439:
440: if(msg.hdr.auxattr&MSG_FILEATTACH) { /* Attached file */
441: smb_getmsgidx(&smb,&msg);
442: strcpy(str,msg.subj); /* filenames in title */
443: strupr(str);
444: tp=str;
445: while(online) {
446: p=strchr(tp,SP);
447: if(p) *p=0;
448: sp=strrchr(tp,'/'); /* sp is slash pointer */
449: if(!sp) sp=strrchr(tp,'\\');
450: if(sp) tp=sp+1;
451: padfname(tp,fd.name);
452: sprintf(str2,"%sFILE\\%04u.IN\\%s" /* str2 is path/fname */
453: ,data_dir,msg.idx.to,tp);
454: length=flength(str2);
455: if(length<1)
456: bputs(text[FileNotFound]);
457: else if(!(useron.exempt&FLAG('T')) && cur_cps && !SYSOP
458: && length/(ulong)cur_cps>timeleft)
459: bputs(text[NotEnoughTimeToDl]);
460: else {
461: sprintf(str3,text[DownloadAttachedFileQ]
462: ,tp,ultoac(length,tmp));
463: if(length>0L && yesno(str3)) {
464: if(online==ON_LOCAL) {
465: bputs(text[EnterPath]);
466: if(getstr(str3,60,K_LINE|K_UPPER)) {
467: backslashcolon(str3);
468: sprintf(tmp,"%s%s",str3,tp);
469: if(!mv(str2,tmp,which!=MAIL_YOUR)) {
470: logon_dlb+=length;
471: logon_dls++;
472: useron.dls=adjustuserrec(useron.number
473: ,U_DLS,5,1);
474: useron.dlb=adjustuserrec(useron.number
475: ,U_DLB,10,length);
476: bprintf(text[FileNBytesSent]
477: ,fd.name,ultoac(length,tmp)); } } }
478:
479: else { /* Remote User */
480: menu("DLPROT");
481: mnemonics(text[ProtocolOrQuit]);
482: strcpy(str3,"Q");
483: for(i=0;i<total_prots;i++)
484: if(prot[i]->dlcmd[0]
485: && chk_ar(prot[i]->ar,useron)) {
486: sprintf(tmp,"%c",prot[i]->mnemonic);
487: strcat(str3,tmp); }
488: ch=getkeys(str3,0);
489: for(i=0;i<total_prots;i++)
490: if(prot[i]->dlcmd[0] && ch==prot[i]->mnemonic
491: && chk_ar(prot[i]->ar,useron))
492: break;
493: if(i<total_prots) {
494: j=protocol(cmdstr(prot[i]->dlcmd,str2,nulstr
495: ,NULL),0);
496: if((prot[i]->misc&PROT_DSZLOG
497: && checkprotlog(fd))
498: || (!(prot[i]->misc&PROT_DSZLOG) && !j)) {
499: if(which==MAIL_YOUR)
500: remove(str2);
501: logon_dlb+=length; /* Update stats */
502: logon_dls++;
503: useron.dls=adjustuserrec(useron.number
504: ,U_DLS,5,1);
505: useron.dlb=adjustuserrec(useron.number
506: ,U_DLB,10,length);
507: bprintf(text[FileNBytesSent]
508: ,fd.name,ultoac(length,tmp));
509: sprintf(str3
510: ,"Downloaded attached file: %s"
511: ,fd.name);
512: logline("D-",str3); }
513: autohangup(); } } } }
514: if(!p)
515: break;
516: tp=p+1;
517: while(*tp==SP) tp++; }
518: sprintf(str,"%sFILE\\%04u.IN",data_dir,usernumber);
519: rmdir(str); }
520: if(which==MAIL_YOUR && !(msg.hdr.attr&MSG_READ)) {
521: if(thisnode.status==NODE_INUSE)
522: telluser(msg);
523: if(msg.total_hfields)
524: smb_freemsgmem(&msg);
525: msg.total_hfields=0;
526: msg.idx.offset=0; /* Search by number */
527: if(!smb_locksmbhdr(&smb)) { /* Lock the entire base */
528: if(loadmsg(&msg,msg.idx.number)) {
529: msg.hdr.attr|=MSG_READ;
530: msg.idx.attr=msg.hdr.attr;
531: if((i=smb_putmsg(&smb,&msg))!=0)
532: errormsg(WHERE,ERR_WRITE,smb.file,i);
533: smb_unlockmsghdr(&smb,&msg); }
534: smb_unlocksmbhdr(&smb); }
535: if(!msg.total_hfields) { /* unsuccessful reload */
536: domsg=0;
537: continue; } }
538: }
539: else domsg=1;
540:
541: if(useron.misc&WIP) {
542: strcpy(str,which==MAIL_YOUR ? "MAILREAD" : which==MAIL_ALL ?
543: "ALLMAIL" : "SENTMAIL");
544: menu(str); }
545:
546: ASYNC;
547: if(which==MAIL_SENT)
548: bprintf(text[ReadingSentMail],curmsg+1,msgs);
549: else if(which==MAIL_ALL)
550: bprintf(text[ReadingAllMail],curmsg+1,msgs);
551: else
552: bprintf(text[ReadingMail],curmsg+1,msgs);
553: sprintf(str,"ADFLNQRT?<>[]{}-+");
554: if(SYSOP)
555: strcat(str,"CUSP");
556: if(which!=MAIL_YOUR)
557: strcat(str,"E");
558: l=getkeys(str,msgs);
559: if(l&0x80000000L) {
560: if(l==-1) /* ctrl-c */
561: break;
562: curmsg=(l&~0x80000000L)-1;
563: continue; }
564: switch(l) {
565: case 'A': /* Auto-reply to last piece */
566: if(which==MAIL_SENT)
567: break;
568: if((msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP) {
569: bputs(text[CantReplyToAnonMsg]);
570: break; }
571:
572: quotemsg(msg,1);
573:
574: if(msg.from_net.type==NET_FIDO) /* FidoNet type */
575: sprintf(str,"%s @%s",msg.from
576: ,faddrtoa(*(faddr_t *)msg.from_net.addr));
577: else if(msg.from_net.type==NET_INTERNET)
578: strcpy(str,msg.from_net.addr);
579: else if(msg.from_net.type)
580: sprintf(str,"%s@%s",msg.from,msg.from_net.addr);
581: else /* No net */
582: strcpy(str,msg.from);
583:
584: strcpy(str2,str);
585:
586: bputs(text[Email]);
587: if(!getstr(str,64,K_EDIT|K_AUTODEL))
588: break;
589: msg.hdr.number=msg.idx.number;
590: smb_getmsgidx(&smb,&msg);
591:
592: if(!stricmp(str2,str)) /* Reply to sender */
593: sprintf(str2,text[Regarding],msg.subj);
594: else /* Reply to other */
595: sprintf(str2,text[RegardingBy],msg.subj,msg.from
596: ,timestr((time_t *)&msg.hdr.when_written.time));
597:
598: p=strrchr(str,'@');
599: if(p) { /* name @addr */
600: netmail(str,msg.subj,WM_QUOTE);
601: sprintf(str2,text[DeleteMailQ],msg.from); }
602: else {
603: if(!msg.from_net.type && !stricmp(str,msg.from))
604: email(msg.idx.from,str2,msg.subj,WM_EMAIL|WM_QUOTE);
605: else if(!stricmp(str,"SYSOP"))
606: email(1,str2,msg.subj,WM_EMAIL|WM_QUOTE);
607: else if((i=finduser(str))!=0)
608: email(i,str2,msg.subj,WM_EMAIL|WM_QUOTE);
609: sprintf(str2,text[DeleteMailQ],msg.from); }
610: if(!yesno(str2)) {
611: if(curmsg<msgs-1) curmsg++;
612: else done=1;
613: break; }
614: /* Case 'D': must follow! */
615: case 'D': /* Delete last piece (toggle) */
616: if(msg.hdr.attr&MSG_PERMANENT) {
617: bputs("\r\nPermanent message.\r\n");
618: domsg=0;
619: break; }
620: if(msg.total_hfields)
621: smb_freemsgmem(&msg);
622: msg.total_hfields=0;
623: msg.idx.offset=0;
624: if(loadmsg(&msg,msg.idx.number)) {
625: msg.hdr.attr^=MSG_DELETE;
626: msg.idx.attr=msg.hdr.attr;
627: // mail[curmsg].attr=msg.hdr.attr;
628: if((i=smb_putmsg(&smb,&msg))!=0)
629: errormsg(WHERE,ERR_WRITE,smb.file,i);
630: smb_unlockmsghdr(&smb,&msg); }
631: if(curmsg<msgs-1) curmsg++;
632: else done=1;
633: break;
634: case 'F': /* Forward last piece */
635: domsg=0;
636: bputs(text[ForwardMailTo]);
637: if(!getstr(str,LEN_ALIAS,K_UPRLWR))
638: break;
639: i=finduser(str);
640: if(!i)
641: break;
642: domsg=1;
643: if(curmsg<msgs-1) curmsg++;
644: else done=1;
645: smb_getmsgidx(&smb,&msg);
646: forwardmail(&msg,i);
647: if(msg.hdr.attr&MSG_PERMANENT)
648: break;
649: sprintf(str2,text[DeleteMailQ],msg.from);
650: if(!yesno(str2))
651: break;
652: if(msg.total_hfields)
653: smb_freemsgmem(&msg);
654: msg.total_hfields=0;
655: msg.idx.offset=0;
656: if(loadmsg(&msg,msg.idx.number)) {
657: msg.hdr.attr|=MSG_DELETE;
658: msg.idx.attr=msg.hdr.attr;
659: // mail[curmsg].attr=msg.hdr.attr;
660: if((i=smb_putmsg(&smb,&msg))!=0)
661: errormsg(WHERE,ERR_WRITE,smb.file,i);
662: smb_unlockmsghdr(&smb,&msg); }
663:
664: break;
665: case 'L': /* List mail */
666: domsg=0;
667: bprintf(text[StartWithN],(long)curmsg+1);
668: if((i=getnum(msgs))>0)
669: i--;
670: else if(i==-1)
671: break;
672: else
673: i=curmsg;
674: if(which==MAIL_SENT)
675: bputs(text[MailSentLstHdr]);
676: else if(which==MAIL_ALL)
677: bputs(text[MailOnSystemLstHdr]);
678: else
679: bputs(text[MailWaitingLstHdr]);
680: for(;i<msgs && !msgabort();i++) {
681: if(msg.total_hfields)
682: smb_freemsgmem(&msg);
683: msg.total_hfields=0;
684: msg.idx.offset=mail[i].offset;
685: if(!loadmsg(&msg,mail[i].number))
686: continue;
687: smb_unlockmsghdr(&smb,&msg);
688: if(which==MAIL_ALL)
689: bprintf(text[MailOnSystemLstFmt]
690: ,i+1,msg.from,msg.to
691: ,msg.hdr.attr&MSG_DELETE ? '-'
692: : msg.hdr.attr&MSG_READ ? SP
693: : msg.from_net.type || msg.to_net.type ? 'N':'*'
694: ,msg.subj);
695: else
696: bprintf(text[MailWaitingLstFmt],i+1
697: ,which==MAIL_SENT ? msg.to
698: : (msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP
699: ? text[Anonymous] : msg.from
700: ,msg.hdr.attr&MSG_DELETE ? '-'
701: : msg.hdr.attr&MSG_READ ? SP
702: : msg.from_net.type || msg.to_net.type ? 'N':'*'
703: ,msg.subj);
704: smb_freemsgmem(&msg);
705: msg.total_hfields=0; }
706: break;
707: case 'Q':
708: done=1;
709: break;
710: case 'C': /* Change attributes of last piece */
711: i=chmsgattr(msg.hdr.attr);
712: if(msg.hdr.attr==i)
713: break;
714: if(msg.total_hfields)
715: smb_freemsgmem(&msg);
716: msg.total_hfields=0;
717: msg.idx.offset=0;
718: if(loadmsg(&msg,msg.idx.number)) {
719: msg.hdr.attr=msg.idx.attr=i;
720: if((i=smb_putmsg(&smb,&msg))!=0)
721: errormsg(WHERE,ERR_WRITE,smb.file,i);
722: smb_unlockmsghdr(&smb,&msg); }
723: break;
724: case '>':
725: for(i=curmsg+1;i<msgs;i++)
726: if(mail[i].subj==msg.idx.subj)
727: break;
728: if(i<msgs)
729: curmsg=i;
730: else
731: domsg=0;
732: break;
733: case '<': /* Search Title backward */
734: for(i=curmsg-1;i>-1;i--)
735: if(mail[i].subj==msg.idx.subj)
736: break;
737: if(i>-1)
738: curmsg=i;
739: else
740: domsg=0;
741: break;
742: case '}': /* Search Author forward */
743: strcpy(str,msg.from);
744: for(i=curmsg+1;i<msgs;i++)
745: if(mail[i].from==msg.idx.from)
746: break;
747: if(i<msgs)
748: curmsg=i;
749: else
750: domsg=0;
751: break;
752: case 'N': /* Got to next un-read message */
753: for(i=curmsg+1;i<msgs;i++)
754: if(!(mail[i].attr&MSG_READ))
755: break;
756: if(i<msgs)
757: curmsg=i;
758: else
759: domsg=0;
760: break;
761: case '{': /* Search Author backward */
762: strcpy(str,msg.from);
763: for(i=curmsg-1;i>-1;i--)
764: if(mail[i].from==msg.idx.from)
765: break;
766: if(i>-1)
767: curmsg=i;
768: else
769: domsg=0;
770: break;
771: case ']': /* Search To User forward */
772: strcpy(str,msg.to);
773: for(i=curmsg+1;i<msgs;i++)
774: if(mail[i].to==msg.idx.to)
775: break;
776: if(i<msgs)
777: curmsg=i;
778: else
779: domsg=0;
780: break;
781: case '[': /* Search To User backward */
782: strcpy(str,msg.to);
783: for(i=curmsg-1;i>-1;i--)
784: if(mail[i].to==msg.idx.to)
785: break;
786: if(i>-1)
787: curmsg=i;
788: else
789: domsg=0;
790: break;
791: case 0:
792: case '+':
793: if(curmsg<msgs-1) curmsg++;
794: else done=1;
795: break;
796: case '-':
797: if(curmsg>0) curmsg--;
798: break;
799: case 'S':
800: domsg=0;
801: /*
802: if(!yesno(text[SaveMsgToFile]))
803: break;
804: */
805: bputs(text[FileToWriteTo]);
806: if(getstr(str,40,K_LINE|K_UPPER))
807: msgtotxt(msg,str,1,1);
808: break;
809: case 'E':
810: editmsg(&msg,INVALID_SUB);
811: break;
812: case 'T':
813: domsg=0;
814: i=curmsg;
815: if(i) i++;
816: j=i+10;
817: if(j>msgs)
818: j=msgs;
819:
820: if(which==MAIL_SENT)
821: bputs(text[MailSentLstHdr]);
822: else if(which==MAIL_ALL)
823: bputs(text[MailOnSystemLstHdr]);
824: else
825: bputs(text[MailWaitingLstHdr]);
826: for(;i<j;i++) {
827: if(msg.total_hfields)
828: smb_freemsgmem(&msg);
829: msg.total_hfields=0;
830: msg.idx.offset=mail[i].offset;
831: if(!loadmsg(&msg,mail[i].number))
832: continue;
833: smb_unlockmsghdr(&smb,&msg);
834: if(which==MAIL_ALL)
835: bprintf(text[MailOnSystemLstFmt]
836: ,i+1,msg.from,msg.to
837: ,msg.hdr.attr&MSG_DELETE ? '-'
838: : msg.hdr.attr&MSG_READ ? SP
839: : msg.from_net.type || msg.to_net.type ? 'N':'*'
840: ,msg.subj);
841: else
842: bprintf(text[MailWaitingLstFmt],i+1
843: ,which==MAIL_SENT ? msg.to
844: : (msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP
845: ? text[Anonymous] : msg.from
846: ,msg.hdr.attr&MSG_DELETE ? '-'
847: : msg.hdr.attr&MSG_READ ? SP
848: : msg.from_net.type || msg.to_net.type ? 'N':'*'
849: ,msg.subj);
850: smb_freemsgmem(&msg);
851: msg.total_hfields=0; }
852: curmsg=(i-1);
853: break;
854: case 'U': /* user edit */
855: msg.hdr.number=msg.idx.number;
856: smb_getmsgidx(&smb,&msg);
857: useredit(which==MAIL_SENT ? msg.idx.to : msg.idx.from,0);
858: break;
859: case 'P': /* Purge author and all mail to/from */
860: if(noyes(text[AreYouSureQ]))
861: break;
862: msg.hdr.number=msg.idx.number;
863: smb_getmsgidx(&smb,&msg);
864: purgeuser(msg.idx.from);
865: if(curmsg<msgs-1) curmsg++;
866: break;
867: case '?':
868: strcpy(str,which==MAIL_YOUR ? "MAILREAD" : which==MAIL_ALL
869: ? "ALLMAIL" : "SENTMAIL");
870: menu(str);
871: if(SYSOP && which==MAIL_SENT)
872: menu("SYSSMAIL");
873: else if(SYSOP && which==MAIL_YOUR)
874: menu("SYSMAILR"); /* Sysop Mail Read */
875: domsg=0;
876: break;
877: } }
878:
879: if(msg.total_hfields)
880: smb_freemsgmem(&msg);
881:
882: if(msgs)
883: FREE(mail);
884:
885: /***************************************/
886: /* Delete messages marked for deletion */
887: /***************************************/
888:
889: if(sys_misc&SM_DELEMAIL) {
890: if((i=smb_locksmbhdr(&smb))!=0) /* Lock the base, so nobody */
891: errormsg(WHERE,ERR_LOCK,smb.file,i); /* messes with the index */
892: else
893: delmail(usernumber,which); }
894:
895: smb_close(&smb);
896: smb_stack(&smb,SMB_STACK_POP);
897: }
898:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.