Blame


1 d1f529f4 2005-10-29 devnull #include "common.h"
2 d1f529f4 2005-10-29 devnull
3 d1f529f4 2005-10-29 devnull enum {
4 cbeb0b26 2006-04-01 devnull Buffersize = 64*1024
5 d1f529f4 2005-10-29 devnull };
6 d1f529f4 2005-10-29 devnull
7 d1f529f4 2005-10-29 devnull typedef struct Inbuf Inbuf;
8 d1f529f4 2005-10-29 devnull struct Inbuf
9 d1f529f4 2005-10-29 devnull {
10 d1f529f4 2005-10-29 devnull char buf[Buffersize];
11 d1f529f4 2005-10-29 devnull char *wp;
12 d1f529f4 2005-10-29 devnull char *rp;
13 d1f529f4 2005-10-29 devnull int eof;
14 d1f529f4 2005-10-29 devnull int in;
15 d1f529f4 2005-10-29 devnull int out;
16 d1f529f4 2005-10-29 devnull int last;
17 d1f529f4 2005-10-29 devnull ulong bytes;
18 d1f529f4 2005-10-29 devnull };
19 d1f529f4 2005-10-29 devnull
20 d1f529f4 2005-10-29 devnull static Inbuf*
21 d1f529f4 2005-10-29 devnull allocinbuf(int in, int out)
22 d1f529f4 2005-10-29 devnull {
23 d1f529f4 2005-10-29 devnull Inbuf *b;
24 d1f529f4 2005-10-29 devnull
25 d1f529f4 2005-10-29 devnull b = mallocz(sizeof(Inbuf), 1);
26 d1f529f4 2005-10-29 devnull if(b == nil)
27 d1f529f4 2005-10-29 devnull sysfatal("reading mailbox: %r");
28 d1f529f4 2005-10-29 devnull b->rp = b->wp = b->buf;
29 d1f529f4 2005-10-29 devnull b->in = in;
30 d1f529f4 2005-10-29 devnull b->out = out;
31 d1f529f4 2005-10-29 devnull return b;
32 d1f529f4 2005-10-29 devnull }
33 d1f529f4 2005-10-29 devnull
34 d1f529f4 2005-10-29 devnull static int
35 d1f529f4 2005-10-29 devnull fill(Inbuf *b, int addspace)
36 d1f529f4 2005-10-29 devnull {
37 d1f529f4 2005-10-29 devnull int i, n;
38 d1f529f4 2005-10-29 devnull
39 d1f529f4 2005-10-29 devnull if(b->eof && b->wp - b->rp == 0)
40 d1f529f4 2005-10-29 devnull return 0;
41 d1f529f4 2005-10-29 devnull
42 d1f529f4 2005-10-29 devnull n = b->rp - b->buf;
43 d1f529f4 2005-10-29 devnull if(n > 0){
44 d1f529f4 2005-10-29 devnull i = write(b->out, b->buf, n);
45 d1f529f4 2005-10-29 devnull if(i != n)
46 d1f529f4 2005-10-29 devnull return -1;
47 d1f529f4 2005-10-29 devnull b->last = b->buf[n-1];
48 d1f529f4 2005-10-29 devnull b->bytes += n;
49 d1f529f4 2005-10-29 devnull }
50 d1f529f4 2005-10-29 devnull if(addspace){
51 d1f529f4 2005-10-29 devnull if(write(b->out, " ", 1) != 1)
52 d1f529f4 2005-10-29 devnull return -1;
53 d1f529f4 2005-10-29 devnull b->last = ' ';
54 d1f529f4 2005-10-29 devnull b->bytes++;
55 d1f529f4 2005-10-29 devnull }
56 d1f529f4 2005-10-29 devnull
57 d1f529f4 2005-10-29 devnull n = b->wp - b->rp;
58 d1f529f4 2005-10-29 devnull memmove(b->buf, b->rp, n);
59 d1f529f4 2005-10-29 devnull b->rp = b->buf;
60 d1f529f4 2005-10-29 devnull b->wp = b->rp + n;
61 d1f529f4 2005-10-29 devnull
62 d1f529f4 2005-10-29 devnull i = read(b->in, b->buf+n, sizeof(b->buf)-n);
63 d1f529f4 2005-10-29 devnull if(i < 0)
64 d1f529f4 2005-10-29 devnull return -1;
65 d1f529f4 2005-10-29 devnull b->wp += i;
66 d1f529f4 2005-10-29 devnull
67 d1f529f4 2005-10-29 devnull return b->wp - b->rp;
68 d1f529f4 2005-10-29 devnull }
69 d1f529f4 2005-10-29 devnull
70 d1f529f4 2005-10-29 devnull /* code to escape ' '*From' ' at the beginning of a line */
71 d1f529f4 2005-10-29 devnull int
72 d1f529f4 2005-10-29 devnull appendfiletombox(int in, int out)
73 d1f529f4 2005-10-29 devnull {
74 d1f529f4 2005-10-29 devnull int addspace;
75 d1f529f4 2005-10-29 devnull int n;
76 d1f529f4 2005-10-29 devnull char *p;
77 d1f529f4 2005-10-29 devnull int sol;
78 d1f529f4 2005-10-29 devnull Inbuf *b;
79 d1f529f4 2005-10-29 devnull
80 d1f529f4 2005-10-29 devnull seek(out, 0, 2);
81 d1f529f4 2005-10-29 devnull
82 d1f529f4 2005-10-29 devnull b = allocinbuf(in, out);
83 d1f529f4 2005-10-29 devnull addspace = 0;
84 d1f529f4 2005-10-29 devnull sol = 1;
85 d1f529f4 2005-10-29 devnull
86 d1f529f4 2005-10-29 devnull for(;;){
87 d1f529f4 2005-10-29 devnull if(b->wp - b->rp < 5){
88 d1f529f4 2005-10-29 devnull n = fill(b, addspace);
89 d1f529f4 2005-10-29 devnull addspace = 0;
90 d1f529f4 2005-10-29 devnull if(n < 0)
91 d1f529f4 2005-10-29 devnull goto error;
92 d1f529f4 2005-10-29 devnull if(n == 0)
93 d1f529f4 2005-10-29 devnull break;
94 d1f529f4 2005-10-29 devnull if(n < 5){
95 d1f529f4 2005-10-29 devnull b->rp = b->wp;
96 d1f529f4 2005-10-29 devnull continue;
97 d1f529f4 2005-10-29 devnull }
98 d1f529f4 2005-10-29 devnull }
99 d1f529f4 2005-10-29 devnull
100 d1f529f4 2005-10-29 devnull /* state machine looking for ' '*From' ' */
101 d1f529f4 2005-10-29 devnull if(!sol){
102 d1f529f4 2005-10-29 devnull p = memchr(b->rp, '\n', b->wp - b->rp);
103 d1f529f4 2005-10-29 devnull if(p == nil)
104 d1f529f4 2005-10-29 devnull b->rp = b->wp;
105 d1f529f4 2005-10-29 devnull else{
106 d1f529f4 2005-10-29 devnull b->rp = p+1;
107 d1f529f4 2005-10-29 devnull sol = 1;
108 d1f529f4 2005-10-29 devnull }
109 d1f529f4 2005-10-29 devnull continue;
110 d1f529f4 2005-10-29 devnull } else {
111 d1f529f4 2005-10-29 devnull if(*b->rp == ' ' || strncmp(b->rp, "From ", 5) != 0){
112 d1f529f4 2005-10-29 devnull b->rp++;
113 d1f529f4 2005-10-29 devnull continue;
114 d1f529f4 2005-10-29 devnull }
115 d1f529f4 2005-10-29 devnull addspace = 1;
116 d1f529f4 2005-10-29 devnull sol = 0;
117 d1f529f4 2005-10-29 devnull }
118 d1f529f4 2005-10-29 devnull }
119 d1f529f4 2005-10-29 devnull
120 d1f529f4 2005-10-29 devnull /* mailbox entries always terminate with two newlines */
121 d1f529f4 2005-10-29 devnull n = b->last == '\n' ? 1 : 2;
122 d1f529f4 2005-10-29 devnull if(write(out, "\n\n", n) != n)
123 d1f529f4 2005-10-29 devnull goto error;
124 d1f529f4 2005-10-29 devnull n += b->bytes;
125 d1f529f4 2005-10-29 devnull free(b);
126 d1f529f4 2005-10-29 devnull return n;
127 d1f529f4 2005-10-29 devnull error:
128 d1f529f4 2005-10-29 devnull free(b);
129 d1f529f4 2005-10-29 devnull return -1;
130 d1f529f4 2005-10-29 devnull }
131 d1f529f4 2005-10-29 devnull
132 d1f529f4 2005-10-29 devnull int
133 d1f529f4 2005-10-29 devnull appendfiletofile(int in, int out)
134 d1f529f4 2005-10-29 devnull {
135 d1f529f4 2005-10-29 devnull int n;
136 d1f529f4 2005-10-29 devnull Inbuf *b;
137 d1f529f4 2005-10-29 devnull
138 d1f529f4 2005-10-29 devnull seek(out, 0, 2);
139 d1f529f4 2005-10-29 devnull
140 d1f529f4 2005-10-29 devnull b = allocinbuf(in, out);
141 d1f529f4 2005-10-29 devnull for(;;){
142 d1f529f4 2005-10-29 devnull n = fill(b, 0);
143 d1f529f4 2005-10-29 devnull if(n < 0)
144 d1f529f4 2005-10-29 devnull goto error;
145 d1f529f4 2005-10-29 devnull if(n == 0)
146 d1f529f4 2005-10-29 devnull break;
147 d1f529f4 2005-10-29 devnull b->rp = b->wp;
148 d1f529f4 2005-10-29 devnull }
149 d1f529f4 2005-10-29 devnull n = b->bytes;
150 d1f529f4 2005-10-29 devnull free(b);
151 d1f529f4 2005-10-29 devnull return n;
152 d1f529f4 2005-10-29 devnull error:
153 d1f529f4 2005-10-29 devnull free(b);
154 d1f529f4 2005-10-29 devnull return -1;
155 d1f529f4 2005-10-29 devnull }