-
Notifications
You must be signed in to change notification settings - Fork 2
/
passthrough.go
122 lines (111 loc) · 3.01 KB
/
passthrough.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// 2019, Georg Sauthoff <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later
package main
import (
"golang.org/x/sys/unix"
"io"
"log"
"os"
)
func copy_stdin(tmpdir string) (*os.File, error) {
f, err := os.OpenFile(tmpdir, os.O_RDWR | os.O_EXCL | unix.O_TMPFILE, 0600)
if err != nil {
return f, err
}
block := make([]byte, read_size)
for {
block := block[:cap(block)]
n, err := os.Stdin.Read(block)
if err != nil && err != io.EOF {
return f, err
}
block = block[:n]
if n == 0 {
break
}
if _, err := f.Write(block); err != nil {
return f, err
}
}
if _, err := f.Seek(0, 0); err != nil {
return f, err
}
return f, nil
}
func passthrough_file(in io.Reader, is_ham bool, out io.WriteCloser) error {
var m split_machine
block := make([]byte, read_size)
hout := new_xgonzo_filter_writer(new_keep_open_writer(out))
for {
block := block[:cap(block)]
n, err := in.Read(block)
if err != nil && err != io.EOF {
return err
}
block = block[:n]
if n == 0 {
break
}
for {
if len(block) == 0 {
break
}
action, bs, bl := m.next(block)
block = bl
switch action {
case split_machine_WRITE_HEADER:
if _, err := hout.Write(bs); err != nil {
return err
}
case split_machine_WRITE_BODY:
if _, err := out.Write(bs); err != nil {
return err
}
case split_machine_SETUP_BODY:
if err := hout.Close(); err != nil {
return err
}
if is_ham {
out.Write([]byte("X-gonzo: ham\n\n"))
} else {
out.Write([]byte("X-gonzo: spam\n\n"))
}
case split_machine_MORE:
;
}
}
}
return nil
}
func passthrough_message(args *args) {
var f *os.File
var err error
if args.in_filename == "-" {
f, err = copy_stdin(args.tmpdir)
if err != nil {
log.Fatal(err)
}
} else {
f, err = os.OpenFile(args.in_filename, os.O_RDONLY, 0644)
if err != nil {
log.Fatal(err)
}
}
is_ham, err := classify_file(f, args)
if err != nil {
debugf("classification failed: %v", err)
// we ignore this error since we don't want to stop the passthrough just
// because something went wrong during classification ...
}
if _, err := f.Seek(0, 0); err != nil {
log.Fatal(err)
}
out := open_output_or_stdout(args.out_filename)
err = passthrough_file(f, is_ham, out)
if err != nil {
log.Fatal(err)
}
if err := out.Close(); err != nil {
log.Fatal(err)
}
}