|
|
1.1 root 1: /*
2: * Package to maintain the temporary file.
3: */
4: #include <stdio.h>
5: #include <signal.h>
6: #include "letter.h"
7: #include "mail.h"
8: #include "string.h"
9:
10: /* imports */
11: extern char *mktemp();
12: extern int panic();
13:
14: /* globals */
15: static letter let[NLETTERS];
16:
17: #define TMPNAME "/tmp/maXXXXX"
18: static char tmpfile[sizeof(TMPNAME)];
19:
20: static FILE *tfp;
21: static letter *lastp;
22:
23: #define ASSERT(x,y) if(!(x)) panic(y)
24:
25: void
26: inittmp()
27: {
28: /* make temp file */
29: (void)strcpy(tmpfile, TMPNAME);
30: (void)mktemp(tmpfile);
31: (void)unlink(tmpfile);
32: close(creat(tmpfile, 0600));
33: chown(tmpfile, getuid(), getgid());
34: tfp = fopen(tmpfile, "r+");
35: if (tfp == NULL)
36: panic("mail: can't open tempfile");
37: }
38:
39: void
40: releasetmp()
41: {
42: if (tfp != NULL)
43: fclose(tfp);
44: unlink(tmpfile);
45: }
46:
47: /*
48: * Modes are:
49: * "w" to write a letter
50: * "r" to read a letter
51: * "ru" to read only undeleted letters
52: */
53: letter *
54: lopen(n, mode)
55: int n;
56: char *mode;
57: {
58: letter *lp, *rv = NULL;
59:
60: if (n >= NLETTERS)
61: return NULL;
62:
63: lp = &let[n];
64: if (strcmp(mode, "w")==0) {
65: lp->status = L_USED;
66: (void)fseek(tfp, 0L, 2);
67: lp->address = ftell(tfp);
68: lp->offset = lp->size = 0;
69: rv = lp;
70:
71: } else if (strcmp(mode, "r")==0) {
72: if (lp->status & L_USED) {
73: lp->offset = 0;
74: (void)fseek(tfp, lp->address, 0);
75: rv = lp;
76: }
77:
78: } else if (strcmp(mode, "ru")==0) {
79: if ((lp->status & L_USED) && !(lp->status & L_DELETED)) {
80: lp->offset = 0;
81: (void)fseek(tfp, lp->address, 0);
82: rv = lp;
83: }
84: }
85:
86: lastp = rv;
87: return rv;
88: }
89:
90: extern char *
91: lgets(bp, len, lp)
92: char *bp;
93: int len;
94: letter *lp;
95: {
96: char *rv;
97:
98: ASSERT(lp->status & L_USED, "tmpfile botch");
99: if (lp != lastp)
100: (void)fseek(tfp, lp->address+lp->offset, 0);
101: if (lp->offset >= lp->size)
102: return NULL;
103: if (lp->offset+len > lp->size)
104: len = lp->size - lp->offset + 1;
105: rv = fgets(bp, len, tfp);
106: ASSERT(rv != NULL, "tmpfile botch");
107: lp->offset = ftell(tfp) - lp->address;
108: lastp = lp;
109: return bp;
110: }
111:
112: extern void
113: lputs(bp, lp)
114: char *bp;
115: letter *lp;
116: {
117: int rv;
118:
119: ASSERT(lp->status & L_USED, "tmpfile botch");
120: if (lp != lastp)
121: (void)fseek(tfp, lp->address+lp->offset, 0);
122: rv = fputs(bp, tfp);
123: ASSERT(rv != EOF, "can't write to /tmp");
124: lp->size = lp->offset = ftell(tfp) - lp->address;
125: lastp = lp;
126: }
127:
128: extern void
129: lputc(c, lp)
130: char c;
131: letter *lp;
132: {
133: char rv;
134:
135: ASSERT(lp->status & L_USED, "tmpfile botch");
136: if (lp != lastp)
137: (void)fseek(tfp, lp->address+lp->offset, 0);
138: rv = fputc(c, tfp);
139: ASSERT(rv != EOF, "can't write to /tmp");
140: lp->size = lp->offset = ftell(tfp) - lp->address;
141: lastp = lp;
142: }
143:
144: extern long
145: ltell(lp)
146: letter *lp;
147: {
148: ASSERT(lp->status & L_USED, "tmpfile botch");
149: return lp->offset;
150: }
151:
152: extern long
153: lsize(lp)
154: letter *lp;
155: {
156: ASSERT(lp->status & L_USED, "tmpfile botch");
157: return lp->size;
158: }
159:
160: extern int
161: letseek(lp, off)
162: letter *lp;
163: long off;
164: {
165: ASSERT(lp->status & L_USED, "tmpfile botch");
166: lp->offset = off < lp->size ? off : lp->size - 1;
167: lastp = NULL;
168: return 0;
169: }
170:
171: extern int
172: ldelete(n)
173: int n;
174: {
175: ASSERT(n>= 0 && n < NLETTERS && (let[n].status & L_USED), "tmpfile botch");
176: let[n].status |= L_DELETED;
177: return 1;
178: }
179:
180: extern int
181: lundelete(n)
182: int n;
183: {
184: ASSERT(n>= 0 && n < NLETTERS && (let[n].status & L_USED), "tmpfile botch");
185: let[n].status &= ~L_DELETED;
186: return 1;
187: }
188:
189: extern int
190: copyto(fp, lp, onatty, escape)
191: FILE *fp;
192: letter *lp;
193: int onatty;
194: int escape;
195: {
196: char buf[FROMLINESIZE];
197:
198: while (fgets(buf, FROMLINESIZE, fp)!=NULL) {
199: if (onatty && buf[0]=='.' && buf[1]=='\n' && buf[2]=='\0')
200: break;
201: if (escape && strncmp(buf, FROM, FSIZE)==0)
202: lputc('>', lp);
203: (void)lputs(buf, lp);
204: }
205: }
206:
207: extern int
208: copyfrom(lp, fp)
209: letter *lp;
210: FILE *fp;
211: {
212: char buf[FROMLINESIZE];
213:
214: while (lgets(buf, FROMLINESIZE, lp)!=NULL)
215: (void)fputs(buf, fp);
216: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.