Merge pull request #4 from Freeaqingme/master
Implement stop(), Support IPv6, Custom log callbacks, reformatted code
This commit is contained in:
160
gomilter.go
160
gomilter.go
@@ -17,21 +17,23 @@ package gomilter
|
|||||||
#cgo LDFLAGS: -lmilter
|
#cgo LDFLAGS: -lmilter
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
//#include <string.h>
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
#include "libmilter/mfapi.h"
|
#include "libmilter/mfapi.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"unsafe"
|
|
||||||
"encoding/binary"
|
|
||||||
"reflect"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
type sockaddr_in struct {
|
type sockaddr_in struct {
|
||||||
@@ -101,7 +103,7 @@ func (m *MilterRaw) GetSocket() string {
|
|||||||
|
|
||||||
// ********* Callback checking types *********
|
// ********* Callback checking types *********
|
||||||
type checkForConnect interface {
|
type checkForConnect interface {
|
||||||
Connect(ctx uintptr, hostname, ip string) (sfsistat int8)
|
Connect(ctx uintptr, hostname string, ip net.IP) (sfsistat int8)
|
||||||
}
|
}
|
||||||
|
|
||||||
type checkForHelo interface {
|
type checkForHelo interface {
|
||||||
@@ -193,7 +195,6 @@ func GobDecode(buf []byte, data interface{}) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ********* Filter Callback functions *********
|
// ********* Filter Callback functions *********
|
||||||
// These are registered with Milter
|
// These are registered with Milter
|
||||||
// They are only called if they get registered but need to be defined anyway
|
// They are only called if they get registered but need to be defined anyway
|
||||||
@@ -201,29 +202,37 @@ func GobDecode(buf []byte, data interface{}) error {
|
|||||||
//export Go_xxfi_connect
|
//export Go_xxfi_connect
|
||||||
func Go_xxfi_connect(ctx *C.SMFICTX, hostname *C.char, hostaddr *C._SOCK_ADDR) C.sfsistat {
|
func Go_xxfi_connect(ctx *C.SMFICTX, hostname *C.char, hostaddr *C._SOCK_ADDR) C.sfsistat {
|
||||||
ctxptr := ctx2int(ctx)
|
ctxptr := ctx2int(ctx)
|
||||||
// Check if the host address is a regular ipv4 address
|
var ip net.IP
|
||||||
if hostaddr.sa_family == C.AF_INET {
|
|
||||||
//fmt.Println(hostaddr.sa_data)
|
|
||||||
|
|
||||||
// hostaddrin is a parallel data structure of the C type hostaddr
|
if hostaddr.sa_family == C.AF_INET {
|
||||||
//var hostaddrin *sockaddr_in
|
|
||||||
hostaddrin := (*sockaddr_in)(unsafe.Pointer(hostaddr))
|
hostaddrin := (*sockaddr_in)(unsafe.Pointer(hostaddr))
|
||||||
//fmt.Println(hostaddrin)
|
|
||||||
ip_addr := make([]byte, 4)
|
ip_addr := make([]byte, 4)
|
||||||
binary.LittleEndian.PutUint32(ip_addr, hostaddrin.sin_addr)
|
binary.LittleEndian.PutUint32(ip_addr, hostaddrin.sin_addr)
|
||||||
|
ip = net.IPv4(ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3])
|
||||||
|
|
||||||
// Call our application's callback
|
} else if hostaddr.sa_family == C.AF_INET6 {
|
||||||
m := milter.(checkForConnect)
|
sa_in := (*C.struct_sockaddr_in6)(unsafe.Pointer(hostaddr))
|
||||||
code := m.Connect(ctxptr, C.GoString(hostname), fmt.Sprintf("%d.%d.%d.%d", ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]))
|
var dst = make([]byte, 16)
|
||||||
|
C.inet_ntop(
|
||||||
|
C.int(hostaddr.sa_family),
|
||||||
|
unsafe.Pointer(&sa_in.sin6_addr),
|
||||||
|
(*C.char)(unsafe.Pointer(&dst)),
|
||||||
|
16)
|
||||||
|
|
||||||
|
ip = net.ParseIP(C.GoString((*C.char)(unsafe.Pointer(&dst))))
|
||||||
|
} else {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Printf("Connect callback returned: %d\n", code)
|
LoggerPrintln("hostaddr.sa_family value not implemented")
|
||||||
|
}
|
||||||
|
ip = net.ParseIP("::")
|
||||||
|
}
|
||||||
|
|
||||||
|
m := milter.(checkForConnect)
|
||||||
|
code := m.Connect(ctxptr, C.GoString(hostname), ip)
|
||||||
|
if milter.GetDebug() {
|
||||||
|
LoggerPrintf("Connect callback returned: %d\n", code)
|
||||||
}
|
}
|
||||||
return C.sfsistat(code)
|
return C.sfsistat(code)
|
||||||
}
|
|
||||||
if milter.GetDebug() {
|
|
||||||
fmt.Println("hostaddr.sa_family value not implemented")
|
|
||||||
}
|
|
||||||
return C.SMFIS_CONTINUE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//export Go_xxfi_helo
|
//export Go_xxfi_helo
|
||||||
@@ -231,7 +240,7 @@ func Go_xxfi_helo(ctx *C.SMFICTX, helohost *C.char) C.sfsistat {
|
|||||||
m := milter.(checkForHelo)
|
m := milter.(checkForHelo)
|
||||||
code := m.Helo(ctx2int(ctx), C.GoString(helohost))
|
code := m.Helo(ctx2int(ctx), C.GoString(helohost))
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Printf("Helo callback returned: %d\n", code)
|
LoggerPrintf("Helo callback returned: %d\n", code)
|
||||||
}
|
}
|
||||||
return C.sfsistat(code)
|
return C.sfsistat(code)
|
||||||
}
|
}
|
||||||
@@ -242,7 +251,7 @@ func Go_xxfi_envfrom(ctx *C.SMFICTX, argv **C.char) C.sfsistat {
|
|||||||
m := milter.(checkForEnvFrom)
|
m := milter.(checkForEnvFrom)
|
||||||
code := m.EnvFrom(ctx2int(ctx), cStringArrayToSlice(argv))
|
code := m.EnvFrom(ctx2int(ctx), cStringArrayToSlice(argv))
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Printf("EnvFrom callback returned: %d\n", code)
|
LoggerPrintf("EnvFrom callback returned: %d\n", code)
|
||||||
}
|
}
|
||||||
return C.sfsistat(code)
|
return C.sfsistat(code)
|
||||||
}
|
}
|
||||||
@@ -253,7 +262,7 @@ func Go_xxfi_envrcpt(ctx *C.SMFICTX, argv **C.char) C.sfsistat {
|
|||||||
m := milter.(checkForEnvRcpt)
|
m := milter.(checkForEnvRcpt)
|
||||||
code := m.EnvRcpt(ctx2int(ctx), cStringArrayToSlice(argv))
|
code := m.EnvRcpt(ctx2int(ctx), cStringArrayToSlice(argv))
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Printf("EnvRcpt callback returned: %d\n", code)
|
LoggerPrintf("EnvRcpt callback returned: %d\n", code)
|
||||||
}
|
}
|
||||||
return C.sfsistat(code)
|
return C.sfsistat(code)
|
||||||
}
|
}
|
||||||
@@ -263,7 +272,7 @@ func Go_xxfi_header(ctx *C.SMFICTX, headerf, headerv *C.char) C.sfsistat {
|
|||||||
m := milter.(checkForHeader)
|
m := milter.(checkForHeader)
|
||||||
code := m.Header(ctx2int(ctx), C.GoString(headerf), C.GoString(headerv))
|
code := m.Header(ctx2int(ctx), C.GoString(headerf), C.GoString(headerv))
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Printf("Header callback returned: %d\n", code)
|
LoggerPrintf("Header callback returned: %d\n", code)
|
||||||
}
|
}
|
||||||
return C.sfsistat(code)
|
return C.sfsistat(code)
|
||||||
}
|
}
|
||||||
@@ -274,7 +283,7 @@ func Go_xxfi_eoh(ctx *C.SMFICTX) C.sfsistat {
|
|||||||
m := milter.(checkForEoh)
|
m := milter.(checkForEoh)
|
||||||
code := m.Eoh(ctx2int(ctx))
|
code := m.Eoh(ctx2int(ctx))
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Printf("Eoh callback returned: %d\n", code)
|
LoggerPrintf("Eoh callback returned: %d\n", code)
|
||||||
}
|
}
|
||||||
return C.sfsistat(code)
|
return C.sfsistat(code)
|
||||||
}
|
}
|
||||||
@@ -286,12 +295,12 @@ func Go_xxfi_body(ctx *C.SMFICTX, bodyp *C.uchar, bodylen C.size_t) C.sfsistat {
|
|||||||
// Our bit slice is backed by the original body. No copy is made here
|
// Our bit slice is backed by the original body. No copy is made here
|
||||||
// Be aware that converting the byte slice to string will make a copy
|
// Be aware that converting the byte slice to string will make a copy
|
||||||
var b []byte
|
var b []byte
|
||||||
b = (*[1<<30]byte)(unsafe.Pointer(bodyp))[0:bodylen]
|
b = (*[1 << 30]byte)(unsafe.Pointer(bodyp))[0:bodylen]
|
||||||
// Call our application's callback
|
// Call our application's callback
|
||||||
m := milter.(checkForBody)
|
m := milter.(checkForBody)
|
||||||
code := m.Body(ctx2int(ctx), b)
|
code := m.Body(ctx2int(ctx), b)
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Printf("Body callback returned: %d\n", code)
|
LoggerPrintf("Body callback returned: %d\n", code)
|
||||||
}
|
}
|
||||||
return C.sfsistat(code)
|
return C.sfsistat(code)
|
||||||
}
|
}
|
||||||
@@ -302,7 +311,7 @@ func Go_xxfi_eom(ctx *C.SMFICTX) C.sfsistat {
|
|||||||
m := milter.(checkForEom)
|
m := milter.(checkForEom)
|
||||||
code := m.Eom(ctx2int(ctx))
|
code := m.Eom(ctx2int(ctx))
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Printf("Eom callback returned: %d\n", code)
|
LoggerPrintf("Eom callback returned: %d\n", code)
|
||||||
}
|
}
|
||||||
return C.sfsistat(code)
|
return C.sfsistat(code)
|
||||||
}
|
}
|
||||||
@@ -313,7 +322,7 @@ func Go_xxfi_abort(ctx *C.SMFICTX) C.sfsistat {
|
|||||||
m := milter.(checkForAbort)
|
m := milter.(checkForAbort)
|
||||||
code := m.Abort(ctx2int(ctx))
|
code := m.Abort(ctx2int(ctx))
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Printf("Abort callback returned: %d\n", code)
|
LoggerPrintf("Abort callback returned: %d\n", code)
|
||||||
}
|
}
|
||||||
return C.sfsistat(code)
|
return C.sfsistat(code)
|
||||||
}
|
}
|
||||||
@@ -324,7 +333,7 @@ func Go_xxfi_close(ctx *C.SMFICTX) C.sfsistat {
|
|||||||
m := milter.(checkForClose)
|
m := milter.(checkForClose)
|
||||||
code := m.Close(ctx2int(ctx))
|
code := m.Close(ctx2int(ctx))
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Printf("Close callback returned: %d\n", code)
|
LoggerPrintf("Close callback returned: %d\n", code)
|
||||||
}
|
}
|
||||||
return C.sfsistat(code)
|
return C.sfsistat(code)
|
||||||
}
|
}
|
||||||
@@ -340,6 +349,7 @@ func GetSymVal(ctx uintptr, symname string) string {
|
|||||||
return C.GoString(cval)
|
return C.GoString(cval)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See also: http://bit.ly/1HVWA9I
|
||||||
func SetPriv(ctx uintptr, privatedata interface{}) int {
|
func SetPriv(ctx uintptr, privatedata interface{}) int {
|
||||||
// privatedata seems to work for any data type
|
// privatedata seems to work for any data type
|
||||||
// Structs must have exported fields
|
// Structs must have exported fields
|
||||||
@@ -438,7 +448,7 @@ func GetPriv(ctx uintptr, privatedata interface{}) int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetReply (ctx uintptr, rcode, xcode, message string) int {
|
func SetReply(ctx uintptr, rcode, xcode, message string) int {
|
||||||
type CtxPtr *C.struct_smfi_str
|
type CtxPtr *C.struct_smfi_str
|
||||||
crcode := C.CString(rcode)
|
crcode := C.CString(rcode)
|
||||||
defer C.free(unsafe.Pointer(crcode))
|
defer C.free(unsafe.Pointer(crcode))
|
||||||
@@ -450,7 +460,7 @@ func SetReply (ctx uintptr, rcode, xcode, message string) int {
|
|||||||
return int(C.smfi_setreply(int2ctx(ctx), crcode, cxcode, cmessage))
|
return int(C.smfi_setreply(int2ctx(ctx), crcode, cxcode, cmessage))
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetMLReply (ctx uintptr, rcode, xcode string, message ...string) int {
|
func SetMLReply(ctx uintptr, rcode, xcode string, message ...string) int {
|
||||||
/* Allows up to 32 lines of message
|
/* Allows up to 32 lines of message
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -468,7 +478,7 @@ func SetMLReply (ctx uintptr, rcode, xcode string, message ...string) int {
|
|||||||
defer C.free(argv)
|
defer C.free(argv)
|
||||||
// Assign each line to its address offset
|
// Assign each line to its address offset
|
||||||
for i := 0; i < len(message); i++ {
|
for i := 0; i < len(message); i++ {
|
||||||
linePtr := (**C.char)(unsafe.Pointer(uintptr(argv) + uintptr(i) * ptrSize))
|
linePtr := (**C.char)(unsafe.Pointer(uintptr(argv) + uintptr(i)*ptrSize))
|
||||||
line := C.CString(message[i])
|
line := C.CString(message[i])
|
||||||
defer C.free(unsafe.Pointer(line))
|
defer C.free(unsafe.Pointer(line))
|
||||||
*linePtr = line
|
*linePtr = line
|
||||||
@@ -491,7 +501,7 @@ func AddHeader(ctx uintptr, headerf, headerv string) int {
|
|||||||
defer C.free(unsafe.Pointer(cheaderv))
|
defer C.free(unsafe.Pointer(cheaderv))
|
||||||
|
|
||||||
// Call smfi_addheader
|
// Call smfi_addheader
|
||||||
return int(C.smfi_addheader(int2ctx(ctx), cheaderf, cheaderv));
|
return int(C.smfi_addheader(int2ctx(ctx), cheaderf, cheaderv))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ChgHeader(ctx uintptr, headerf string, hdridx int, headerv string) int {
|
func ChgHeader(ctx uintptr, headerf string, hdridx int, headerv string) int {
|
||||||
@@ -504,7 +514,7 @@ func ChgHeader(ctx uintptr, headerf string, hdridx int, headerv string) int {
|
|||||||
defer C.free(unsafe.Pointer(cheaderv))
|
defer C.free(unsafe.Pointer(cheaderv))
|
||||||
|
|
||||||
// Call smfi_chgheader
|
// Call smfi_chgheader
|
||||||
return int(C.smfi_chgheader(int2ctx(ctx), cheaderf, C.int(hdridx), cheaderv));
|
return int(C.smfi_chgheader(int2ctx(ctx), cheaderf, C.int(hdridx), cheaderv))
|
||||||
}
|
}
|
||||||
|
|
||||||
func InsHeader(ctx uintptr, hdridx int, headerf, headerv string) int {
|
func InsHeader(ctx uintptr, hdridx int, headerf, headerv string) int {
|
||||||
@@ -517,10 +527,9 @@ func InsHeader(ctx uintptr, hdridx int, headerf, headerv string) int {
|
|||||||
defer C.free(unsafe.Pointer(cheaderv))
|
defer C.free(unsafe.Pointer(cheaderv))
|
||||||
|
|
||||||
// Call smfi_insheader
|
// Call smfi_insheader
|
||||||
return int(C.smfi_insheader(int2ctx(ctx), C.int(hdridx), cheaderf, cheaderv));
|
return int(C.smfi_insheader(int2ctx(ctx), C.int(hdridx), cheaderf, cheaderv))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func ChgFrom(ctx uintptr, mail, args string) int {
|
func ChgFrom(ctx uintptr, mail, args string) int {
|
||||||
/* Change the envelope sender address. SMFIF_CHGFROM
|
/* Change the envelope sender address. SMFIF_CHGFROM
|
||||||
*/
|
*/
|
||||||
@@ -595,10 +604,14 @@ func progress(ctx uintptr) int {
|
|||||||
|
|
||||||
// ********* Run the milter *********
|
// ********* Run the milter *********
|
||||||
|
|
||||||
|
func Stop() {
|
||||||
|
C.smfi_stop()
|
||||||
|
}
|
||||||
|
|
||||||
func Run(amilter Milter) int {
|
func Run(amilter Milter) int {
|
||||||
milter = amilter
|
milter = amilter
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println ("Debugging enabled")
|
LoggerPrintf("Debugging enabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declare an empty smfiDesc structure
|
// Declare an empty smfiDesc structure
|
||||||
@@ -609,7 +622,7 @@ func Run(amilter Milter) int {
|
|||||||
defer C.free(unsafe.Pointer(fname))
|
defer C.free(unsafe.Pointer(fname))
|
||||||
smfilter.xxfi_name = fname
|
smfilter.xxfi_name = fname
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Printf("Filter Name: %s\n", C.GoString(smfilter.xxfi_name))
|
LoggerPrintf("Filter Name: %s\n", C.GoString(smfilter.xxfi_name))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set version code
|
// Set version code
|
||||||
@@ -618,7 +631,7 @@ func Run(amilter Milter) int {
|
|||||||
// Set Flags
|
// Set Flags
|
||||||
smfilter.xxfi_flags = C.ulong(milter.GetFlags())
|
smfilter.xxfi_flags = C.ulong(milter.GetFlags())
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Printf("Flags: 0x%b\n", smfilter.xxfi_flags)
|
LoggerPrintf("Flags: 0x%b\n", smfilter.xxfi_flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Callbacks if they are implemented
|
// Set Callbacks if they are implemented
|
||||||
@@ -626,117 +639,117 @@ func Run(amilter Milter) int {
|
|||||||
// Check if Connect method was implemented
|
// Check if Connect method was implemented
|
||||||
if _, ok := milter.(checkForConnect); ok {
|
if _, ok := milter.(checkForConnect); ok {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("Connect callback implemented")
|
LoggerPrintln("Connect callback implemented")
|
||||||
}
|
}
|
||||||
C.setConnect(&smfilter)
|
C.setConnect(&smfilter)
|
||||||
} else {
|
} else {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("Connect callback not implemented")
|
LoggerPrintln("Connect callback not implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if Helo method was implemented
|
// Check if Helo method was implemented
|
||||||
if _, ok := milter.(checkForHelo); ok {
|
if _, ok := milter.(checkForHelo); ok {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("Helo callback implemented")
|
LoggerPrintln("Helo callback implemented")
|
||||||
}
|
}
|
||||||
C.setHelo(&smfilter)
|
C.setHelo(&smfilter)
|
||||||
} else {
|
} else {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("Helo callback not implemented")
|
LoggerPrintln("Helo callback not implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if EnvFrom method was implemented
|
// Check if EnvFrom method was implemented
|
||||||
if _, ok := milter.(checkForEnvFrom); ok {
|
if _, ok := milter.(checkForEnvFrom); ok {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("EnvFrom callback implemented")
|
LoggerPrintln("EnvFrom callback implemented")
|
||||||
}
|
}
|
||||||
C.setEnvFrom(&smfilter)
|
C.setEnvFrom(&smfilter)
|
||||||
} else {
|
} else {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("EnvFrom callback not implemented")
|
LoggerPrintln("EnvFrom callback not implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if EnvRcpt method was implemented
|
// Check if EnvRcpt method was implemented
|
||||||
if _, ok := milter.(checkForEnvRcpt); ok {
|
if _, ok := milter.(checkForEnvRcpt); ok {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("EnvRcpt callback implemented")
|
LoggerPrintln("EnvRcpt callback implemented")
|
||||||
}
|
}
|
||||||
C.setEnvRcpt(&smfilter)
|
C.setEnvRcpt(&smfilter)
|
||||||
} else {
|
} else {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("EnvRcpt callback not implemented")
|
LoggerPrintln("EnvRcpt callback not implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if Header method was implemented
|
// Check if Header method was implemented
|
||||||
if _, ok := milter.(checkForHeader); ok {
|
if _, ok := milter.(checkForHeader); ok {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("Header callback implemented")
|
LoggerPrintln("Header callback implemented")
|
||||||
}
|
}
|
||||||
C.setHeader(&smfilter)
|
C.setHeader(&smfilter)
|
||||||
} else {
|
} else {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("Header callback not implemented")
|
LoggerPrintln("Header callback not implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if Eoh method was implemented
|
// Check if Eoh method was implemented
|
||||||
if _, ok := milter.(checkForEoh); ok {
|
if _, ok := milter.(checkForEoh); ok {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("Eoh callback implemented")
|
LoggerPrintln("Eoh callback implemented")
|
||||||
}
|
}
|
||||||
C.setEoh(&smfilter)
|
C.setEoh(&smfilter)
|
||||||
} else {
|
} else {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("Eoh callback not implemented")
|
LoggerPrintln("Eoh callback not implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if Body method was implemented
|
// Check if Body method was implemented
|
||||||
if _, ok := milter.(checkForBody); ok {
|
if _, ok := milter.(checkForBody); ok {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("Body callback implemented")
|
LoggerPrintln("Body callback implemented")
|
||||||
}
|
}
|
||||||
C.setBody(&smfilter)
|
C.setBody(&smfilter)
|
||||||
} else {
|
} else {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("Body callback not implemented")
|
LoggerPrintln("Body callback not implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if Eom method was implemented
|
// Check if Eom method was implemented
|
||||||
if _, ok := milter.(checkForEom); ok {
|
if _, ok := milter.(checkForEom); ok {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("Eom callback implemented")
|
LoggerPrintln("Eom callback implemented")
|
||||||
}
|
}
|
||||||
C.setEom(&smfilter)
|
C.setEom(&smfilter)
|
||||||
} else {
|
} else {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("Eom callback not implemented")
|
LoggerPrintln("Eom callback not implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if Abort method was implemented
|
// Check if Abort method was implemented
|
||||||
if _, ok := milter.(checkForAbort); ok {
|
if _, ok := milter.(checkForAbort); ok {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("Abort callback implemented")
|
LoggerPrintln("Abort callback implemented")
|
||||||
}
|
}
|
||||||
C.setAbort(&smfilter)
|
C.setAbort(&smfilter)
|
||||||
} else {
|
} else {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("Abort callback not implemented")
|
LoggerPrintln("Abort callback not implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if Close method was implemented
|
// Check if Close method was implemented
|
||||||
if _, ok := milter.(checkForClose); ok {
|
if _, ok := milter.(checkForClose); ok {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("Close callback implemented")
|
LoggerPrintln("Close callback implemented")
|
||||||
}
|
}
|
||||||
C.setClose(&smfilter)
|
C.setClose(&smfilter)
|
||||||
} else {
|
} else {
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("Close callback not implemented")
|
LoggerPrintln("Close callback not implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("smfilter:")
|
LoggerPrintln("smfilter:")
|
||||||
fmt.Println(smfilter)
|
LoggerPrintln(fmt.Sprint(smfilter))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup socket connection
|
// Setup socket connection
|
||||||
@@ -753,24 +766,29 @@ func Run(amilter Milter) int {
|
|||||||
csocket := C.CString(socket)
|
csocket := C.CString(socket)
|
||||||
defer C.free(unsafe.Pointer(csocket))
|
defer C.free(unsafe.Pointer(csocket))
|
||||||
if code := C.smfi_setconn(csocket); code != 0 {
|
if code := C.smfi_setconn(csocket); code != 0 {
|
||||||
fmt.Printf("smfi_setconn failed: %d\n", code)
|
LoggerPrintf("smfi_setconn failed: %d\n", code)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register the filter
|
// Register the filter
|
||||||
if code := C.smfi_register(smfilter); code == C.MI_FAILURE {
|
if code := C.smfi_register(smfilter); code == C.MI_FAILURE {
|
||||||
fmt.Printf("smfi_register failed: %d\n", code)
|
LoggerPrintf("smfi_register failed: %d\n", code)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hand control to libmilter
|
// Hand control to libmilter
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Println("Handing over to libmilter")
|
LoggerPrintln("Handing over to libmilter")
|
||||||
}
|
}
|
||||||
result := C.smfi_main()
|
result := C.smfi_main()
|
||||||
if milter.GetDebug() {
|
if milter.GetDebug() {
|
||||||
fmt.Printf("smfi_main returned: %v\n", result)
|
LoggerPrintf("smfi_main returned: %v\n", result)
|
||||||
}
|
}
|
||||||
return int(result)
|
return int(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var LoggerPrintln func(...interface{})
|
||||||
|
var LoggerPrintf func(string, ...interface{})
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
LoggerPrintln = func(i ...interface{}) { fmt.Println(i...) }
|
||||||
|
LoggerPrintf = func(i string, j ...interface{}) { fmt.Printf(i, j...) }
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,13 +15,10 @@ Sample Milter
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
||||||
"."
|
"."
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
type Mymilter struct {
|
type Mymilter struct {
|
||||||
gomilter.MilterRaw // Embed the basic functionality. No callbacks yet
|
gomilter.MilterRaw // Embed the basic functionality. No callbacks yet
|
||||||
}
|
}
|
||||||
@@ -43,7 +40,7 @@ func main() {
|
|||||||
mymilter := new(Mymilter)
|
mymilter := new(Mymilter)
|
||||||
mymilter.FilterName = "TestFilter"
|
mymilter.FilterName = "TestFilter"
|
||||||
mymilter.Debug = true
|
mymilter.Debug = true
|
||||||
mymilter.Flags = gomilter.AddHdrs|gomilter.AddRcpt
|
mymilter.Flags = gomilter.AddHdrs | gomilter.AddRcpt
|
||||||
|
|
||||||
// Start Milter
|
// Start Milter
|
||||||
gomilter.Run(mymilter)
|
gomilter.Run(mymilter)
|
||||||
|
|||||||
@@ -7,10 +7,8 @@ Copyright (c) 2015 Leon Baker
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
||||||
m "github.com/leonrbaker/gomilter"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
m "github.com/leonrbaker/gomilter"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Mymilter struct {
|
type Mymilter struct {
|
||||||
@@ -86,7 +84,7 @@ func (milter *Mymilter) Eom(ctx uintptr) (sfsistat int8) {
|
|||||||
fmt.Println("t:", t)
|
fmt.Println("t:", t)
|
||||||
|
|
||||||
m.AddHeader(ctx, "LEONUX-Mailer",
|
m.AddHeader(ctx, "LEONUX-Mailer",
|
||||||
"test server;\n\ttest1=\"foobar\"")
|
"test server;\n\ttest1=\"foobar\"")
|
||||||
|
|
||||||
newBody := []byte("This is a new body")
|
newBody := []byte("This is a new body")
|
||||||
m.ReplaceBody(ctx, newBody)
|
m.ReplaceBody(ctx, newBody)
|
||||||
@@ -107,7 +105,7 @@ func main() {
|
|||||||
mymilter := new(Mymilter)
|
mymilter := new(Mymilter)
|
||||||
mymilter.FilterName = "TestFilter"
|
mymilter.FilterName = "TestFilter"
|
||||||
mymilter.Debug = true
|
mymilter.Debug = true
|
||||||
mymilter.Flags = m.ADDHDRS|m.ADDRCPT|m.CHGFROM|m.CHGBODY
|
mymilter.Flags = m.ADDHDRS | m.ADDRCPT | m.CHGFROM | m.CHGBODY
|
||||||
mymilter.Socket = "unix:/var/milterattachcheck/socket"
|
mymilter.Socket = "unix:/var/milterattachcheck/socket"
|
||||||
|
|
||||||
// Start Milter
|
// Start Milter
|
||||||
|
|||||||
Reference in New Issue
Block a user