summaryrefslogtreecommitdiff
path: root/src/printforward.c
diff options
context:
space:
mode:
authorJannis Hoffmann <jannis@fehcom.de>2024-07-03 15:48:04 +0200
committerJannis Hoffmann <jannis@fehcom.de>2024-07-03 15:48:04 +0200
commit89b7b67a13ebb7965cc7f13ad0595e2194a2d34c (patch)
tree25efd77a90ae87236e6730d8ea3846bbe0fd126f /src/printforward.c
add sqmail-4.2.29asqmail-4.2
Diffstat (limited to 'src/printforward.c')
-rw-r--r--src/printforward.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/src/printforward.c b/src/printforward.c
new file mode 100644
index 0000000..0ab7ad9
--- /dev/null
+++ b/src/printforward.c
@@ -0,0 +1,142 @@
+#include <unistd.h>
+#include "buffer.h"
+#include "logmsg.h"
+#include "stralloc.h"
+#include "cdbread.h"
+
+#define WHO "printmaillist"
+
+void badformat()
+{
+ logmsg(WHO,100,FATAL,"bad database format");
+}
+void nomem()
+{
+ logmsg(WHO,111,FATAL,"out of memory");
+}
+
+void getch(char *ch)
+{
+ int r;
+ r = buffer_get(buffer_0small,ch,1);
+ if (r == -1)
+ logmsg(WHO,111,FATAL,"unable to read input");
+ if (r == 0)
+ badformat();
+}
+
+void out(char *ch)
+{
+ if (buffer_put(buffer_1small,ch,1) == -1)
+ logmsg(WHO,111,FATAL,"unable to write output");
+}
+
+void printbuf(char *buf)
+{
+ while (*buf)
+ out(buf++);
+}
+
+void printsafe(char *buf,int len)
+{
+ char ch;
+
+ while (len) {
+ ch = *buf;
+ if ((ch <= 32) || (ch == ',') || (ch == ':') || (ch == ';') || (ch == '\\') || (ch == '#'))
+ out("\\");
+ out(&ch);
+ ++buf;
+ --len;
+ }
+}
+
+stralloc key = {0};
+stralloc data = {0};
+
+int main()
+{
+ uint32 eod;
+ uint32 pos;
+ uint32 klen;
+ uint32 dlen;
+ char buf[8];
+ char ch;
+ int i;
+ int j;
+
+ for (i = 0; i < 4; ++i)
+ getch(buf + i);
+ eod = cdb_unpack(buf);
+
+ for (i = 4; i < 2048; ++i)
+ getch(&ch);
+
+ pos = 2048;
+ while (pos < eod) {
+ if (eod - pos < 8) badformat();
+ pos += 8;
+ for (i = 0; i < 8; ++i) getch(buf + i);
+ klen = cdb_unpack(buf);
+ dlen = cdb_unpack(buf + 4);
+
+ if (!stralloc_copys(&key,"")) nomem();
+ if (eod - pos < klen) badformat();
+ pos += klen;
+ while (klen) {
+ --klen;
+ getch(&ch);
+ if (!stralloc_append(&key,&ch)) nomem();
+ }
+
+ if (eod - pos < dlen) badformat();
+ pos += dlen;
+ if (!stralloc_copys(&data,"")) nomem();
+ while (dlen) {
+ --dlen;
+ getch(&ch);
+ if (!stralloc_append(&data,&ch)) nomem();
+ }
+
+ if (!key.len) badformat();
+ if (key.s[0] == '?') {
+ printsafe(key.s + 1,key.len - 1);
+ printbuf(": ?");
+ printsafe(data.s,data.len);
+ printbuf(";\n");
+ }
+ else if (key.s[0] == ':') {
+ printsafe(key.s + 1,key.len - 1);
+ printbuf(":\n");
+
+ i = 0;
+ for (j = 0; j < data.len; ++j)
+ if (!data.s[j]) {
+ if ((data.s[i] == '.') || (data.s[i] == '/')) {
+ printbuf(", ");
+ printsafe(data.s + i,j - i);
+ printbuf("\n");
+ }
+ else if ((data.s[i] == '|') || (data.s[i] == '!')) {
+ printbuf(", ");
+ printsafe(data.s + i,j - i);
+ printbuf("\n");
+ }
+ else if ((data.s[i] == '&') && (j - i < 900)) {
+ printbuf(", ");
+ printsafe(data.s + i,j - i);
+ printbuf("\n");
+ }
+ else badformat();
+ i = j + 1;
+ }
+ if (i != j) badformat();
+ printbuf(";\n");
+ }
+ else badformat();
+ }
+
+ if (buffer_flush(buffer_1small) == -1)
+ logmsg(WHO,111,FATAL,"unable to write output");
+ _exit(0);
+}