s/qmail 4.3.24
Next generation secure email transport
Loading...
Searching...
No Matches
setforward.c
Go to the documentation of this file.
1#include <unistd.h>
2#include "buffer.h"
3#include "logmsg.h"
4#include "stralloc.h"
5#include "open.h"
6#include "case.h"
7#include "cdbmake.h"
8#include "logmsg.h"
9
10#define WHO "setforward"
11
12int rename(const char *,const char *); // stdio.h
13
14void usage()
15{
16 logmsg(WHO,100,USAGE,"setforward data.cdb data.tmp");
17}
18void nomem()
19{
20 logmsg(WHO,111,FATAL,"out of memory");
21}
23{
24 logmsg(WHO,100,FATAL,"final instruction must end with semicolon");
25}
27{
28 logmsg(WHO,100,FATAL,"double colons are not permitted");
29}
31{
32 logmsg(WHO,100,FATAL,"commas are not permitted before colons");
33}
34void nulbyte()
35{
36 logmsg(WHO,100,FATAL,"NUL bytes are not permitted");
37}
39{
40 logmsg(WHO,100,FATAL,"addresses over 800 bytes are not permitted");
41}
42
43char *fncdb;
44char *fntmp;
45int fd;
46struct cdb_make cdb;
47stralloc key = {0};
48
49stralloc target = {0}; /* always initialized; no NUL */
50stralloc command = {0}; /* always initialized; no NUL */
51stralloc instr = {0}; /* always initialized */
52
53int flagtarget = 0;
54/* 0: reading target; command is empty; instr is empty */
55/* 1: target is complete; instr still has to be written; reading command */
56
58{
59 logmsg(WHO,111,FATAL,B("unable to write to: ",fntmp));
60}
61
62void doit(char *prepend,char *data,int datalen)
63{
64 if (!stralloc_copys(&key,prepend)) nomem();
65 if (!stralloc_cat(&key,&target)) nomem();
66 case_lowerb(key.s,key.len);
67 if (cdb_make_add(&cdb,key.s,key.len,data,datalen) == -1)
68 writeerr();
69}
70
71int getch(char *ch)
72{
73 int r;
74
75 r = buffer_get(buffer_0small,ch,1);
76 if (r == -1)
77 logmsg(WHO,111,FATAL,"unable to read input: ");
78 return r;
79}
80
81int main(int argc,char * const argv[])
82{
83 char ch;
84
85 if (!stralloc_copys(&target,"")) nomem();
86 if (!stralloc_copys(&command,"")) nomem();
87 if (!stralloc_copys(&instr,"")) nomem();
88
89 fncdb = argv[1]; if (!fncdb) usage();
90 fntmp = argv[2]; if (!fntmp) usage();
91
92 fd = open_trunc(fntmp);
93 if (fd == -1)
94 logmsg(WHO,111,FATAL,B("unable to create: ",fntmp));
95
96 if (cdb_make_start(&cdb,fd) == -1) writeerr();
97
98 for (;;) {
99 if (!getch(&ch)) goto EOF;
100
101 if (ch == '#') {
102 while (ch != '\n') if (!getch(&ch)) goto EOF;
103 continue;
104 }
105
106 if (ch == ' ') continue;
107 if (ch == '\n') continue;
108 if (ch == '\t') continue;
109
110 if (ch == ':') {
111 if (flagtarget) extracolon();
112 flagtarget = 1;
113 continue;
114 }
115
116 if ((ch == ',') || (ch == ';')) {
117 if (!flagtarget) extracomma();
118 if (command.len) {
119 if (command.s[0] == '?') {
120 doit("?",command.s + 1,command.len - 1);
121 }
122 else if ((command.s[0] == '|') || (command.s[0] == '!')) {
123 if (!stralloc_cat(&instr,&command)) nomem();
124 if (!stralloc_0(&instr)) nomem();
125 }
126 else if ((command.s[0] == '.') || (command.s[0] == '/')) {
127 if (!stralloc_cat(&instr,&command)) nomem();
128 if (!stralloc_0(&instr)) nomem();
129 }
130 else {
131 if (command.len > 800) longaddress();
132 if (command.s[0] != '&')
133 if (!stralloc_cats(&instr,"&")) nomem();
134 if (!stralloc_cat(&instr,&command)) nomem();
135 if (!stralloc_0(&instr)) nomem();
136 }
137 }
138
139 if (!stralloc_copys(&command,"")) nomem();
140
141 if (ch == ';') {
142 if (instr.len)
143 doit(":",instr.s,instr.len);
144
145 if (!stralloc_copys(&target,"")) nomem();
146 if (!stralloc_copys(&instr,"")) nomem();
147 flagtarget = 0;
148 }
149 continue;
150 }
151
152 if (ch == '\\') if (!getch(&ch)) goto EOF;
153 if (ch == 0) nulbyte();
154 if (!stralloc_append(flagtarget ? &command : &target,&ch)) nomem();
155 }
156
157 EOF:
158 if (flagtarget || target.len)
160
161 if (cdb_make_finish(&cdb) == -1) writeerr();
162 if (fsync(fd) == -1) writeerr();
163 if (close(fd) == -1) writeerr(); /* NFS stupidity */
164
165 if (rename(fntmp,fncdb) == -1)
166 logmsg(WHO,111,FATAL,B("unable to move ",fntmp," to: ",fncdb));
167
168 _exit(0);
169}
#define WHO
Definition bouncesaying.c:8
int main()
Definition chkshsgr.c:6
int stralloc_copys(stralloc *, char const *)
void _exit(int)
stralloc key
stralloc data
char * fncdb
struct cdb cdb
stralloc instr
Definition newaliases.c:85
stralloc target
Definition newaliases.c:83
#define fntmp
Definition newinclude.c:37
stralloc command
Definition setforward.c:50
void usage()
Definition setforward.c:14
void nulbyte()
Definition setforward.c:34
void extracolon()
Definition setforward.c:26
int getch(char *ch)
Definition setforward.c:71
void extracomma()
Definition setforward.c:30
int rename(const char *, const char *)
void missingsemicolon()
Definition setforward.c:22
int flagtarget
Definition setforward.c:53
void longaddress()
Definition setforward.c:38
void nomem()
Definition setforward.c:18
void writeerr()
Definition setforward.c:57
void doit(char *prepend, char *data, int datalen)
Definition setforward.c:62