Make gobencode() optional in SetPriv(), return errors instead of integers
This commit is contained in:
53
gomilter.go
53
gomilter.go
@@ -28,6 +28,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
@@ -349,14 +350,24 @@ func GetSymVal(ctx uintptr, symname string) string {
|
|||||||
return C.GoString(cval)
|
return C.GoString(cval)
|
||||||
}
|
}
|
||||||
|
|
||||||
// See also: http://bit.ly/1HVWA9I
|
// Beware that if your struct is too large it will be discarded
|
||||||
func SetPriv(ctx uintptr, privatedata interface{}) int {
|
// without storing. You may want to simply provide a reference
|
||||||
|
// to something you keep in a map or similar structure yourself.
|
||||||
|
func SetPriv(ctx uintptr, privatedata interface{}) error {
|
||||||
// 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
|
||||||
|
|
||||||
// Serialize Go privatedata into a byte slice
|
// Serialize Go privatedata into a byte slice
|
||||||
bytedata, _ := GobEncode(privatedata)
|
bytedata, err := GobEncode(privatedata)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return SetPrivBytes(ctx, bytedata)
|
||||||
|
}
|
||||||
|
|
||||||
|
// See also: http://bit.ly/1HVWA9I
|
||||||
|
func SetPrivBytes(ctx uintptr, bytedata []byte) error {
|
||||||
// length and size
|
// length and size
|
||||||
// length is a uint32 (usually 4 bytes)
|
// length is a uint32 (usually 4 bytes)
|
||||||
// the length will be stored in front of the byte sequence
|
// the length will be stored in front of the byte sequence
|
||||||
@@ -365,7 +376,7 @@ func SetPriv(ctx uintptr, privatedata interface{}) int {
|
|||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
err := binary.Write(buf, binary.BigEndian, length)
|
err := binary.Write(buf, binary.BigEndian, length)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1
|
return errors.New("Could not write binary data into buffer: " + err.Error())
|
||||||
}
|
}
|
||||||
lengthbytes := buf.Bytes()
|
lengthbytes := buf.Bytes()
|
||||||
|
|
||||||
@@ -391,10 +402,29 @@ func SetPriv(ctx uintptr, privatedata interface{}) int {
|
|||||||
|
|
||||||
// Call libmilter smfi_setpriv
|
// Call libmilter smfi_setpriv
|
||||||
type CtxPtr *C.struct_smfi_str
|
type CtxPtr *C.struct_smfi_str
|
||||||
return int(C.smfi_setpriv(int2ctx(ctx), unsafe.Pointer(lenStart)))
|
res := int(C.smfi_setpriv(int2ctx(ctx), unsafe.Pointer(lenStart)))
|
||||||
|
if res != int(C.MI_SUCCESS) {
|
||||||
|
return errors.New("smfi_setpriv() returned a failure")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPriv(ctx uintptr, privatedata interface{}) int {
|
func GetPriv(ctx uintptr, privatedata interface{}) error {
|
||||||
|
databytes, err := GetPrivBytes(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = GobDecode(databytes, privatedata)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPrivBytes(ctx uintptr) ([]byte, error) {
|
||||||
/* Retrieve the private data stored by the milter
|
/* Retrieve the private data stored by the milter
|
||||||
Retrieving the data will release the memory allocated for it
|
Retrieving the data will release the memory allocated for it
|
||||||
Don't try to retrieve it again unless you call SetPriv first
|
Don't try to retrieve it again unless you call SetPriv first
|
||||||
@@ -405,7 +435,7 @@ func GetPriv(ctx uintptr, privatedata interface{}) int {
|
|||||||
|
|
||||||
// Make sure data has been set with a previous call to SetPriv
|
// Make sure data has been set with a previous call to SetPriv
|
||||||
if CArray == nil {
|
if CArray == nil {
|
||||||
return -1
|
return nil, errors.New("smfi_getpriv() call failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read uint32 size bytes from the start of the pointer
|
// Read uint32 size bytes from the start of the pointer
|
||||||
@@ -425,7 +455,7 @@ func GetPriv(ctx uintptr, privatedata interface{}) int {
|
|||||||
buf := bytes.NewBuffer(lengthbytes)
|
buf := bytes.NewBuffer(lengthbytes)
|
||||||
err := binary.Read(buf, binary.BigEndian, &length)
|
err := binary.Read(buf, binary.BigEndian, &length)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1
|
return nil, errors.New("Could not parse binary data")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read byte sequence of data
|
// Read byte sequence of data
|
||||||
@@ -440,12 +470,7 @@ func GetPriv(ctx uintptr, privatedata interface{}) int {
|
|||||||
C.smfi_setpriv(int2ctx(ctx), nil)
|
C.smfi_setpriv(int2ctx(ctx), nil)
|
||||||
|
|
||||||
// Unserialize the data bytes back into a data structure
|
// Unserialize the data bytes back into a data structure
|
||||||
err = GobDecode(databytes, privatedata)
|
return databytes, nil
|
||||||
if err != nil {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetReply(ctx uintptr, rcode, xcode, message string) int {
|
func SetReply(ctx uintptr, rcode, xcode, message string) int {
|
||||||
|
|||||||
Reference in New Issue
Block a user