s/qmail 4.2.29a
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(prepend,data,datalen)
63char *prepend;
64char *data;
65int datalen;
66{
67 if (!stralloc_copys(&key,prepend)) nomem();
68 if (!stralloc_cat(&key,&target)) nomem();
69 case_lowerb(key.s,key.len);
70 if (cdb_make_add(&cdb,key.s,key.len,data,datalen) == -1)
71 writeerr();
72}
73
74int getch(ch)
75char *ch;
76{
77 int r;
78
79 r = buffer_get(buffer_0small,ch,1);
80 if (r == -1)
81 logmsg(WHO,111,FATAL,"unable to read input: ");
82 return r;
83}
84
85int main(int argc, char **argv)
86{
87 char ch;
88
89 if (!stralloc_copys(&target,"")) nomem();
90 if (!stralloc_copys(&command,"")) nomem();
91 if (!stralloc_copys(&instr,"")) nomem();
92
93 fncdb = argv[1]; if (!fncdb) usage();
94 fntmp = argv[2]; if (!fntmp) usage();
95
96 fd = open_trunc(fntmp);
97 if (fd == -1)
98 logmsg(WHO,111,FATAL,B("unable to create: ",fntmp));
99
100 if (cdb_make_start(&cdb,fd) == -1) writeerr();
101
102 for (;;) {
103 if (!getch(&ch)) goto EOF;
104
105 if (ch == '#') {
106 while (ch != '\n') if (!getch(&ch)) goto EOF;
107 continue;
108 }
109
110 if (ch == ' ') continue;
111 if (ch == '\n') continue;
112 if (ch == '\t') continue;
113
114 if (ch == ':') {
115 if (flagtarget) extracolon();
116 flagtarget = 1;
117 continue;
118 }
119
120 if ((ch == ',') || (ch == ';')) {
121 if (!flagtarget) extracomma();
122 if (command.len) {
123 if (command.s[0] == '?') {
124 doit("?",command.s + 1,command.len - 1);
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 if ((command.s[0] == '.') || (command.s[0] == '/')) {
131 if (!stralloc_cat(&instr,&command)) nomem();
132 if (!stralloc_0(&instr)) nomem();
133 }
134 else {
135 if (command.len > 800) longaddress();
136 if (command.s[0] != '&')
137 if (!stralloc_cats(&instr,"&")) nomem();
138 if (!stralloc_cat(&instr,&command)) nomem();
139 if (!stralloc_0(&instr)) nomem();
140 }
141 }
142
143 if (!stralloc_copys(&command,"")) nomem();
144
145 if (ch == ';') {
146 if (instr.len)
147 doit(":",instr.s,instr.len);
148
149 if (!stralloc_copys(&target,"")) nomem();
150 if (!stralloc_copys(&instr,"")) nomem();
151 flagtarget = 0;
152 }
153 continue;
154 }
155
156 if (ch == '\\') if (!getch(&ch)) goto EOF;
157 if (ch == 0) nulbyte();
158 if (!stralloc_append(flagtarget ? &command : &target,&ch)) nomem();
159 }
160
161 EOF:
162 if (flagtarget || target.len)
164
165 if (cdb_make_finish(&cdb) == -1) writeerr();
166 if (fsync(fd) == -1) writeerr();
167 if (close(fd) == -1) writeerr(); /* NFS stupidity */
168
169 if (rename(fntmp,fncdb) == -1)
170 logmsg(WHO,111,FATAL,B("unable to move ",fntmp," to: ",fncdb));
171
172 _exit(0);
173}
int main()
Definition: chkshsgr.c:6
int stralloc_copys(stralloc *, char const *)
void _exit()
stralloc data
Definition: fastforward.c:118
void doit()
Definition: newaliases.c:256
stralloc key
Definition: setforward.c:47
stralloc command
Definition: setforward.c:50
stralloc instr
Definition: setforward.c:51
char * fntmp
Definition: setforward.c:44
struct cdb_make cdb
Definition: setforward.c:46
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:74
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
int fd
Definition: setforward.c:45
void nomem()
Definition: setforward.c:18
stralloc target
Definition: setforward.c:49
void writeerr()
Definition: setforward.c:57
char * fncdb
Definition: setforward.c:43
#define WHO
Definition: setforward.c:10