ezmlmx 0.68
ezmlmx
Loading...
Searching...
No Matches
ezcopy.c
Go to the documentation of this file.
1#include <unistd.h>
2#include "stralloc.h"
3#include "buffer.h"
4#include "str.h"
5#include "getln.h"
6#include "case.h"
7#include "readwrite.h"
8#include "qmail.h"
9#include "logmsg.h"
10#include "error.h"
11#include "quote.h"
12#include "ezcopy.h"
13#include "mime.h"
14#include "open.h"
15#include "byte.h"
16#include "idx.h"
17#include "errtxt.h"
18
19#define WHO "ezcopy"
20
42
43static stralloc line = {0};
44static stralloc outline = {0};
45static stralloc qline = {0};
46static stralloc outlocal = {0};
47static stralloc outhost = {0};
48
49static buffer bt;
50static char textbuf[256];
51static const char *target = "?????";
52static const char *verptarget = "?????";
53static const char *confirm = "?????";
54static unsigned int confirmlocal;
55static const char *szmsgnum = "?????";
56
57static void die_nomem() { logmsg(WHO,111,FATAL,ERR_NOMEM); }
58
66
67void set_cpoutlocal(const stralloc *ln)
68{
69 if (!quote(&outlocal,ln))
70 die_nomem();
71}
72
73void set_cpouthost(const stralloc *ln)
74{
75 if (!stralloc_copy(&outhost,ln))
76 die_nomem();
77}
78
79void set_cptarget(const char *tg)
80{
81 target = tg;
82}
83
84void set_cpverptarget(const char *tg)
85{
86 verptarget = tg;
87}
88
89void set_cpconfirm(const char *cf)
90{
91 confirm = cf;
92 confirmlocal = str_chr(cf,'@');
93}
94
95void set_cpnum(const char *cf)
96{
97 szmsgnum = cf;
98}
99
100static struct qmail *qqc;
101
102static void codeput(const char *l,unsigned int n,char code)
103{
104 if (!code || code == 'H')
105 qmail_put(qqc,l,n);
106 else {
107 if (code == 'Q')
108 encode_qp(l,n,&qline);
109 else
110 encode_b64(l,n,&qline,0);
111 qmail_put(qqc,qline.s,qline.len);
112 }
113}
114
115static void codeputs(const char *l,char code)
116{
117 codeput(l,str_len(l),code);
118}
119
127
128void ezcopy(struct qmail *qqp,const char *fn, char q)
129{
130 int fd;
131 int match, done;
132 unsigned int pos, nextpos;
133
134 qqc = qqp;
135 if ((fd = open_read(fn)) == -1)
136 if (errno != ENOENT)
137 logmsg(WHO,111,FATAL,B("error opening: ",fn));
138 else
139 logmsg(WHO,100,FATAL,B("error opening: ",fn));
140
141 buffer_init(&bt,buffer_unixread,fd,textbuf,sizeof(textbuf));
142
143 for (;;) {
144 if (getln(&bt,&line,&match,'\n') == -1)
145 logmsg(WHO,111,FATAL,B("error opening: ",fn));
146 if (line.len > 0) { /* line.len is always > 0 if match is true */
147 /* suppress blank line for 'H'eader mode */
148 if (line.len == 1 && q == 'H') continue;
149 if (line.s[0] == '!') {
150 if (line.s[1] == 'R') {
151 codeput(" ",3,q);
152 codeputs(confirm,q);
153 codeput("\n",1,q);
154 continue;
155 }
156 if (line.s[1] == 'A') {
157 codeput(" ",3,q);
158 codeputs(target,q);
159 codeput("\n",1,q);
160 continue;
161 }
162 }
163 /* Find tags <#x#>. Replace with for x=R confirm, for x=A */
164 /* target, x=l outlocal, x=h outhost. For others, just */
165 /* skip tag. If outlocal/outhost are not set, the tags are*/
166 /* skipped. If confirm/taget are not set, the tags are */
167 /* replaced by "???????" */
168
169 pos = 0;
170 nextpos = 0;
171 done = 0;
172 outline.len = 0; /* zap outline */
173
174 while ((pos += byte_chr(line.s+pos,line.len-pos,'<')) != line.len) {
175 if (pos + 4 < line.len &&
176 line.s[pos+1] == '#' &&
177 line.s[pos+3] == '#' &&
178 line.s[pos+4] == '>') { /* tag. Copy first part of line */
179 done = 1; /* did something */
180 if (!stralloc_catb(&outline,line.s+nextpos,pos-nextpos))
181 die_nomem();
182 switch(line.s[pos+2]) {
183 case 'A':
184 if (q == 'H') logmsg(WHO,111,ERROR,ERR_SUBST_UNSAFE);
185 if (!stralloc_cats(&outline,target)) die_nomem();
186 break;
187 case 'R':
188 if (!stralloc_cats(&outline,confirm)) die_nomem();
189 break;
190 case 'r':
191 if (!stralloc_catb(&outline,confirm,confirmlocal)) die_nomem();
192 break;
193 case 'l':
194 if (!stralloc_cat(&outline,&outlocal)) die_nomem();
195 break;
196 case 'h':
197 if (!stralloc_cat(&outline,&outhost)) die_nomem();
198 break;
199 case 't':
200 if (q == 'H') logmsg(WHO,111,ERROR,ERR_SUBST_UNSAFE);
201 if (!stralloc_cats(&outline,verptarget)) die_nomem();
202 break;
203 case 'n':
204 if (!stralloc_cats(&outline,szmsgnum)) die_nomem();
205 break;
206 default:
207 break; /* unknown tags killed */
208 }
209 pos += 5;
210 nextpos = pos;
211 } else
212 ++pos; /* try next position */
213 }
214 if (!done)
215 codeput(line.s,line.len,q);
216 else {
217 if (!stralloc_catb(&outline,line.s+nextpos,line.len-nextpos))
218 die_nomem(); /* remainder */
219 codeput(outline.s,outline.len,q);
220 }
221
222 /* Last line is missing its trailing newline, add one on output. */
223 if (!match)
224 codeput("\n",1,q);
225 } else
226 break;
227 }
228 close(fd);
229}
int quote(stralloc *saout, const stralloc *sain)
Definition quote.c:57
Error messages. If you translate these, I would urge you to keep the English version as well....
#define ERR_NOMEM
Definition errtxt.h:14
#define ERR_SUBST_UNSAFE
Definition errtxt.h:69
void qmail_put(struct qmail *, const char *, int)
Definition qmail.c:87
void die_nomem()
Definition getconf.c:17
void ezcopy(struct qmail *qqp, const char *fn, char q)
Definition ezcopy.c:128
void set_cpoutlocal(const stralloc *ln)
Definition ezcopy.c:67
void set_cpverptarget(const char *tg)
Definition ezcopy.c:84
void set_cpnum(const char *cf)
Definition ezcopy.c:95
void set_cptarget(const char *tg)
Definition ezcopy.c:79
void set_cpouthost(const stralloc *ln)
Definition ezcopy.c:73
void set_cpconfirm(const char *cf)
Definition ezcopy.c:89
#define WHO
Definition author.c:1
void encode_qp(const char *indata, unsigned int n, stralloc *outdata)
Definition encode_qp.c:21
stralloc fn
const char * code
Definition ezmlm-cron.c:75
int fd
Definition ezmlm-cgi.c:141
int match
Definition ezmlm-cgi.c:140
void encode_b64(const unsigned char *indata, unsigned int n, stralloc *outdata, int control)
Definition encode_b64.c:75
Definition qmail.h:10
const char * logmsg(const char *dir, unsigned long num, unsigned long listno, unsigned long subs, int done)
Definition loginfo.c:32