<commit_before>// Package pkcs11 is a thin wrapper around the PKCS#11 crypto library.
package pkcs11

/*
#cgo LDFLAGS: -lltdl
#define CK_PTR *
#ifndef NULL_PTR
#define NULL_PTR 0
#endif
#define CK_DEFINE_FUNCTION(returnType, name) returnType name
#define CK_DECLARE_FUNCTION(returnType, name) returnType name
#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)

#include <stdlib.h>
#include <stdio.h>
#include <ltdl.h>
#include <unistd.h>
#include "pkcs11.h"

struct ctx {
        lt_dlhandle handle;
        CK_FUNCTION_LIST_PTR sym;
};

// New initializes a ctx and fills the symbol table.
struct ctx * New(const char *module) {
        if (lt_dlinit() != 0) {
                return NULL;
        }
        CK_C_GetFunctionList list;
        struct ctx *c=  calloc(1, sizeof(struct ctx));
        c->handle = lt_dlopen(module);
        if (c->handle == NULL) {
                free(c);
                return NULL;
        }
        list = (CK_C_GetFunctionList) lt_dlsym(c->handle, "C_GetFunctionList");
        if (list == NULL) {
                free(c);
                return NULL;
        }
        list(&c->sym);
        return c;
}

// Destroy cleans up a ctx.
void Destroy(struct ctx *c) {
        if (!c) {
                return;
        }
        if (c->handle == NULL) {
                return;
        }
        if (lt_dlclose(c->handle) < 0) {
                return;
        }
        lt_dlexit();
        free(c);
}

CK_RV Initialize(struct ctx* c, CK_VOID_PTR initArgs) {
	return c->sym->C_Initialize(initArgs);
}

CK_RV Finalize(struct ctx* c) {
	return c->sym->C_Finalize(NULL_PTR);
}

CK_RV GetSlotList(struct ctx* c, CK_BBOOL tokenPresent, CK_ULONG_PTR *slotList, CK_ULONG_PTR ulCount) {
	CK_RV e = c->sym->C_GetSlotList(tokenPresent, NULL_PTR, ulCount);
	if (e != CKR_OK) {
		return e;
	}
	*slotList = calloc(1, sizeof(CK_SLOT_ID) * *ulCount);
	e = c->sym->C_GetSlotList(tokenPresent, *slotList, ulCount);
	return e;
}

CK_RV OpenSession(struct ctx* c, CK_ULONG slotID, CK_ULONG flags, CK_SESSION_HANDLE_PTR session) {
	CK_RV e = c->sym->C_OpenSession((CK_SLOT_ID)slotID, (CK_FLAGS)flags, NULL_PTR, NULL_PTR, session);
	return e;
}

CK_RV CloseSession(struct ctx *c, CK_SESSION_HANDLE session) {
	CK_RV e = c->sym->C_CloseSession(session);
	return e;
}

CK_RV CloseAllSessions(struct ctx *c, CK_ULONG slotID) {
	CK_RV e = c->sym->C_CloseAllSessions(slotID);
	return e;
}

CK_RV Login(struct ctx* c, CK_SESSION_HANDLE session, CK_USER_TYPE userType, char* pin, CK_ULONG pinLen) {
	CK_RV e = c->sym->C_Login(session, userType, (CK_UTF8CHAR_PTR)pin, pinLen);
	return e;
}

CK_RV Logout(struct ctx *c, CK_SESSION_HANDLE session) {
	CK_RV e = c->sym->C_Logout(session);
	return e;
}

CK_RV DigestInit(struct ctx *c, CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism) {
	CK_RV e = c->sym->C_DigestInit(session, mechanism);
	return e;
}

CK_RV Digest(struct ctx *c, CK_SESSION_HANDLE session, CK_BYTE_PTR message, CK_ULONG mlen, CK_BYTE_PTR *hash, CK_ULONG_PTR hashlen) {
        CK_RV rv = c->sym->C_Digest(session, message, mlen, NULL, hashlen);
        if (rv != CKR_OK) {
                return rv;
        }
        *hash = malloc(*hashlen * sizeof(CK_BYTE));
	if (*hash == NULL) {
		return CKR_HOST_MEMORY;
	}
        rv = c->sym->C_Digest(session, message, mlen, *hash, hashlen);
	return rv;
}

CK_RV GenerateKeyPair(struct ctx* c, CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
	CK_ATTRIBUTE_PTR pub, CK_ULONG pubCount, CK_ATTRIBUTE_PTR priv, CK_ULONG privCount,
	CK_OBJECT_HANDLE_PTR pubkey, CK_OBJECT_HANDLE_PTR privkey) {
	CK_RV e = c->sym->C_GenerateKeyPair(session, mechanism, pub, pubCount, priv, privCount,
					pubkey, privkey);
	return e;
}

CK_RV SignInit(struct ctx* c, CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) {
	CK_RV e = c->sym->C_SignInit(session, mechanism, key);
	return e;
}

CK_RV Sign(struct ctx *c, CK_SESSION_HANDLE session, CK_BYTE_PTR message, CK_ULONG mlen, CK_BYTE_PTR *sig, CK_ULONG_PTR siglen) {
        CK_RV rv = c->sym->C_Sign(session, message, mlen, NULL, siglen);
        if (rv != CKR_OK) {
                return rv;
        }
        *sig = malloc(*siglen * sizeof(CK_BYTE));
	if (*sig == NULL) {
		return CKR_HOST_MEMORY;
	}
        rv = c->sym->C_Sign(session, message, mlen, *sig, siglen);
	return rv;
}

CK_RV EncryptInit(struct ctx* c, CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) {
	CK_RV e = c->sym->C_EncryptInit(session, mechanism, key);
	return e;
}

CK_RV Encrypt(struct ctx *c, CK_SESSION_HANDLE session, CK_BYTE_PTR message, CK_ULONG mlen, CK_BYTE_PTR *enc, CK_ULONG_PTR enclen) {
        CK_RV rv = c->sym->C_Encrypt(session, message, mlen, NULL, enclen);
        if (rv != CKR_OK) {
                return rv;
        }
        *enc = malloc(*enclen * sizeof(CK_BYTE));
	if (*enc == NULL) {
		return CKR_HOST_MEMORY;
	}
        rv = c->sym->C_Encrypt(session, message, mlen, *enc, enclen);
	return rv;
}

*/
import "C"

import "unsafe"

// Ctx contains the current pkcs11 context.
type Ctx struct {
	ctx         *C.struct_ctx
	initialized bool
}

// New creates a new context.
func New(module string) *Ctx {
	c := new(Ctx)
	mod := C.CString(module)
	defer C.free(unsafe.Pointer(mod))
	c.ctx = C.New(mod)
	if c.ctx == nil {
		return nil
	}
	return c
}

// Destroy unload the module and frees any remaining memory.
func (c *Ctx) Destroy() {
	if c == nil {
		return
	}
	C.Destroy(c.ctx)
}

/* Initialize initializes the Cryptoki library. */
func (c *Ctx) Initialize() error {
	args := &C.CK_C_INITIALIZE_ARGS{nil, nil, nil, nil, C.CKF_OS_LOCKING_OK, nil}
	e := C.Initialize(c.ctx, C.CK_VOID_PTR(args))
	if e == C.CKR_OK {
		c.initialized = true // TODO(miek): keep?
	}
	return toError(e)
}

/* Finalize indicates that an application is done with the Cryptoki library. */
func (c *Ctx) Finalize() error {
	if !c.initialized {
		panic("pkcs11: context not initialized")
	}
	e := C.Finalize(c.ctx)
	return toError(e)
}

/* GetSlotList obtains a list of slots in the system. */
func (c *Ctx) GetSlotList(tokenPresent bool) (List, error) {
	var (
		slotList C.CK_ULONG_PTR
		ulCount  C.CK_ULONG
	)
	e := C.GetSlotList(c.ctx, cBBool(tokenPresent), &slotList, &ulCount)
	if toError(e) == nil {
		l := toList(slotList, ulCount)
		return l, nil
	}
	return nil, toError(e)
}

/* OpenSession opens a session between an application and a token. */
func (c *Ctx) OpenSession(slotID uint, flags uint) (SessionHandle, error) {
	var s C.CK_SESSION_HANDLE
	e := C.OpenSession(c.ctx, C.CK_ULONG(slotID), C.CK_ULONG(flags), C.CK_SESSION_HANDLE_PTR(&s))
	return SessionHandle(s), toError(e)
}

/* CloseSession closes a session between an application and a token. */
func (c *Ctx) CloseSession(sh SessionHandle) error {
	e := C.CloseSession(c.ctx, C.CK_SESSION_HANDLE(sh))
	return toError(e)
}

/* CloseAllSessions closes all sessions with a token. */
func (c *Ctx) CloseAllSessions(slotID uint) error {
	e := C.CloseAllSessions(c.ctx, C.CK_ULONG(slotID))
	return toError(e)
}

/* Login logs a user into a token. */
func (c *Ctx) Login(sh SessionHandle, userType uint, pin string) error {
	p := C.CString(pin)
	defer C.free(unsafe.Pointer(p))
	e := C.Login(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_USER_TYPE(userType), p, C.CK_ULONG(len(pin)))
	return toError(e)
}

/* Logout logs a user out from a token. */
func (c *Ctx) Logout(sh SessionHandle) error {
	e := C.Logout(c.ctx, C.CK_SESSION_HANDLE(sh))
	return toError(e)
}

func (c *Ctx) GenerateKeyPair(sh SessionHandle, m []*Mechanism, public, private []*Attribute) (ObjectHandle, ObjectHandle, error) {
	var (
		pubkey  C.CK_OBJECT_HANDLE
		privkey C.CK_OBJECT_HANDLE
	)
	pub, pubcount := cAttributeList(public)
	priv, privcount := cAttributeList(private)
	mech, _ := cMechanismList(m)
	e := C.GenerateKeyPair(c.ctx, C.CK_SESSION_HANDLE(sh), mech, pub, pubcount, priv, privcount, C.CK_OBJECT_HANDLE_PTR(&pubkey), C.CK_OBJECT_HANDLE_PTR(&privkey))
	e1 := toError(e)
	if e1 == nil {
		return ObjectHandle(pubkey), ObjectHandle(privkey), nil
	}
	return 0, 0, e1
}

func (c *Ctx) DigestInit(sh SessionHandle, m []*Mechanism) error {
	mech, _ := cMechanismList(m)
	e := C.DigestInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech)
	return toError(e)
}

func (c *Ctx) Digest(sh SessionHandle, message []byte) ([]byte, error) {
	var (
		hash    C.CK_BYTE_PTR
		hashlen C.CK_ULONG
	)
	e := C.Digest(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&message[0])), C.CK_ULONG(len(message)), &hash, &hashlen)
	if toError(e) != nil {
		return nil, toError(e)
	}
	h := C.GoBytes(unsafe.Pointer(hash), C.int(hashlen))
	return h, nil
}

func (c *Ctx) SignInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error {
	mech, _ := cMechanismList(m) // Only the first is used, but still use a list.
	e := C.SignInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(o))
	return toError(e)
}

func (c *Ctx) Sign(sh SessionHandle, message []byte) ([]byte, error) {
	var (
		sig    C.CK_BYTE_PTR
		siglen C.CK_ULONG
	)
	e := C.Sign(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&message[0])), C.CK_ULONG(len(message)), &sig, &siglen)
	if toError(e) != nil {
		return nil, toError(e)
	}
	s := C.GoBytes(unsafe.Pointer(sig), C.int(siglen))
	return s, nil
}

/* EncryptInit initializes an encryption operation. */
func (c *Ctx) EncryptInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error {
	mech, _ := cMechanismList(m)
	e := C.EncryptInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(o))
	return toError(e)
}

/* Encrypt encrypts single-part data. */
func (c *Ctx) Encrypt(sh SessionHandle, message []byte) ([]byte, error) {
	var (
		enc    C.CK_BYTE_PTR
		enclen C.CK_ULONG
	)
	e := C.Encrypt(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&message[0])), C.CK_ULONG(len(message)), &enc, &enclen)
	if toError(e) != nil {
		return nil, toError(e)
	}
	s := C.GoBytes(unsafe.Pointer(enc), C.int(enclen))
	return s, nil
}
<commit_msg>Add GenerateKey<commit_after>// Package pkcs11 is a thin wrapper around the PKCS#11 crypto library.
package pkcs11

/*
#cgo LDFLAGS: -lltdl
#define CK_PTR *
#ifndef NULL_PTR
#define NULL_PTR 0
#endif
#define CK_DEFINE_FUNCTION(returnType, name) returnType name
#define CK_DECLARE_FUNCTION(returnType, name) returnType name
#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)

#include <stdlib.h>
#include <stdio.h>
#include <ltdl.h>
#include <unistd.h>
#include "pkcs11.h"

struct ctx {
        lt_dlhandle handle;
        CK_FUNCTION_LIST_PTR sym;
};

// New initializes a ctx and fills the symbol table.
struct ctx * New(const char *module) {
        if (lt_dlinit() != 0) {
                return NULL;
        }
        CK_C_GetFunctionList list;
        struct ctx *c=  calloc(1, sizeof(struct ctx));
        c->handle = lt_dlopen(module);
        if (c->handle == NULL) {
                free(c);
                return NULL;
        }
        list = (CK_C_GetFunctionList) lt_dlsym(c->handle, "C_GetFunctionList");
        if (list == NULL) {
                free(c);
                return NULL;
        }
        list(&c->sym);
        return c;
}

// Destroy cleans up a ctx.
void Destroy(struct ctx *c) {
        if (!c) {
                return;
        }
        if (c->handle == NULL) {
                return;
        }
        if (lt_dlclose(c->handle) < 0) {
                return;
        }
        lt_dlexit();
        free(c);
}

CK_RV Initialize(struct ctx* c, CK_VOID_PTR initArgs) {
	return c->sym->C_Initialize(initArgs);
}

CK_RV Finalize(struct ctx* c) {
	return c->sym->C_Finalize(NULL_PTR);
}

CK_RV GetSlotList(struct ctx* c, CK_BBOOL tokenPresent, CK_ULONG_PTR *slotList, CK_ULONG_PTR ulCount) {
	CK_RV e = c->sym->C_GetSlotList(tokenPresent, NULL_PTR, ulCount);
	if (e != CKR_OK) {
		return e;
	}
	*slotList = calloc(1, sizeof(CK_SLOT_ID) * *ulCount);
	e = c->sym->C_GetSlotList(tokenPresent, *slotList, ulCount);
	return e;
}

CK_RV OpenSession(struct ctx* c, CK_ULONG slotID, CK_ULONG flags, CK_SESSION_HANDLE_PTR session) {
	CK_RV e = c->sym->C_OpenSession((CK_SLOT_ID)slotID, (CK_FLAGS)flags, NULL_PTR, NULL_PTR, session);
	return e;
}

CK_RV CloseSession(struct ctx *c, CK_SESSION_HANDLE session) {
	CK_RV e = c->sym->C_CloseSession(session);
	return e;
}

CK_RV CloseAllSessions(struct ctx *c, CK_ULONG slotID) {
	CK_RV e = c->sym->C_CloseAllSessions(slotID);
	return e;
}

CK_RV Login(struct ctx* c, CK_SESSION_HANDLE session, CK_USER_TYPE userType, char* pin, CK_ULONG pinLen) {
	CK_RV e = c->sym->C_Login(session, userType, (CK_UTF8CHAR_PTR)pin, pinLen);
	return e;
}

CK_RV Logout(struct ctx *c, CK_SESSION_HANDLE session) {
	CK_RV e = c->sym->C_Logout(session);
	return e;
}

CK_RV DigestInit(struct ctx *c, CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism) {
	CK_RV e = c->sym->C_DigestInit(session, mechanism);
	return e;
}

CK_RV Digest(struct ctx *c, CK_SESSION_HANDLE session, CK_BYTE_PTR message, CK_ULONG mlen, CK_BYTE_PTR *hash, CK_ULONG_PTR hashlen) {
        CK_RV rv = c->sym->C_Digest(session, message, mlen, NULL, hashlen);
        if (rv != CKR_OK) {
                return rv;
        }
        *hash = malloc(*hashlen * sizeof(CK_BYTE));
	if (*hash == NULL) {
		return CKR_HOST_MEMORY;
	}
        rv = c->sym->C_Digest(session, message, mlen, *hash, hashlen);
	return rv;
}

CK_RV GenerateKey(struct ctx* c, CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
	CK_ATTRIBUTE_PTR temp, CK_ULONG tempCount, CK_OBJECT_HANDLE_PTR key) {
	CK_RV e = c->sym->C_GenerateKey(session, mechanism, temp, tempCount, key);
	return e;
}

CK_RV GenerateKeyPair(struct ctx* c, CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
	CK_ATTRIBUTE_PTR pub, CK_ULONG pubCount, CK_ATTRIBUTE_PTR priv, CK_ULONG privCount,
	CK_OBJECT_HANDLE_PTR pubkey, CK_OBJECT_HANDLE_PTR privkey) {
	CK_RV e = c->sym->C_GenerateKeyPair(session, mechanism, pub, pubCount, priv, privCount,
					pubkey, privkey);
	return e;
}

CK_RV SignInit(struct ctx* c, CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) {
	CK_RV e = c->sym->C_SignInit(session, mechanism, key);
	return e;
}

CK_RV Sign(struct ctx *c, CK_SESSION_HANDLE session, CK_BYTE_PTR message, CK_ULONG mlen, CK_BYTE_PTR *sig, CK_ULONG_PTR siglen) {
        CK_RV rv = c->sym->C_Sign(session, message, mlen, NULL, siglen);
        if (rv != CKR_OK) {
                return rv;
        }
        *sig = malloc(*siglen * sizeof(CK_BYTE));
	if (*sig == NULL) {
		return CKR_HOST_MEMORY;
	}
        rv = c->sym->C_Sign(session, message, mlen, *sig, siglen);
	return rv;
}

CK_RV EncryptInit(struct ctx* c, CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) {
	CK_RV e = c->sym->C_EncryptInit(session, mechanism, key);
	return e;
}

CK_RV Encrypt(struct ctx *c, CK_SESSION_HANDLE session, CK_BYTE_PTR message, CK_ULONG mlen, CK_BYTE_PTR *enc, CK_ULONG_PTR enclen) {
        CK_RV rv = c->sym->C_Encrypt(session, message, mlen, NULL, enclen);
        if (rv != CKR_OK) {
                return rv;
        }
        *enc = malloc(*enclen * sizeof(CK_BYTE));
	if (*enc == NULL) {
		return CKR_HOST_MEMORY;
	}
        rv = c->sym->C_Encrypt(session, message, mlen, *enc, enclen);
	return rv;
}

*/
import "C"

import "unsafe"

// Ctx contains the current pkcs11 context.
type Ctx struct {
	ctx         *C.struct_ctx
	initialized bool
}

// New creates a new context.
func New(module string) *Ctx {
	c := new(Ctx)
	mod := C.CString(module)
	defer C.free(unsafe.Pointer(mod))
	c.ctx = C.New(mod)
	if c.ctx == nil {
		return nil
	}
	return c
}

// Destroy unload the module and frees any remaining memory.
func (c *Ctx) Destroy() {
	if c == nil {
		return
	}
	C.Destroy(c.ctx)
}

/* Initialize initializes the Cryptoki library. */
func (c *Ctx) Initialize() error {
	args := &C.CK_C_INITIALIZE_ARGS{nil, nil, nil, nil, C.CKF_OS_LOCKING_OK, nil}
	e := C.Initialize(c.ctx, C.CK_VOID_PTR(args))
	if e == C.CKR_OK {
		c.initialized = true // TODO(miek): keep?
	}
	return toError(e)
}

/* Finalize indicates that an application is done with the Cryptoki library. */
func (c *Ctx) Finalize() error {
	if !c.initialized {
		panic("pkcs11: context not initialized")
	}
	e := C.Finalize(c.ctx)
	return toError(e)
}

/* GetSlotList obtains a list of slots in the system. */
func (c *Ctx) GetSlotList(tokenPresent bool) (List, error) {
	var (
		slotList C.CK_ULONG_PTR
		ulCount  C.CK_ULONG
	)
	e := C.GetSlotList(c.ctx, cBBool(tokenPresent), &slotList, &ulCount)
	if toError(e) == nil {
		l := toList(slotList, ulCount)
		return l, nil
	}
	return nil, toError(e)
}

/* OpenSession opens a session between an application and a token. */
func (c *Ctx) OpenSession(slotID uint, flags uint) (SessionHandle, error) {
	var s C.CK_SESSION_HANDLE
	e := C.OpenSession(c.ctx, C.CK_ULONG(slotID), C.CK_ULONG(flags), C.CK_SESSION_HANDLE_PTR(&s))
	return SessionHandle(s), toError(e)
}

/* CloseSession closes a session between an application and a token. */
func (c *Ctx) CloseSession(sh SessionHandle) error {
	e := C.CloseSession(c.ctx, C.CK_SESSION_HANDLE(sh))
	return toError(e)
}

/* CloseAllSessions closes all sessions with a token. */
func (c *Ctx) CloseAllSessions(slotID uint) error {
	e := C.CloseAllSessions(c.ctx, C.CK_ULONG(slotID))
	return toError(e)
}

/* Login logs a user into a token. */
func (c *Ctx) Login(sh SessionHandle, userType uint, pin string) error {
	p := C.CString(pin)
	defer C.free(unsafe.Pointer(p))
	e := C.Login(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_USER_TYPE(userType), p, C.CK_ULONG(len(pin)))
	return toError(e)
}

/* Logout logs a user out from a token. */
func (c *Ctx) Logout(sh SessionHandle) error {
	e := C.Logout(c.ctx, C.CK_SESSION_HANDLE(sh))
	return toError(e)
}

/* GenerateKey generates a secret key, creating a new key object. */
func (c *Ctx) GenerateKey(sh SessionHandle, m []*Mechanism, temp []*Attribute) (ObjectHandle, error) {
	var key  C.CK_OBJECT_HANDLE
	t, tcount := cAttributeList(temp)
	mech, _ := cMechanismList(m)
	e := C.GenerateKey(c.ctx, C.CK_SESSION_HANDLE(sh), mech, t, tcount, C.CK_OBJECT_HANDLE_PTR(&key))
	e1 := toError(e)
	if e1 == nil {
		return ObjectHandle(key), nil
	}
	return 0, e1
}

/* GenerateKeyPair generates a public-key/private-key pair creating new key objects. */
func (c *Ctx) GenerateKeyPair(sh SessionHandle, m []*Mechanism, public, private []*Attribute) (ObjectHandle, ObjectHandle, error) {
	var (
		pubkey  C.CK_OBJECT_HANDLE
		privkey C.CK_OBJECT_HANDLE
	)
	pub, pubcount := cAttributeList(public)
	priv, privcount := cAttributeList(private)
	mech, _ := cMechanismList(m)
	e := C.GenerateKeyPair(c.ctx, C.CK_SESSION_HANDLE(sh), mech, pub, pubcount, priv, privcount, C.CK_OBJECT_HANDLE_PTR(&pubkey), C.CK_OBJECT_HANDLE_PTR(&privkey))
	e1 := toError(e)
	if e1 == nil {
		return ObjectHandle(pubkey), ObjectHandle(privkey), nil
	}
	return 0, 0, e1
}

func (c *Ctx) DigestInit(sh SessionHandle, m []*Mechanism) error {
	mech, _ := cMechanismList(m)
	e := C.DigestInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech)
	return toError(e)
}

func (c *Ctx) Digest(sh SessionHandle, message []byte) ([]byte, error) {
	var (
		hash    C.CK_BYTE_PTR
		hashlen C.CK_ULONG
	)
	e := C.Digest(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&message[0])), C.CK_ULONG(len(message)), &hash, &hashlen)
	if toError(e) != nil {
		return nil, toError(e)
	}
	h := C.GoBytes(unsafe.Pointer(hash), C.int(hashlen))
	return h, nil
}

func (c *Ctx) SignInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error {
	mech, _ := cMechanismList(m) // Only the first is used, but still use a list.
	e := C.SignInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(o))
	return toError(e)
}

func (c *Ctx) Sign(sh SessionHandle, message []byte) ([]byte, error) {
	var (
		sig    C.CK_BYTE_PTR
		siglen C.CK_ULONG
	)
	e := C.Sign(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&message[0])), C.CK_ULONG(len(message)), &sig, &siglen)
	if toError(e) != nil {
		return nil, toError(e)
	}
	s := C.GoBytes(unsafe.Pointer(sig), C.int(siglen))
	return s, nil
}

/* EncryptInit initializes an encryption operation. */
func (c *Ctx) EncryptInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error {
	mech, _ := cMechanismList(m)
	e := C.EncryptInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(o))
	return toError(e)
}

/* Encrypt encrypts single-part data. */
func (c *Ctx) Encrypt(sh SessionHandle, message []byte) ([]byte, error) {
	var (
		enc    C.CK_BYTE_PTR
		enclen C.CK_ULONG
	)
	e := C.Encrypt(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&message[0])), C.CK_ULONG(len(message)), &enc, &enclen)
	if toError(e) != nil {
		return nil, toError(e)
	}
	s := C.GoBytes(unsafe.Pointer(enc), C.int(enclen))
	return s, nil
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"fmt"
	"io"
	"os"
	"os/user"
	"path/filepath"
	"regexp"
	"strings"
	"time"
	"unicode"

	"github.com/chzyer/readline"
	"github.com/knq/dburl"
	"github.com/knq/xoutil"
	"github.com/olekukonko/tablewriter"
)

const (
	notConnected = "(not connected)"
)

// Handler is a cli input handler.
type Handler struct {
	args        *Args
	interactive bool

	u  *dburl.URL
	db *sql.DB
}

// Prompt returns the base input prompt.
func (h *Handler) Prompt() string {
	if !h.interactive {
		return ""
	}

	s := notConnected

	if h.db != nil {
		s = h.u.Short()
	}

	return s + "=> "
}

// Cont returns the continuation prompt.
func (h *Handler) Cont() string {
	if !h.interactive {
		return ""
	}

	s := notConnected

	if h.db != nil {
		s = h.u.Short()
	}

	return s + "-> "
}

// Open handles opening a specified database URL.
func (h *Handler) Open(urlstr string) error {
	if urlstr == "" {
		return nil
	}

	// parse dsn
	var err error
	h.u, err = dburl.Parse(urlstr)
	switch {
	case err == dburl.ErrInvalidDatabaseScheme:
		if fi, err := os.Stat(urlstr); err == nil {
			// TODO: add support for postgres unix domain sockets
			if fi.Mode()&os.ModeSocket != 0 {
				return h.Open("mysql+unix:" + urlstr)
			}

			// it is a file, so reattempt to open it with sqlite3
			return h.Open("sqlite3:" + urlstr)
		}

		return err

	case err != nil:
		return err
	}

	// check driver
	if !drivers[h.u.Driver] {
		if h.u.Driver == "ora" {
			return ErrOracleDriverNotAvailable
		}
		return fmt.Errorf("driver '%s' is not available for '%s'", h.u.Driver, h.u.Scheme)
	}

	// add connection parameters for databases
	dsn := h.u.DSN
	dsn = h.addQueryParam(dsn, "mysql", "parseTime", "true")
	dsn = h.addQueryParam(dsn, "mysql", "loc", "Local")
	dsn = h.addQueryParam(dsn, "sqlite3", "loc", "auto")

	//log.Printf(">>> dsn: %s", dsn)

	// connect
	h.db, err = sql.Open(h.u.Driver, dsn)
	return err
}

// addQueryParam conditionally adds a ?name=val style query parameter to the
// end of a DSN if the connected database driver matches the supplied driver
// name.
func (h *Handler) addQueryParam(dsn, driver, name, val string) string {
	if h.u.Driver == driver {
		if !strings.Contains(dsn, name+"=") {
			s := "?"
			if strings.Contains(dsn, "?") {
				s = "&"
			}
			return dsn + s + name + "=" + val
		}
	}

	return dsn
}

// Execute executes a sql query against the connected database.
func (h *Handler) Execute(w io.Writer, sqlstr string) error {
	if h.db == nil {
		return ErrNotConnected
	}

	if h.u.Driver == "ora" {
		sqlstr = strings.TrimSuffix(sqlstr, ";")
	}

	// select
	if s := strings.TrimLeftFunc(sqlstr, unicode.IsSpace); len(s) >= 5 {
		i := strings.IndexFunc(s, unicode.IsSpace)
		if i == -1 {
			i = len(s)
		}

		z := strings.ToUpper(s[:i])
		if z == "SELECT" ||
			(h.u.Driver == "sqlite3" && z == "PRAGMA" && !strings.ContainsRune(s[i:], '=')) {
			err := h.Query(w, sqlstr)
			if err != nil {
				return h.wrapError(err)
			}

			return nil
		}
	}

	// exec
	res, err := h.db.Exec(sqlstr)
	if err != nil {
		return err
	}

	// get count
	count, err := res.RowsAffected()
	if err != nil {
		return err
	}

	// print name
	name := "EXEC"
	if i := strings.Index(sqlstr, " "); i >= 0 {
		name = strings.ToUpper(sqlstr[:i])
	}
	fmt.Fprint(w, name)

	// print count
	if count > 0 {
		fmt.Fprintf(w, " %d", count)
	}

	fmt.Fprint(w, "\n")

	return nil
}

var allcapsRE = regexp.MustCompile(`^[A-Z_]+$`)

// Query executes a query against the database.
func (h *Handler) Query(w io.Writer, sqlstr string) error {
	// run query
	q, err := h.db.Query(sqlstr)
	if err != nil {
		return err
	}
	defer q.Close()

	// get column names
	cols, err := q.Columns()
	if err != nil {
		return err
	}

	// fix display column names
	for i, s := range cols {
		s = strings.TrimSpace(s)
		if len(s) == 0 {
			cols[i] = fmt.Sprintf("col%d", i)
		}

		// fix case on oracle column names
		if h.u.Driver == "ora" && allcapsRE.MatchString(cols[i]) {
			cols[i] = strings.ToLower(cols[i])
		}
	}

	// create output table
	t := tablewriter.NewWriter(w)
	t.SetAutoFormatHeaders(false)
	t.SetBorder(false)
	t.SetHeader(cols)

	clen := len(cols)
	var rows int
	if clen != 0 {
		for q.Next() {
			r := make([]interface{}, clen)
			for i := range r {
				r[i] = new(interface{})
			}

			err = q.Scan(r...)
			if err != nil {
				return err
			}

			row := make([]string, clen)
			for n, z := range r {
				j := z.(*interface{})

				//log.Printf(">>> %s: %s", cols[n], reflect.TypeOf(*j))

				switch x := (*j).(type) {
				case []byte:
					if h.u.Driver == "sqlite3" {
						row[n] = h.sqlite3Parse(x)
					} else {
						row[n] = string(x)
					}

				case string:
					row[n] = x

				case time.Time:
					row[n] = x.Format(time.RFC3339Nano)

				case fmt.Stringer:
					row[n] = x.String()

				default:
					row[n] = fmt.Sprintf("%v", *j)
				}

			}
			t.Append(row)
			rows++
		}
	}

	t.Render()
	fmt.Fprintf(w, "(%d rows)\n\n", rows)

	return nil
}

// sqlite3Parse will convert buf matching a time format to a time, and will
// format it according to the handler time settings.
//
// TODO: only do this if the type of the column is a timestamp type.
func (h *Handler) sqlite3Parse(buf []byte) string {
	s := string(buf)
	if s != "" && strings.TrimSpace(s) != "" {
		t := &xoutil.SqTime{}
		err := t.Scan(buf)
		if err == nil {
			return t.Format(time.RFC3339Nano)
		}
	}

	return s
}

// HistoryFile returns the name of the history file.
func (h *Handler) HistoryFile() string {
	u, err := user.Current()
	if err != nil {
		panic(err)
	}

	return filepath.Join(u.HomeDir, ".usql_history")
}

// DisplayHelp displays the help message.
func (h *Handler) DisplayHelp(w io.Writer) {
	io.WriteString(w, helpDesc)
}

// Close closes the database connection if it is open.
func (h *Handler) Close() error {
	if h.db != nil {
		err := h.db.Close()

		h.db = nil
		h.u = nil

		return err
	}

	return nil
}

// Run processes h.args, running either the Commands if non-empty, or File if
// specified, or the input from stdin.
func (h *Handler) Run() error {
	var err error

	// open
	err = h.Open(h.args.DSN)
	if err != nil {
		return err
	}

	// short circuit if commands provided
	if len(h.args.Commands) > 0 {
		return h.RunCommands()
	}

	// configure input
	var stdin *os.File
	stdout, stderr := os.Stdout, os.Stderr

	// set file as stdin
	if h.args.File != "" {
		stdin, err = os.OpenFile(h.args.File, os.O_RDONLY, 0)
		if err != nil {
			return err
		}
		defer stdin.Close()

		h.interactive = false
	}

	// set out as stdout
	if h.args.Out != "" {
		stdout, err = os.OpenFile(h.args.Out, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
		if err != nil {
			return err
		}
		defer stdout.Close()

		h.interactive = false
	}

	// set stdin if not set
	var r io.Reader = stdin
	if stdin == nil {
		c := readline.NewCancelableStdin(os.Stdin)
		defer c.Close()

		r = c
	}

	return h.Process(r, stdout, stderr)
}

// Run handles stuff
func (h *Handler) Process(stdin io.Reader, stdout, stderr io.Writer) error {
	var err error

	// create readline instance
	l, err := readline.NewEx(&readline.Config{
		Prompt:                 h.Prompt(),
		HistoryFile:            h.HistoryFile(),
		DisableAutoSaveHistory: true,
		InterruptPrompt:        "^C",
		HistorySearchFold:      true,
		Stdin:                  stdin,
		Stdout:                 stdout,
		Stderr:                 stderr,
		FuncIsTerminal: func() bool {
			return h.interactive
		},
		FuncFilterInputRune: func(r rune) (rune, bool) {
			if r == readline.CharCtrlZ {
				return r, false
			}
			return r, true
		},
	})
	if err != nil {
		return err
	}
	defer l.Close()

	if h.interactive {
		fmt.Fprint(l.Stdout(), cliDesc)
	}

	// process input
	var multi bool
	var stmt []string
	for {
		line, err := l.Readline()
		switch {
		case err == readline.ErrInterrupt:
			stmt = stmt[:0]
			multi = false
			l.SetPrompt(h.Prompt())
			continue

		case err != nil:
			return nil
		}

		z := strings.TrimSpace(line)
		if len(z) == 0 {
			continue
		}

		if !multi {
			switch {
			case z == "help":
				h.DisplayHelp(l.Stdout())
				continue

			case z == `\q`:
				h.SaveHistory(l, line)
				return nil

			case strings.HasPrefix(line, `\c `) || strings.HasPrefix(line, `\connect `):
				h.SaveHistory(l, line)

				err = h.Close()
				if err != nil {
					return err
				}

				urlstr := strings.TrimSpace(line[strings.IndexRune(line, ' '):])
				err = h.Open(urlstr)
				if err != nil {
					fmt.Fprintf(l.Stderr(), "error: could not connect to database: %v\n", err)
				}

				l.SetPrompt(h.Prompt())
				continue

			case z == `\Z`:
				h.SaveHistory(l, line)

				err = h.Close()
				if err != nil {
					return err
				}

				l.SetPrompt(h.Prompt())
				continue
			}
		}

		stmt = append(stmt, line)

		if !strings.HasSuffix(z, ";") {
			multi = true
			l.SetPrompt(h.Cont())
			continue
		}

		s := strings.Join(stmt, "\n")
		h.SaveHistory(l, s)
		l.SetPrompt(h.Prompt())

		err = h.Execute(l.Stdout(), s)
		if err != nil {
			fmt.Fprintf(l.Stderr(), "error: %v\n", h.wrapError(err))
		}

		stmt = stmt[:0]
		multi = false
	}
}

// SaveHistory conditionally saves a line to the history if the session is
// interactive.
func (h *Handler) SaveHistory(l *readline.Instance, line string) error {
	if h.interactive {
		return l.SaveHistory(line)
	}

	return nil
}

// RunCommands runs the argument commands.
func (h *Handler) RunCommands() error {
	h.interactive = false

	var err error
	for _, c := range h.args.Commands {
		err = h.Process(strings.NewReader(c), os.Stdout, os.Stderr)
		if err != nil {
			return err
		}
	}

	return nil
}

// driverError is a wrapper to standardize errors.
type driverError struct {
	driver string
	err    error
}

// Error satisfies the error interface.
func (e *driverError) Error() string {
	if e.driver != "" {
		s := e.err.Error()
		return e.driver + ": " + strings.TrimLeftFunc(strings.TrimPrefix(strings.TrimSpace(s), e.driver+":"), unicode.IsSpace)
	}

	return e.err.Error()
}

// wrapError conditionally wraps an error if the error occurs while connected
// to a database.
func (h *Handler) wrapError(err error) error {
	if h.db != nil {
		// attempt to clean up and standardize errors
		driver := h.u.Driver
		if driver == "postgres" {
			driver = "pq"
		}

		return &driverError{driver, err}
	}

	return err
}
<commit_msg>Fixing last commit<commit_after>package main

import (
	"database/sql"
	"fmt"
	"io"
	"os"
	"os/user"
	"path/filepath"
	"regexp"
	"strings"
	"time"
	"unicode"

	"github.com/chzyer/readline"
	"github.com/knq/dburl"
	"github.com/knq/xoutil"
	"github.com/olekukonko/tablewriter"
)

const (
	notConnected = "(not connected)"
)

// Handler is a cli input handler.
type Handler struct {
	args        *Args
	interactive bool

	u  *dburl.URL
	db *sql.DB
}

// Prompt returns the base input prompt.
func (h *Handler) Prompt() string {
	if !h.interactive {
		return ""
	}

	s := notConnected

	if h.db != nil {
		s = h.u.Short()
	}

	return s + "=> "
}

// Cont returns the continuation prompt.
func (h *Handler) Cont() string {
	if !h.interactive {
		return ""
	}

	s := notConnected

	if h.db != nil {
		s = h.u.Short()
	}

	return s + "-> "
}

// Open handles opening a specified database URL.
func (h *Handler) Open(urlstr string) error {
	if urlstr == "" {
		return nil
	}

	// parse dsn
	var err error
	h.u, err = dburl.Parse(urlstr)
	switch {
	case err == dburl.ErrInvalidDatabaseScheme:
		if fi, err := os.Stat(urlstr); err == nil {
			// TODO: add support for postgres unix domain sockets
			if fi.Mode()&os.ModeSocket != 0 {
				return h.Open("mysql+unix:" + urlstr)
			}

			// it is a file, so reattempt to open it with sqlite3
			return h.Open("sqlite3:" + urlstr)
		}

		return err

	case err != nil:
		return err
	}

	// check driver
	if !drivers[h.u.Driver] {
		if h.u.Driver == "ora" {
			return ErrOracleDriverNotAvailable
		}
		return fmt.Errorf("driver '%s' is not available for '%s'", h.u.Driver, h.u.Scheme)
	}

	// add connection parameters for databases
	dsn := h.u.DSN
	dsn = h.addQueryParam(dsn, "mysql", "parseTime", "true")
	dsn = h.addQueryParam(dsn, "mysql", "loc", "Local")
	dsn = h.addQueryParam(dsn, "sqlite3", "loc", "auto")

	//log.Printf(">>> dsn: %s", dsn)

	// connect
	h.db, err = sql.Open(h.u.Driver, dsn)
	return err
}

// addQueryParam conditionally adds a ?name=val style query parameter to the
// end of a DSN if the connected database driver matches the supplied driver
// name.
func (h *Handler) addQueryParam(dsn, driver, name, val string) string {
	if h.u.Driver == driver {
		if !strings.Contains(dsn, name+"=") {
			s := "?"
			if strings.Contains(dsn, "?") {
				s = "&"
			}
			return dsn + s + name + "=" + val
		}
	}

	return dsn
}

// Execute executes a sql query against the connected database.
func (h *Handler) Execute(w io.Writer, sqlstr string) error {
	if h.db == nil {
		return ErrNotConnected
	}

	if h.u.Driver == "ora" {
		sqlstr = strings.TrimSuffix(sqlstr, ";")
	}

	// select
	if s := strings.TrimLeftFunc(sqlstr, unicode.IsSpace); len(s) >= 5 {
		i := strings.IndexFunc(s, unicode.IsSpace)
		if i == -1 {
			i = len(s)
		}

		z := strings.ToUpper(s[:i])
		if z == "SELECT" ||
			(h.u.Driver == "sqlite3" && z == "PRAGMA" && !strings.ContainsRune(s[i:], '=')) {
			err := h.Query(w, sqlstr)
			if err != nil {
				return h.wrapError(err)
			}

			return nil
		}
	}

	// exec
	res, err := h.db.Exec(sqlstr)
	if err != nil {
		return err
	}

	// get count
	count, err := res.RowsAffected()
	if err != nil {
		return err
	}

	// print name
	name := "EXEC"
	if i := strings.Index(sqlstr, " "); i >= 0 {
		name = strings.ToUpper(sqlstr[:i])
	}
	fmt.Fprint(w, name)

	// print count
	if count > 0 {
		fmt.Fprintf(w, " %d", count)
	}

	fmt.Fprint(w, "\n")

	return nil
}

var allcapsRE = regexp.MustCompile(`^[A-Z_]+$`)

// Query executes a query against the database.
func (h *Handler) Query(w io.Writer, sqlstr string) error {
	// run query
	q, err := h.db.Query(sqlstr)
	if err != nil {
		return err
	}
	defer q.Close()

	// get column names
	cols, err := q.Columns()
	if err != nil {
		return err
	}

	// fix display column names
	for i, s := range cols {
		s = strings.TrimSpace(s)
		if len(s) == 0 {
			cols[i] = fmt.Sprintf("col%d", i)
		}

		// fix case on oracle column names
		if h.u.Driver == "ora" && allcapsRE.MatchString(cols[i]) {
			cols[i] = strings.ToLower(cols[i])
		}
	}

	// create output table
	t := tablewriter.NewWriter(w)
	t.SetAutoFormatHeaders(false)
	t.SetBorder(false)
	t.SetHeader(cols)

	clen := len(cols)
	var rows int
	if clen != 0 {
		for q.Next() {
			r := make([]interface{}, clen)
			for i := range r {
				r[i] = new(interface{})
			}

			err = q.Scan(r...)
			if err != nil {
				return err
			}

			row := make([]string, clen)
			for n, z := range r {
				j := z.(*interface{})

				//log.Printf(">>> %s: %s", cols[n], reflect.TypeOf(*j))

				switch x := (*j).(type) {
				case []byte:
					if h.u.Driver == "sqlite3" {
						row[n] = h.sqlite3Parse(x)
					} else {
						row[n] = string(x)
					}

				case string:
					row[n] = x

				case time.Time:
					row[n] = x.Format(time.RFC3339Nano)

				case fmt.Stringer:
					row[n] = x.String()

				default:
					row[n] = fmt.Sprintf("%v", *j)
				}

			}
			t.Append(row)
			rows++
		}
	}

	t.Render()
	fmt.Fprintf(w, "(%d rows)\n\n", rows)

	return nil
}

// sqlite3Parse will convert buf matching a time format to a time, and will
// format it according to the handler time settings.
//
// TODO: only do this if the type of the column is a timestamp type.
func (h *Handler) sqlite3Parse(buf []byte) string {
	s := string(buf)
	if s != "" && strings.TrimSpace(s) != "" {
		t := &xoutil.SqTime{}
		err := t.Scan(buf)
		if err == nil {
			return t.Format(time.RFC3339Nano)
		}
	}

	return s
}

// HistoryFile returns the name of the history file.
func (h *Handler) HistoryFile() string {
	u, err := user.Current()
	if err != nil {
		panic(err)
	}

	return filepath.Join(u.HomeDir, ".usql_history")
}

// DisplayHelp displays the help message.
func (h *Handler) DisplayHelp(w io.Writer) {
	io.WriteString(w, helpDesc)
}

// Close closes the database connection if it is open.
func (h *Handler) Close() error {
	if h.db != nil {
		err := h.db.Close()

		h.db = nil
		h.u = nil

		return err
	}

	return nil
}

// Run processes h.args, running either the Commands if non-empty, or File if
// specified, or the input from stdin.
func (h *Handler) Run() error {
	var err error

	// open
	err = h.Open(h.args.DSN)
	if err != nil {
		return err
	}

	// short circuit if commands provided
	if len(h.args.Commands) > 0 {
		return h.RunCommands()
	}

	// configure input
	var stdin *os.File
	stdout, stderr := os.Stdout, os.Stderr

	// set file as stdin
	if h.args.File != "" {
		stdin, err = os.OpenFile(h.args.File, os.O_RDONLY, 0)
		if err != nil {
			return err
		}
		defer stdin.Close()

		h.interactive = false
	}

	// set out as stdout
	if h.args.Out != "" {
		stdout, err = os.OpenFile(h.args.Out, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
		if err != nil {
			return err
		}
		defer stdout.Close()

		h.interactive = false
	}

	// set stdin if not set
	var r io.Reader = stdin
	if stdin == nil {
		c := readline.NewCancelableStdin(os.Stdin)
		defer c.Close()

		r = c
	}

	return h.Process(r, stdout, stderr)
}

// Run handles stuff
func (h *Handler) Process(stdin io.Reader, stdout, stderr io.Writer) error {
	var err error

	// create readline instance
	l, err := readline.NewEx(&readline.Config{
		Prompt:                 h.Prompt(),
		HistoryFile:            h.HistoryFile(),
		DisableAutoSaveHistory: true,
		InterruptPrompt:        "^C",
		HistorySearchFold:      true,
		Stdin:                  stdin,
		Stdout:                 stdout,
		Stderr:                 stderr,
		FuncIsTerminal: func() bool {
			return h.interactive
		},
		FuncFilterInputRune: func(r rune) (rune, bool) {
			if r == readline.CharCtrlZ {
				return r, false
			}
			return r, true
		},
	})
	if err != nil {
		return err
	}
	defer l.Close()

	if h.interactive {
		fmt.Fprint(l.Stdout(), welcomeDesc)
	}

	// process input
	var multi bool
	var stmt []string
	for {
		line, err := l.Readline()
		switch {
		case err == readline.ErrInterrupt:
			stmt = stmt[:0]
			multi = false
			l.SetPrompt(h.Prompt())
			continue

		case err != nil:
			return nil
		}

		z := strings.TrimSpace(line)
		if len(z) == 0 {
			continue
		}

		if !multi {
			switch {
			case z == "help":
				h.DisplayHelp(l.Stdout())
				continue

			case z == `\q`:
				h.SaveHistory(l, line)
				return nil

			case strings.HasPrefix(line, `\c `) || strings.HasPrefix(line, `\connect `):
				h.SaveHistory(l, line)

				err = h.Close()
				if err != nil {
					return err
				}

				urlstr := strings.TrimSpace(line[strings.IndexRune(line, ' '):])
				err = h.Open(urlstr)
				if err != nil {
					fmt.Fprintf(l.Stderr(), "error: could not connect to database: %v\n", err)
				}

				l.SetPrompt(h.Prompt())
				continue

			case z == `\Z`:
				h.SaveHistory(l, line)

				err = h.Close()
				if err != nil {
					return err
				}

				l.SetPrompt(h.Prompt())
				continue
			}
		}

		stmt = append(stmt, line)

		if !strings.HasSuffix(z, ";") {
			multi = true
			l.SetPrompt(h.Cont())
			continue
		}

		s := strings.Join(stmt, "\n")
		h.SaveHistory(l, s)
		l.SetPrompt(h.Prompt())

		err = h.Execute(l.Stdout(), s)
		if err != nil {
			fmt.Fprintf(l.Stderr(), "error: %v\n", h.wrapError(err))
		}

		stmt = stmt[:0]
		multi = false
	}
}

// SaveHistory conditionally saves a line to the history if the session is
// interactive.
func (h *Handler) SaveHistory(l *readline.Instance, line string) error {
	if h.interactive {
		return l.SaveHistory(line)
	}

	return nil
}

// RunCommands runs the argument commands.
func (h *Handler) RunCommands() error {
	h.interactive = false

	var err error
	for _, c := range h.args.Commands {
		err = h.Process(strings.NewReader(c), os.Stdout, os.Stderr)
		if err != nil {
			return err
		}
	}

	return nil
}

// driverError is a wrapper to standardize errors.
type driverError struct {
	driver string
	err    error
}

// Error satisfies the error interface.
func (e *driverError) Error() string {
	if e.driver != "" {
		s := e.err.Error()
		return e.driver + ": " + strings.TrimLeftFunc(strings.TrimPrefix(strings.TrimSpace(s), e.driver+":"), unicode.IsSpace)
	}

	return e.err.Error()
}

// wrapError conditionally wraps an error if the error occurs while connected
// to a database.
func (h *Handler) wrapError(err error) error {
	if h.db != nil {
		// attempt to clean up and standardize errors
		driver := h.u.Driver
		if driver == "postgres" {
			driver = "pq"
		}

		return &driverError{driver, err}
	}

	return err
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/deckarep/golang-set"
	"math/rand"
	"sort"
)

// AllColors is a list of the available player colors
var AllColors = []interface{}{
	"green",
	"blue",
	"pink",
	"orange",
	"white",
	"yellow",
	"cyan",
	"purple",
	"red",
}

// Colors is the definitive set of all the colors
var Colors = mapset.NewSetFromSlice(AllColors)

// ScoreData is a structured Key/Value pair list for scores
type ScoreData struct {
	Key    string
	Value  int
	Player *Player
}

// Player is a Participant that is actively participating in battles.
type Player struct {
	Person         *Person `json:"person"`
	Color          string  `json:"color"`
	PreferredColor string  `json:"preferred_color"`
	Shots          int     `json:"shots"`
	Sweeps         int     `json:"sweeps"`
	Kills          int     `json:"kills"`
	Self           int     `json:"self"`
	Explosions     int     `json:"explosions"`
	Matches        int     `json:"matches"`
	TotalScore     int     `json:"score"`
	Match          *Match  `json:"-"`
}

// NewPlayer returns a new instance of a player
func NewPlayer(ps *Person) *Player {
	p := &Player{Person: ps}
	if len(p.PreferredColor) > 0 {
		p.PreferredColor = ps.ColorPreference[0]
	} else {
		p.PreferredColor = RandomColor(Colors)
	}

	return p
}

func (p *Player) String() string {
	return fmt.Sprintf(
		"<%s: %dsh %dsw %dk %ds %de>",
		p.Name(),
		p.Shots,
		p.Sweeps,
		p.Kills,
		p.Self,
		p.Explosions,
	)
}

// Name returns the nickname
func (p *Player) Name() string {
	return p.Person.Nick
}

// Score calculates the score to determine runnerup positions.
func (p *Player) Score() (out int) {
	// This algorithm is probably flawed, but at least it should be able to
	// determine who is the most entertaining.
	// When executed, a sweep is basically 14 points since scoring a sweep
	// also comes with a shot and three kills.

	out += p.Sweeps * 5
	out += p.Shots * 3
	out += p.Kills * 2
	out += p.Self
	out += p.Explosions

	return
}

// ScoreData returns this players set of ScoreData
func (p *Player) ScoreData() []ScoreData {
	sd := []ScoreData{
		{Key: "kills", Value: p.Kills, Player: p},
		{Key: "shots", Value: p.Shots, Player: p},
		{Key: "sweeps", Value: p.Sweeps, Player: p},
		{Key: "self", Value: p.Self, Player: p},
		{Key: "explosions", Value: p.Explosions, Player: p},
	}
	return sd
}

// URL returns the URL to this player
//
// Used for action URLs
func (p *Player) URL() string {
	out := fmt.Sprintf(
		"%s/%d",
		p.Match.URL(),
		p.Index(),
	)
	return out
}

// Classes returns the CSS color classes for the player
func (p *Player) Classes() string {
	if p.Match != nil && p.Match.IsEnded() {
		ps := ByScore(p.Match.Players)
		if ps[0].Name() == p.Name() {
			// Always gold for the winner
			return "gold"
		} else if ps[1].Name() == p.Name() {
			// Silver for the second, unless there is a short amount of tryouts
			if p.Match.Kind != "tryout" || len(p.Match.Tournament.Tryouts) <= 4 {
				return "silver"
			}
		} else if ps[2].Name() == p.Name() && p.Match.Kind == "final" {
			return "bronze"
		}

		return "out"
	}
	return p.PreferredColor
}

// Index returns the index in the current match
func (p *Player) Index() int {
	if p.Match != nil {
		for i, o := range p.Match.Players {
			if p.Name() == o.Name() {
				return i
			}
		}
	}
	return -1
}

// Action performs an action for a player
func (p *Player) Action(action, dir string) error {
	// TODO: This could use with a refactoring...
	if dir == "up" {
		switch action {
		case "kills":
			p.AddKill()
		case "shots":
			p.AddShot()
		case "sweeps":
			p.AddSweep()
		case "self":
			p.AddSelf()
		case "explosions":
			p.AddExplosion()
		}
	} else {
		switch action {
		case "kills":
			p.RemoveKill()
		case "shots":
			p.RemoveShot()
		case "sweeps":
			p.RemoveSweep()
		case "self":
			p.RemoveSelf()
		case "explosions":
			p.RemoveExplosion()
		}
	}

	// Save the change to the database
	p.Match.Tournament.Persist()

	return nil
}

// AddShot increases the shot count
func (p *Player) AddShot() {
	p.Shots++
}

// RemoveShot decreases the shot count
// Fails silently if shots are zero.
func (p *Player) RemoveShot() {
	if p.Shots == 0 {
		return
	}
	p.Shots--
}

// AddSweep increases the sweep count, gives three kills and a shot.
func (p *Player) AddSweep() {
	p.Sweeps++
	p.AddShot()
	p.AddKill()
	p.AddKill()
	p.AddKill()
}

// RemoveSweep decreases the sweep count, three kills and a shot
// Fails silently if sweeps are zero.
func (p *Player) RemoveSweep() {
	if p.Sweeps == 0 {
		return
	}
	p.Sweeps--
	p.RemoveShot()
	p.RemoveKill()
	p.RemoveKill()
	p.RemoveKill()
}

// AddKill increases the kill count
func (p *Player) AddKill(kills ...int) {
	// This is basically only to help out with testing.
	// Adding an optional argument with the amount of kills lets us just use
	// one call to AddKill() rather than 10.
	if len(kills) > 0 {
		p.Kills += kills[0]
	} else {
		p.Kills++
	}
}

// RemoveKill decreases the kill count
// Fails silently if kills are zero.
func (p *Player) RemoveKill() {
	if p.Kills == 0 {
		return
	}
	p.Kills--
}

// AddSelf increases the self count, decreases the kill, and gives a shot
func (p *Player) AddSelf() {
	p.Self++
	p.RemoveKill()
	p.AddShot()
}

// RemoveSelf decreases the self count and a shot
// Fails silently if selfs are zero.
func (p *Player) RemoveSelf() {
	if p.Self == 0 {
		return
	}
	p.Self--
	p.AddKill()
	p.RemoveShot()
}

// AddExplosion increases the explosion count, the kill count and gives a shot
func (p *Player) AddExplosion() {
	p.Explosions++
	p.AddShot()
	p.AddKill()
}

// RemoveExplosion decreases the explosion count, a shot and a kill
// Fails silently if Explosions are zero.
func (p *Player) RemoveExplosion() {
	if p.Explosions == 0 {
		return
	}
	p.Explosions--
	p.RemoveShot()
	p.RemoveKill()
}

// Reset resets the stats on a Player to 0
//
// It is to be run in Match.Start()
func (p *Player) Reset() {
	p.Shots = 0
	p.Sweeps = 0
	p.Kills = 0
	p.Self = 0
	p.Explosions = 0
	p.Matches = 0
}

// Update updates a player with the scores of another
//
// This is primarily used by the tournament score calculator
func (p *Player) Update(other Player) {
	p.Shots += other.Shots
	p.Sweeps += other.Sweeps
	p.Kills += other.Kills
	p.Self += other.Self
	p.Explosions += other.Explosions
	p.TotalScore = p.Score()

	// Every call to this method is per match. Count every call
	// as if a match.
	p.Matches++
	// log.Printf("Updated player: %d, %d", p.TotalScore, p.Matches)
}

// HTML renders the HTML of a player
func (p *Player) HTML() (out string) {
	return
}

// ByScore is a sort.Interface that sorts players by their score
type ByScore []Player

func (s ByScore) Len() int {
	return len(s)

}
func (s ByScore) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByScore) Less(i, j int) bool {
	// Technically not Less, but we want biggest first...
	return s[i].Score() > s[j].Score()
}

// SortByScore returns a list in order of the score the players have
func SortByScore(ps []Player) []Player {
	tmp := make([]Player, len(ps))
	copy(tmp, ps)
	sort.Sort(ByScore(tmp))
	return tmp
}

// SortByTournamentScore returns a list in order of the score the players
// have, computed from the total of the tournament
func SortByTournamentScore(ps []Player) (tmp []Player, err error) {
	var tp *Player
	tmp = make([]Player, len(ps))
	for i, p := range ps {
		// TODO(thiderman): This is not very elegant and should be replaced.
		tp, err = p.Match.Tournament.getTournamentPlayerObject(p.Person)
		if err != nil {
			return
		}
		tmp[i] = *tp
	}
	sort.Sort(ByScore(tmp))
	return
}

// ByKills is a sort.Interface that sorts players by their kills
type ByKills []Player

func (s ByKills) Len() int {
	return len(s)

}
func (s ByKills) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByKills) Less(i, j int) bool {
	// Technically not Less, but we want biggest first...
	iKills := s[i].Kills
	jKills := s[j].Kills
	if iKills == jKills {
		return s[i].Score() > s[j].Score()
	}
	return iKills > jKills
}

// SortByKills returns a list in order of the kills the players have
func SortByKills(ps []Player) []Player {
	tmp := make([]Player, len(ps))
	copy(tmp, ps)
	sort.Sort(ByKills(tmp))
	return tmp
}

// ByRunnerup is a sort.Interface that sorts players by their runnerup status
//
// This is almost exactly the same as score, but the number of matches a player
// has played factors in, and players that have played less matches are sorted
// favorably.
type ByRunnerup []Player

func (s ByRunnerup) Len() int {
	return len(s)

}
func (s ByRunnerup) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByRunnerup) Less(i, j int) bool {
	if s[i].Matches == s[j].Matches {
		// Same as by kills
		return s[i].Score() > s[j].Score()
	}
	// Lower is better - the ones that have not played should be at the top
	return s[i].Matches < s[j].Matches
}

// SortByRunnerup returns a list in order of the kills the players have
func SortByRunnerup(ps []Player) []Player {
	sort.Sort(ByRunnerup(ps))
	return ps
}

// RandomColor returns a random color from the ColorList
func RandomColor(s mapset.Set) string {
	colors := s.ToSlice()
	x := len(colors)
	return colors[rand.Intn(x)].(string)
}

// AvailableColors returns a ColorList with the colors not used in a match
func AvailableColors(m *Match) mapset.Set {
	colors := mapset.NewSetFromSlice(AllColors)
	ret := colors.Difference(m.presentColors)
	return ret
}

// Judge is a Participant that has access to the judge functions
type Judge struct {
}
<commit_msg>This is the worst thing that's ever happened to me.<commit_after>package main

import (
	"fmt"
	"github.com/deckarep/golang-set"
	"math/rand"
	"sort"
)

// AllColors is a list of the available player colors
var AllColors = []interface{}{
	"green",
	"blue",
	"pink",
	"orange",
	"white",
	"yellow",
	"cyan",
	"purple",
	"red",
}

// Colors is the definitive set of all the colors
var Colors = mapset.NewSetFromSlice(AllColors)

// ScoreData is a structured Key/Value pair list for scores
type ScoreData struct {
	Key    string
	Value  int
	Player *Player
}

// Player is a Participant that is actively participating in battles.
type Player struct {
	Person         *Person `json:"person"`
	Color          string  `json:"color"`
	PreferredColor string  `json:"preferred_color"`
	Shots          int     `json:"shots"`
	Sweeps         int     `json:"sweeps"`
	Kills          int     `json:"kills"`
	Self           int     `json:"self"`
	Explosions     int     `json:"explosions"`
	Matches        int     `json:"matches"`
	TotalScore     int     `json:"score"`
	Match          *Match  `json:"-"`
}

// NewPlayer returns a new instance of a player
func NewPlayer(ps *Person) *Player {
	p := &Player{Person: ps}
	if len(ps.ColorPreference) > 0 {
		p.PreferredColor = ps.ColorPreference[0]
	} else {
		p.PreferredColor = RandomColor(Colors)
	}

	return p
}

func (p *Player) String() string {
	return fmt.Sprintf(
		"<%s: %dsh %dsw %dk %ds %de>",
		p.Name(),
		p.Shots,
		p.Sweeps,
		p.Kills,
		p.Self,
		p.Explosions,
	)
}

// Name returns the nickname
func (p *Player) Name() string {
	return p.Person.Nick
}

// Score calculates the score to determine runnerup positions.
func (p *Player) Score() (out int) {
	// This algorithm is probably flawed, but at least it should be able to
	// determine who is the most entertaining.
	// When executed, a sweep is basically 14 points since scoring a sweep
	// also comes with a shot and three kills.

	out += p.Sweeps * 5
	out += p.Shots * 3
	out += p.Kills * 2
	out += p.Self
	out += p.Explosions

	return
}

// ScoreData returns this players set of ScoreData
func (p *Player) ScoreData() []ScoreData {
	sd := []ScoreData{
		{Key: "kills", Value: p.Kills, Player: p},
		{Key: "shots", Value: p.Shots, Player: p},
		{Key: "sweeps", Value: p.Sweeps, Player: p},
		{Key: "self", Value: p.Self, Player: p},
		{Key: "explosions", Value: p.Explosions, Player: p},
	}
	return sd
}

// URL returns the URL to this player
//
// Used for action URLs
func (p *Player) URL() string {
	out := fmt.Sprintf(
		"%s/%d",
		p.Match.URL(),
		p.Index(),
	)
	return out
}

// Classes returns the CSS color classes for the player
func (p *Player) Classes() string {
	if p.Match != nil && p.Match.IsEnded() {
		ps := ByScore(p.Match.Players)
		if ps[0].Name() == p.Name() {
			// Always gold for the winner
			return "gold"
		} else if ps[1].Name() == p.Name() {
			// Silver for the second, unless there is a short amount of tryouts
			if p.Match.Kind != "tryout" || len(p.Match.Tournament.Tryouts) <= 4 {
				return "silver"
			}
		} else if ps[2].Name() == p.Name() && p.Match.Kind == "final" {
			return "bronze"
		}

		return "out"
	}
	return p.PreferredColor
}

// Index returns the index in the current match
func (p *Player) Index() int {
	if p.Match != nil {
		for i, o := range p.Match.Players {
			if p.Name() == o.Name() {
				return i
			}
		}
	}
	return -1
}

// Action performs an action for a player
func (p *Player) Action(action, dir string) error {
	// TODO: This could use with a refactoring...
	if dir == "up" {
		switch action {
		case "kills":
			p.AddKill()
		case "shots":
			p.AddShot()
		case "sweeps":
			p.AddSweep()
		case "self":
			p.AddSelf()
		case "explosions":
			p.AddExplosion()
		}
	} else {
		switch action {
		case "kills":
			p.RemoveKill()
		case "shots":
			p.RemoveShot()
		case "sweeps":
			p.RemoveSweep()
		case "self":
			p.RemoveSelf()
		case "explosions":
			p.RemoveExplosion()
		}
	}

	// Save the change to the database
	p.Match.Tournament.Persist()

	return nil
}

// AddShot increases the shot count
func (p *Player) AddShot() {
	p.Shots++
}

// RemoveShot decreases the shot count
// Fails silently if shots are zero.
func (p *Player) RemoveShot() {
	if p.Shots == 0 {
		return
	}
	p.Shots--
}

// AddSweep increases the sweep count, gives three kills and a shot.
func (p *Player) AddSweep() {
	p.Sweeps++
	p.AddShot()
	p.AddKill()
	p.AddKill()
	p.AddKill()
}

// RemoveSweep decreases the sweep count, three kills and a shot
// Fails silently if sweeps are zero.
func (p *Player) RemoveSweep() {
	if p.Sweeps == 0 {
		return
	}
	p.Sweeps--
	p.RemoveShot()
	p.RemoveKill()
	p.RemoveKill()
	p.RemoveKill()
}

// AddKill increases the kill count
func (p *Player) AddKill(kills ...int) {
	// This is basically only to help out with testing.
	// Adding an optional argument with the amount of kills lets us just use
	// one call to AddKill() rather than 10.
	if len(kills) > 0 {
		p.Kills += kills[0]
	} else {
		p.Kills++
	}
}

// RemoveKill decreases the kill count
// Fails silently if kills are zero.
func (p *Player) RemoveKill() {
	if p.Kills == 0 {
		return
	}
	p.Kills--
}

// AddSelf increases the self count, decreases the kill, and gives a shot
func (p *Player) AddSelf() {
	p.Self++
	p.RemoveKill()
	p.AddShot()
}

// RemoveSelf decreases the self count and a shot
// Fails silently if selfs are zero.
func (p *Player) RemoveSelf() {
	if p.Self == 0 {
		return
	}
	p.Self--
	p.AddKill()
	p.RemoveShot()
}

// AddExplosion increases the explosion count, the kill count and gives a shot
func (p *Player) AddExplosion() {
	p.Explosions++
	p.AddShot()
	p.AddKill()
}

// RemoveExplosion decreases the explosion count, a shot and a kill
// Fails silently if Explosions are zero.
func (p *Player) RemoveExplosion() {
	if p.Explosions == 0 {
		return
	}
	p.Explosions--
	p.RemoveShot()
	p.RemoveKill()
}

// Reset resets the stats on a Player to 0
//
// It is to be run in Match.Start()
func (p *Player) Reset() {
	p.Shots = 0
	p.Sweeps = 0
	p.Kills = 0
	p.Self = 0
	p.Explosions = 0
	p.Matches = 0
}

// Update updates a player with the scores of another
//
// This is primarily used by the tournament score calculator
func (p *Player) Update(other Player) {
	p.Shots += other.Shots
	p.Sweeps += other.Sweeps
	p.Kills += other.Kills
	p.Self += other.Self
	p.Explosions += other.Explosions
	p.TotalScore = p.Score()

	// Every call to this method is per match. Count every call
	// as if a match.
	p.Matches++
	// log.Printf("Updated player: %d, %d", p.TotalScore, p.Matches)
}

// HTML renders the HTML of a player
func (p *Player) HTML() (out string) {
	return
}

// ByScore is a sort.Interface that sorts players by their score
type ByScore []Player

func (s ByScore) Len() int {
	return len(s)

}
func (s ByScore) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByScore) Less(i, j int) bool {
	// Technically not Less, but we want biggest first...
	return s[i].Score() > s[j].Score()
}

// SortByScore returns a list in order of the score the players have
func SortByScore(ps []Player) []Player {
	tmp := make([]Player, len(ps))
	copy(tmp, ps)
	sort.Sort(ByScore(tmp))
	return tmp
}

// SortByTournamentScore returns a list in order of the score the players
// have, computed from the total of the tournament
func SortByTournamentScore(ps []Player) (tmp []Player, err error) {
	var tp *Player
	tmp = make([]Player, len(ps))
	for i, p := range ps {
		// TODO(thiderman): This is not very elegant and should be replaced.
		tp, err = p.Match.Tournament.getTournamentPlayerObject(p.Person)
		if err != nil {
			return
		}
		tmp[i] = *tp
	}
	sort.Sort(ByScore(tmp))
	return
}

// ByKills is a sort.Interface that sorts players by their kills
type ByKills []Player

func (s ByKills) Len() int {
	return len(s)

}
func (s ByKills) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByKills) Less(i, j int) bool {
	// Technically not Less, but we want biggest first...
	iKills := s[i].Kills
	jKills := s[j].Kills
	if iKills == jKills {
		return s[i].Score() > s[j].Score()
	}
	return iKills > jKills
}

// SortByKills returns a list in order of the kills the players have
func SortByKills(ps []Player) []Player {
	tmp := make([]Player, len(ps))
	copy(tmp, ps)
	sort.Sort(ByKills(tmp))
	return tmp
}

// ByRunnerup is a sort.Interface that sorts players by their runnerup status
//
// This is almost exactly the same as score, but the number of matches a player
// has played factors in, and players that have played less matches are sorted
// favorably.
type ByRunnerup []Player

func (s ByRunnerup) Len() int {
	return len(s)

}
func (s ByRunnerup) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByRunnerup) Less(i, j int) bool {
	if s[i].Matches == s[j].Matches {
		// Same as by kills
		return s[i].Score() > s[j].Score()
	}
	// Lower is better - the ones that have not played should be at the top
	return s[i].Matches < s[j].Matches
}

// SortByRunnerup returns a list in order of the kills the players have
func SortByRunnerup(ps []Player) []Player {
	sort.Sort(ByRunnerup(ps))
	return ps
}

// RandomColor returns a random color from the ColorList
func RandomColor(s mapset.Set) string {
	colors := s.ToSlice()
	x := len(colors)
	return colors[rand.Intn(x)].(string)
}

// AvailableColors returns a ColorList with the colors not used in a match
func AvailableColors(m *Match) mapset.Set {
	colors := mapset.NewSetFromSlice(AllColors)
	ret := colors.Difference(m.presentColors)
	return ret
}

// Judge is a Participant that has access to the judge functions
type Judge struct {
}
<|endoftext|>


<commit_before>// Package hashmap implements a simple non-blocking (lock-free) hash map.
//
// The semantics of this hashmap are quite different from the go built-in.
// Aside from thread-safety, any values (including structs and slices) are
// allowed as keys, and a value of nil is indestinguishable from an element not
// being in the map.
package hashmap

import (
	a "sync/atomic"
	r "reflect"
	u "unsafe"
)

var (
	defCap = uint32(32)
)

// A hashmap entry.
type entry struct {
	f uint32
	k interface{}
	v *interface{}
}

type Hashmap struct {
	data []entry
	size uint32
	capc uint32
}

// Creates a hashmap with the default initial capacity (32). The hashmap will
// be grown to twice its size when the number of entries reaches 50% of the
// capacity.
func New() *Hashmap {
	return NewCap(defCap)
}

// Creates a hashmap with the specified initial capacity.
func NewCap(c uint32) *Hashmap {
	return &Hashmap{
		data: make([]entry, c),
		size: 0,
		capc: uint32(c),
	}
}

// Returns the capacity of this hashmap.
func (hm *Hashmap) Capacity() uint32 {
	return a.LoadUint32(&hm.capc)
}

// Returns the size of this hashmap. This is /not/ the number of elements
// stored - it is the number of keys allocated.
func (hm *Hashmap) Size() uint32 {
	return a.LoadUint32(&hm.size)
}

func (hm *Hashmap) Get(k interface{}) interface{} {
Retry:
	// If the map changes capacity during the operation, we will detect
	// that and retry. Note that the only legal transformation of this
	// value is for it to increase (double), so we can easily check to see
	// if it has changed.
	c := hm.Capacity()

	// Guaranteed to be correct when c is correct.
	h := hash(k, c)

	// Since keys cannot be removed, we know that our target entry lies
	// somewhere 'after' the entry indexed by h, and that no nil keys lie
	// in between.
	for i := uint32(0); i < h+c; i++ {
		// Atomically fetch the data indexed by (i%c). Since there are
		// 16 bytes to fetch, this can't be done in a single atomic
		// operation; however, since a set key can never change, we
		// don't need perfect atomicity when fetching it.

		ef := a.LoadUint32(&hm.data[i%c].f)
		if ef == 0 {
			// The key is not set; there's no such element.
			return nil
		}

		// The key is set and can never change - fetch it
		// non-atomically.
		ek := hm.data[i%c].k

		// Load value atomically
		evp := u.Pointer(hm.data[i%c].v)
		ev := (*interface{})(a.LoadPointer(&evp))

		// Note that at this point, the collect data is incorrect if
		// and only if the capacity has changed (and the map has
		// therefore been expanded). We now check to see if that has
		// happened, and if so, abort.
		if c != hm.Capacity() {
			// This is the part that breaks our per-goroutine
			// progress guarantee.
			goto Retry
		}

		// The data (ek, ev) may now be considered actionable. Since it
		// is stored in local memory, we don't have to worry about
		// making further operations atomic.

		if r.DeepEqual(ek, k) {
			return *ev
		}
	}

	// Really, this should never happen; it just means we've cycled through
	// the whole map, and none of the keys were nil.
	return nil
}

// The key will be (shallowly) copied - the value will not.
func (hm *Hashmap) Set(k interface{}, v interface{}) {
	c := hm.Capacity()
	h := hash(k, c)
	for i := uint32(0); i < h+c; i++ {
		e := &hm.data[i%c]
		if e.k == nil {
			e.f = 1
			e.v = &v
			e.k = k
			hm.size++
			// TODO Grow if necessary
			return
		}
		if r.DeepEqual(e.k, k) {
			e.v = &v
			return
		}
	}
	panic("Hashmap full")
}

// Deletes the given key from the map, and returns true if it existed. Although
// this method is semantically equivalent to m.Set(k, nil), this method will
// not allocate another key if the key is not already in use, and should
// therefore be used instead.
func (hm *Hashmap) Del(k interface{}) bool {
	c := hm.Capacity()
	h := hash(k, c)
	for i := uint32(0); i < h+c; i++ {
		e := &hm.data[i%c]
		if r.DeepEqual(e.k, k) {
			//e.k = nil
			e.f = 0
			e.v = nil
			return true
		}
	}
	return false
}

func (hm *Hashmap) Grow(c uint32) {
	// TODO
}

func hash(key interface{}, c uint32) uint32 {
	switch k := key.(type) {
	case int:
		return uint32(k) % c
	}
	return uint32(0)
}
<commit_msg>Better atomicity, and fixing tests<commit_after>// Package hashmap implements a simple non-blocking (lock-free) hash map.
//
// The semantics of this hashmap are quite different from the go built-in.
// Aside from thread-safety, any values (including structs and slices) are
// allowed as keys, and a value of nil is indestinguishable from an element not
// being in the map.
package hashmap

import (
	a "sync/atomic"
	r "reflect"
	u "unsafe"
)

var (
	defCap = uint32(32)
)

// A hashmap entry.
type entry struct {
	f uint32
	k interface{}
	v *interface{}
}

type Hashmap struct {
	data []entry
	size uint32
	capc uint32
}

// Creates a hashmap with the default initial capacity (32). The hashmap will
// be grown to twice its size when the number of entries reaches 50% of the
// capacity.
func New() *Hashmap {
	return NewCap(defCap)
}

// Creates a hashmap with the specified initial capacity.
func NewCap(c uint32) *Hashmap {
	return &Hashmap{
		data: make([]entry, c),
		size: 0,
		capc: uint32(c),
	}
}

// Returns the capacity of this hashmap.
func (hm *Hashmap) Capacity() uint32 {
	return a.LoadUint32(&hm.capc)
}

// Returns the size of this hashmap. This is /not/ the number of elements
// stored - it is the number of keys allocated.
func (hm *Hashmap) Size() uint32 {
	return a.LoadUint32(&hm.size)
}

func (hm *Hashmap) Get(k interface{}) interface{} {
Retry:
	// If the map changes capacity during the operation, we will detect
	// that and retry. Note that the only legal transformation of this
	// value is for it to increase (double), so we can easily check to see
	// if it has changed.
	c := hm.Capacity()

	// Guaranteed to be correct when c is correct.
	h := hash(k, c)

	// Since keys cannot be removed, we know that our target entry lies
	// somewhere 'after' the entry indexed by h, and that no nil keys lie
	// in between.
	for i := uint32(0); i < h+c; i++ {
		// Atomically fetch the data indexed by (i%c). Since there are
		// 16 bytes to fetch, this can't be done in a single atomic
		// operation; however, since a set key can never change, we
		// don't need perfect atomicity when fetching it.

		ef := a.LoadUint32(&hm.data[i%c].f)
		if ef == 0 {
			// The key is not set; there's no such element.
			return nil
		}

		// The key is set and can never change - fetch it
		// non-atomically.
		ek := hm.data[i%c].k

		// Load value atomically
		evp := u.Pointer(hm.data[i%c].v)
		ev := (*interface{})(a.LoadPointer(&evp))

		// Note that at this point, the collect data is incorrect if
		// and only if the capacity has changed (and the map has
		// therefore been expanded). We now check to see if that has
		// happened, and if so, abort.
		if c != hm.Capacity() {
			// This is the part that breaks our per-goroutine
			// progress guarantee.
			goto Retry
		}

		// The data (ek, ev) may now be considered actionable. Since it
		// is stored in local memory, we don't have to worry about
		// making further operations atomic.

		if r.DeepEqual(ek, k) {
			if ev == nil { return nil }
			return *ev
		}
	}

	// Really, this should never happen; it just means we've cycled through
	// the whole map, and none of the keys were nil.
	return nil
}

// The key will be (shallowly) copied - the value will not.
func (hm *Hashmap) Set(k interface{}, v interface{}) {
Retry:
	c := hm.Capacity()
	h := hash(k, c)
	for i := uint32(0); i < h+c; i++ {
		e := &hm.data[i%c]
		ef := a.LoadUint32(&e.f)

		if c != hm.Capacity() {
			goto Retry
		}
		if ef == 0 {

		} else if r.DeepEqual(e.k, k) {
			// Atomically write the value
			return
		}
		if e.k == nil {
			e.f = 1
			e.v = &v
			e.k = k
			hm.size++
			// TODO Grow if necessary
			return
		}
		if r.DeepEqual(e.k, k) {
			e.v = &v
			return
		}
	}
	panic("Hashmap full")
}

// Deletes the given key from the map, and returns true if it existed. Although
// this method is semantically equivalent to m.Set(k, nil), this method will
// not allocate another key if the key is not already in use, and should
// therefore be used instead.
func (hm *Hashmap) Del(k interface{}) bool {
Retry:
	c := hm.Capacity()
	h := hash(k, c)
	for i := uint32(0); i < h+c; i++ {
		e := &hm.data[i%c]
		ef := a.LoadUint32(&e.f)

		if c != hm.Capacity() {
			goto Retry
		}

		if ef == 0 {
			return false
		}

		if r.DeepEqual(e.k, k) {
			e.v = nil
			return true
		}
	}
	return false
}

func (hm *Hashmap) Grow(c uint32) {
	// TODO
}

func hash(key interface{}, c uint32) uint32 {
	switch k := key.(type) {
	case int:
		return uint32(k) % c
	}
	return uint32(0)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"strings"
	"time"

	"github.com/drone/drone-go/drone"
)

// Plugin defines the Downstream plugin parameters.
type Plugin struct {
	Repos   []string
	Server  string
	Token   string
	Fork    bool
	Wait    bool
	Timeout time.Duration
}

// Exec runs the plugin
func (p *Plugin) Exec() error {
	if len(p.Token) == 0 {
		return fmt.Errorf("Error: you must provide your Drone access token.")
	}

	if len(p.Server) == 0 {
		return fmt.Errorf("Error: you must provide your Drone server.")
	}

	client := drone.NewClientToken(p.Server, p.Token)

	for _, entry := range p.Repos {

		// parses the repository name in owner/name@branch format
		owner, name, branch := parseRepoBranch(entry)
		if len(owner) == 0 || len(name) == 0 {
			return fmt.Errorf("Error: unable to parse repository name %s.\n", entry)
		}
		waiting := false

		timeout := time.After(p.Timeout)
		tick := time.Tick(1 * time.Second)

		// Keep trying until we're timed out, successful or got an error
		// Tagged with "I" due to break nested in select
	I:
		for {
			select {
			// Got a timeout! fail with a timeout error
			case <-timeout:
				return fmt.Errorf("Error: timed out waiting on a build for %s.\n", entry)
			// Got a tick, we should check on the build status
			case <-tick:
				// get the latest build for the specified repository
				build, err := client.BuildLast(owner, name, branch)
				if err != nil {
					if waiting {
						continue
					}
					return fmt.Errorf("Error: unable to get latest build for %s.\n", entry)
				}
				if (build.Status != drone.StatusRunning && build.Status != drone.StatusPending) || p.Wait == false {
					if p.Fork {
						// start a new  build
						_, err = client.BuildFork(owner, name, build.Number)
						if err != nil {
							if waiting {
								continue
							}
							return fmt.Errorf("Error: unable to trigger a new build for %s.\n", entry)
						}
						fmt.Printf("Starting new build %d for %s.\n", build.Number, entry)
						break I
					} else {
						// rebuild the latest build
						_, err = client.BuildStart(owner, name, build.Number)
						if err != nil {
							if waiting {
								continue
							}
							return fmt.Errorf("Error: unable to trigger build for %s.\n", entry)
						}
						fmt.Printf("Restarting build %d for %s\n", build.Number, entry)
						break I
					}
				} else if p.Wait == true {
					fmt.Printf("BuildLast for repository: %s, returned build number: %v with a status of %s. Will retry for %v.\n", entry, build.Number, build.Status, p.Timeout)
					waiting = true
				}
			}
		}
	}
	return nil
}

func parseRepoBranch(repo string) (string, string, string) {
	var (
		owner  string
		name   string
		branch string
	)

	parts := strings.Split(repo, "@")
	if len(parts) == 2 {
		branch = parts[1]
		repo = parts[0]
	}

	parts = strings.Split(repo, "/")
	if len(parts) == 2 {
		owner = parts[0]
		name = parts[1]
	}
	return owner, name, branch
}
<commit_msg>Add deprecation warning for fork option; not supported in 0.8.1 of Drone server<commit_after>package main

import (
	"fmt"
	"os"
	"strings"
	"time"

	"github.com/drone/drone-go/drone"
)

// Plugin defines the Downstream plugin parameters.
type Plugin struct {
	Repos   []string
	Server  string
	Token   string
	Fork    bool
	Wait    bool
	Timeout time.Duration
}

// Exec runs the plugin
func (p *Plugin) Exec() error {
	if len(p.Token) == 0 {
		return fmt.Errorf("Error: you must provide your Drone access token.")
	}

	if len(p.Server) == 0 {
		return fmt.Errorf("Error: you must provide your Drone server.")
	}

	if !p.Fork {
		fmt.Fprintln(
			os.Stderr,
			"Warning: \"fork: false\" will be deprecated in future\n"+
				"         set \"fork: true\" to disable this warning",
		)
	}

	client := drone.NewClientToken(p.Server, p.Token)

	for _, entry := range p.Repos {

		// parses the repository name in owner/name@branch format
		owner, name, branch := parseRepoBranch(entry)
		if len(owner) == 0 || len(name) == 0 {
			return fmt.Errorf("Error: unable to parse repository name %s.\n", entry)
		}
		waiting := false

		timeout := time.After(p.Timeout)
		tick := time.Tick(1 * time.Second)

		// Keep trying until we're timed out, successful or got an error
		// Tagged with "I" due to break nested in select
	I:
		for {
			select {
			// Got a timeout! fail with a timeout error
			case <-timeout:
				return fmt.Errorf("Error: timed out waiting on a build for %s.\n", entry)
			// Got a tick, we should check on the build status
			case <-tick:
				// get the latest build for the specified repository
				build, err := client.BuildLast(owner, name, branch)
				if err != nil {
					if waiting {
						continue
					}
					return fmt.Errorf("Error: unable to get latest build for %s.\n", entry)
				}
				if (build.Status != drone.StatusRunning && build.Status != drone.StatusPending) || p.Wait == false {
					if p.Fork {
						// start a new  build
						_, err = client.BuildFork(owner, name, build.Number)
						if err != nil {
							if waiting {
								continue
							}
							return fmt.Errorf("Error: unable to trigger a new build for %s.\n", entry)
						}
						fmt.Printf("Starting new build %d for %s.\n", build.Number, entry)
						break I
					} else {
						// rebuild the latest build
						_, err = client.BuildStart(owner, name, build.Number)
						if err != nil {
							if waiting {
								continue
							}
							return fmt.Errorf("Error: unable to trigger build for %s.\n", entry)
						}
						fmt.Printf("Restarting build %d for %s\n", build.Number, entry)
						break I
					}
				} else if p.Wait == true {
					fmt.Printf("BuildLast for repository: %s, returned build number: %v with a status of %s. Will retry for %v.\n", entry, build.Number, build.Status, p.Timeout)
					waiting = true
				}
			}
		}
	}
	return nil
}

func parseRepoBranch(repo string) (string, string, string) {
	var (
		owner  string
		name   string
		branch string
	)

	parts := strings.Split(repo, "@")
	if len(parts) == 2 {
		branch = parts[1]
		repo = parts[0]
	}

	parts = strings.Split(repo, "/")
	if len(parts) == 2 {
		owner = parts[0]
		name = parts[1]
	}
	return owner, name, branch
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"crypto/tls"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"strings"

	"github.com/drone/drone-template-lib/template"
)

type (
	Repo struct {
		Owner string `json:"owner"`
		Name  string `json:"name"`
	}

	Build struct {
		Tag      string `json:"tag"`
		Event    string `json:"event"`
		Number   int    `json:"number"`
		Commit   string `json:"commit"`
		Ref      string `json:"ref"`
		Branch   string `json:"branch"`
		Author   string `json:"author"`
		Message  string `json:"message"`
		Status   string `json:"status"`
		Link     string `json:"link"`
		DeployTo string `json:"deployTo"`
		Started  int64  `json:"started"`
		Created  int64  `json:"created"`
	}

	Config struct {
		Method      string
		Username    string
		Password    string
		ContentType string
		Template    string
		Headers     []string
		URLs        []string
		ValidCodes  []int
		Debug       bool
		SkipVerify  bool
		Secret      string
	}

	Job struct {
		Started int64
	}

	Plugin struct {
		Repo   Repo
		Build  Build
		Config Config
		Job    Job
	}
)

func (p Plugin) Exec() error {
	var (
		buf bytes.Buffer
		b   []byte
	)

	if len(p.Config.URLs) == 0 {
		return fmt.Errorf("You must provide at least one url")
	}

	if p.Config.Template == "" {
		data := struct {
			Repo  Repo  `json:"repo"`
			Build Build `json:"build"`
		}{p.Repo, p.Build}

		if err := json.NewEncoder(&buf).Encode(&data); err != nil {
			fmt.Printf("Error: Failed to encode JSON payload. %s\n", err)
			return err
		}

		b = buf.Bytes()
	} else {
		txt, err := template.RenderTrim(p.Config.Template, p)

		if err != nil {
			return err
		}

		text := txt
		b = []byte(text)
	}

	// build and execute a request for each url.
	// all auth, headers, method, template (payload),
	// and content_type values will be applied to
	// every webhook request.

	for i, rawurl := range p.Config.URLs {
		uri, err := url.Parse(rawurl)

		if err != nil {
			fmt.Printf("Error: Failed to parse the hook URL. %s\n", err)
			os.Exit(1)
		}

		r := bytes.NewReader(b)
		req, err := http.NewRequest(p.Config.Method, uri.String(), r)

		if err != nil {
			fmt.Printf("Error: Failed to create the HTTP request. %s\n", err)
			return err
		}

		req.Header.Set("Content-Type", p.Config.ContentType)

		if p.Config.Secret != "" {
			// generate signature with secret and body
			h := hmac.New(sha256.New, []byte(p.Config.Secret))
			h.Write(b)
			sha := hex.EncodeToString(h.Sum(nil))

			// append signature to headers
			req.Header.Set("X-Drone-Signature", sha)
		}

		for _, value := range p.Config.Headers {
			header := strings.Split(value, "=")
			req.Header.Set(header[0], header[1])
		}

		if p.Config.Username != "" && p.Config.Password != "" {
			req.SetBasicAuth(p.Config.Username, p.Config.Password)
		}

		client := http.DefaultClient

		if p.Config.SkipVerify {
			client = &http.Client{
				Transport: &http.Transport{
					TLSClientConfig: &tls.Config{
						InsecureSkipVerify: true,
					},
				},
			}
		}

		resp, err := client.Do(req)

		if err != nil {
			fmt.Printf("Error: Failed to execute the HTTP request. %s\n", err)
			return err
		}

		defer resp.Body.Close()

		if p.Config.Debug || resp.StatusCode >= http.StatusBadRequest {
			body, err := ioutil.ReadAll(resp.Body)

			if err != nil {
				fmt.Printf("Error: Failed to read the HTTP response body. %s\n", err)
			}

			if p.Config.Debug {
				fmt.Printf(
					debugFormat,
					i+1,
					req.URL,
					req.Method,
					req.Header,
					string(b),
					resp.Status,
					string(body),
				)
			} else {
				fmt.Printf(
					respFormat,
					i+1,
					req.URL,
					resp.Status,
					string(body),
				)
			}
		}

		if len(p.Config.ValidCodes) > 0 && !intInSlice(p.Config.ValidCodes, resp.StatusCode) {
			return fmt.Errorf("Error: Response code %d not found among valid response codes", resp.StatusCode)
		}

	}

	return nil
}

// Function checks if int is in slice of ints
func intInSlice(s []int, e int) bool {
	for _, a := range s {
		if a == e {
			return true
		}
	}
	return false
}
<commit_msg>Include signature algorithm in header field<commit_after>package main

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"crypto/tls"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"strings"

	"github.com/drone/drone-template-lib/template"
)

type (
	Repo struct {
		Owner string `json:"owner"`
		Name  string `json:"name"`
	}

	Build struct {
		Tag      string `json:"tag"`
		Event    string `json:"event"`
		Number   int    `json:"number"`
		Commit   string `json:"commit"`
		Ref      string `json:"ref"`
		Branch   string `json:"branch"`
		Author   string `json:"author"`
		Message  string `json:"message"`
		Status   string `json:"status"`
		Link     string `json:"link"`
		DeployTo string `json:"deployTo"`
		Started  int64  `json:"started"`
		Created  int64  `json:"created"`
	}

	Config struct {
		Method      string
		Username    string
		Password    string
		ContentType string
		Template    string
		Headers     []string
		URLs        []string
		ValidCodes  []int
		Debug       bool
		SkipVerify  bool
		Secret      string
	}

	Job struct {
		Started int64
	}

	Plugin struct {
		Repo   Repo
		Build  Build
		Config Config
		Job    Job
	}
)

func (p Plugin) Exec() error {
	var (
		buf bytes.Buffer
		b   []byte
	)

	if len(p.Config.URLs) == 0 {
		return fmt.Errorf("You must provide at least one url")
	}

	if p.Config.Template == "" {
		data := struct {
			Repo  Repo  `json:"repo"`
			Build Build `json:"build"`
		}{p.Repo, p.Build}

		if err := json.NewEncoder(&buf).Encode(&data); err != nil {
			fmt.Printf("Error: Failed to encode JSON payload. %s\n", err)
			return err
		}

		b = buf.Bytes()
	} else {
		txt, err := template.RenderTrim(p.Config.Template, p)

		if err != nil {
			return err
		}

		text := txt
		b = []byte(text)
	}

	// build and execute a request for each url.
	// all auth, headers, method, template (payload),
	// and content_type values will be applied to
	// every webhook request.

	for i, rawurl := range p.Config.URLs {
		uri, err := url.Parse(rawurl)

		if err != nil {
			fmt.Printf("Error: Failed to parse the hook URL. %s\n", err)
			os.Exit(1)
		}

		r := bytes.NewReader(b)
		req, err := http.NewRequest(p.Config.Method, uri.String(), r)

		if err != nil {
			fmt.Printf("Error: Failed to create the HTTP request. %s\n", err)
			return err
		}

		req.Header.Set("Content-Type", p.Config.ContentType)

		if p.Config.Secret != "" {
			// generate signature with secret and body
			h := hmac.New(sha256.New, []byte(p.Config.Secret))
			h.Write(b)
			sha := hex.EncodeToString(h.Sum(nil))

			// append signature to headers
			req.Header.Set("X-Drone-Signature", fmt.Sprintf("sha256=%s", sha))
		}

		for _, value := range p.Config.Headers {
			header := strings.Split(value, "=")
			req.Header.Set(header[0], header[1])
		}

		if p.Config.Username != "" && p.Config.Password != "" {
			req.SetBasicAuth(p.Config.Username, p.Config.Password)
		}

		client := http.DefaultClient

		if p.Config.SkipVerify {
			client = &http.Client{
				Transport: &http.Transport{
					TLSClientConfig: &tls.Config{
						InsecureSkipVerify: true,
					},
				},
			}
		}

		resp, err := client.Do(req)

		if err != nil {
			fmt.Printf("Error: Failed to execute the HTTP request. %s\n", err)
			return err
		}

		defer resp.Body.Close()

		if p.Config.Debug || resp.StatusCode >= http.StatusBadRequest {
			body, err := ioutil.ReadAll(resp.Body)

			if err != nil {
				fmt.Printf("Error: Failed to read the HTTP response body. %s\n", err)
			}

			if p.Config.Debug {
				fmt.Printf(
					debugFormat,
					i+1,
					req.URL,
					req.Method,
					req.Header,
					string(b),
					resp.Status,
					string(body),
				)
			} else {
				fmt.Printf(
					respFormat,
					i+1,
					req.URL,
					resp.Status,
					string(body),
				)
			}
		}

		if len(p.Config.ValidCodes) > 0 && !intInSlice(p.Config.ValidCodes, resp.StatusCode) {
			return fmt.Errorf("Error: Response code %d not found among valid response codes", resp.StatusCode)
		}

	}

	return nil
}

// Function checks if int is in slice of ints
func intInSlice(s []int, e int) bool {
	for _, a := range s {
		if a == e {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package RSE

import "syscall"

const MEM_COMMIT  = 0x1000
const MEM_RESERVE = 0x2000
const PAGE_EXECUTE_READWRITE = 0x40
const PROCESS_CREATE_THREAD = 0x0002
const PROCESS_QUERY_INFORMATION = 0x0400
const PROCESS_VM_OPERATION = 0x0008
const PROCESS_VM_WRITE = 0x0020
const PROCESS_VM_READ = 0x0010

func DeObfuscate(Data string) (string){
	var ClearText string
	for i := 0; i < len(Data); i++ {
		ClearText += string(int(Data[i])-1)
	}
	return ClearText
}

var	K32 = syscall.MustLoadDLL(DeObfuscate("lfsofm43/emm"))//kernel32.dll
var USER32 = syscall.MustLoadDLL(DeObfuscate("vtfs43/emm"))//user32.dll
var VirtualAllocEx = K32.MustFindProc(DeObfuscate("WjsuvbmBmmpdF"))//VirtualAllocEx
var CreateRemoteThread = K32.MustFindProc(DeObfuscate("DsfbufSfnpufUisfbe"))//CreateRemoteThread
var WriteProcessMemory = K32.MustFindProc(DeObfuscate("XsjufQspdfttNfnpsz"))//WriteProcessMemory
var OpenProcess = K32.MustFindProc(DeObfuscate("PqfoQspdftt"))//OpenProcess
var IsDebuggerPresent = K32.MustFindProc(DeObfuscate("JtEfcvhhfsQsftfou"))
<commit_msg>Removed obfuscation from RSE<commit_after>package RSE

import "syscall"

const MEM_COMMIT  = 0x1000
const MEM_RESERVE = 0x2000
const PAGE_EXECUTE_READWRITE = 0x40
const PROCESS_CREATE_THREAD = 0x0002
const PROCESS_QUERY_INFORMATION = 0x0400
const PROCESS_VM_OPERATION = 0x0008
const PROCESS_VM_WRITE = 0x0020
const PROCESS_VM_READ = 0x0010

var	K32 = syscall.MustLoadDLL("kernel32.dll")//kernel32.dll
var USER32 = syscall.MustLoadDLL("user32.dll")//user32.dll
var GetAsyncKeyState = USER32.MustFindProc("GetAsyncKeyState")
var VirtualAlloc = K32.MustFindProc("VirtualAlloc")
var CreateThread = K32.MustFindProc("CreateThread")
var VirtualAllocEx = K32.MustFindProc("VirtualAllocEx")
var CreateRemoteThread = K32.MustFindProc("CreateRemoteThread")
var WriteProcessMemory = K32.MustFindProc("WriteProcessMemory")
var OpenProcess = K32.MustFindProc("OpenProcess")
var IsDebuggerPresent = K32.MustFindProc("IsDebuggerPresent")
<|endoftext|>