<commit_before>package strike

/*
FileInfo contains information on the torrent's files
*/
type FileInfo struct {
	FileNames			[]string	`json:"file_names"`
	FileLengths			[]uint64	`json:"file_lengths"`
}

/*
Torrent contains information about the torrent
*/
type Torrent struct {
	Hash				string		`json:"torrent_hash"`
	ImdbID				string		`json:"imdbid"`
	Title				string		`json:"torrent_title"`
	Category			string		`json:"torrent_category"`
	Subcategory			string		`json:"sub_category"`
	Seeds				uint64		`json:"seeds"`
	Leeches				uint64		`json:"leeches"`
	FileCount			uint64		`json:"file_count"`
	Size				float64		`json:"size"`
	DownloadCount		uint64		`json:"download_count"`
	UploadDate			string		`json:"upload_date"`
	UploaderUsername	string		`json:"uploader_username"`
	FileInfo			FileInfo	`json:"file_info"`
	Page				string		`json:"page"`
	RssFeed				string		`json:"rss_feed"`
	MagnetURI			string		`json:"magnet_uri"`
}

/*
GetDownload returns a TorrentDownload
*/
func (t Torrent) GetDownload(string) (TorrentDownload, error) {
	return Download(t.Hash)
}

/*
GetInfo returns an TorrentResults object containing torrent info
*/
func (t Torrent) GetInfo(string) (TorrentResults, error) {
	return Info(t.Hash)
}

/*
GetIMDb returns an IMDb movie information object.
*/
func (t Torrent) GetIMDb(string) (IMDb, error) {
	return Imdb(t.ImdbID)
}

/*
GetDescription returns a TorrentDescription containing a base64 encoded HTML description,
or a TorrentDescription containing a plain text description if true is passed as the
first parameter.
*/
func (t Torrent) GetDescription(params ...bool) (result TorrentDescription, err error) {
	decode := false
	if (len(params) > 0) {
		decode = params[0]
	}
	return Description(t.ImdbID, decode)
}

/*
TorrentResults contains information about an API response and holds an array of Torrent objects
*/
type TorrentResults struct {
	Results				uint64		`json:"results"`
	StatusCode			uint16		`json:"statuscode"`
	ResponseTime		float32		`json:"responsetime"`
	Torrents			[]Torrent	`json:"torrents"`
}

/*
TorrentCount contains a Count from a count API response
*/
type TorrentCount struct {
	StatusCode			uint16		`json:"statuscode"`
	Count				uint64		`json:"message"`
}

/*
TorrentDescription contains a Description from a description API response
*/
type TorrentDescription struct {
	StatusCode			uint16		`json:"statuscode"`
	Description			string		`json:"message"`
}

/*
TorrentDownload contains a Uri from a download API response
*/
type TorrentDownload struct {
	StatusCode			uint16		`json:"statuscode"`
	URI					string		`json:"message"`
}

/*
IMDb contains movie information from an imdb API response
*/
type IMDb struct {
	ID					uint64		`json:"id"`
	ImdbID				string		`json:"imdbID"`
	Title				string		`json:"Title"`
	Year				uint16		`json:"Year"`
	Rating				float32		`json:"Rating"`
	Runtime				string		`json:"Runtime"`
	Genre				string		`json:"Genre"`
	Released			string		`json:"Released"`
	Director			string		`json:"Director"`
	Writer				string		`json:"Writer"`
	Cast				string		`json:"Cast"`
	Metacritic			string		`json:"Metacritic"`
	ImdbRating			string		`json:"imdbRating"`
	ImdbVotes			string		`json:"imdbVotes"`
	Poster				string		`json:"Poster"`
	Plot				string		`json:"Plot"`
	FullPlot			string		`json:"FullPlot"`
	Language			string		`json:"Language"`
	Country				string		`json:"Country"`
	Awards				string		`json:"Awards"`
	LastUpdated			string		`json:"lastUpdated"`
	Type				string		`json:"Type"`
}<commit_msg>Correcting Torrent methods<commit_after>package strike

/*
FileInfo contains information on the torrent's files
*/
type FileInfo struct {
	FileNames			[]string	`json:"file_names"`
	FileLengths			[]uint64	`json:"file_lengths"`
}

/*
Torrent contains information about the torrent
*/
type Torrent struct {
	Hash				string		`json:"torrent_hash"`
	ImdbID				string		`json:"imdbid"`
	Title				string		`json:"torrent_title"`
	Category			string		`json:"torrent_category"`
	Subcategory			string		`json:"sub_category"`
	Seeds				uint64		`json:"seeds"`
	Leeches				uint64		`json:"leeches"`
	FileCount			uint64		`json:"file_count"`
	Size				float64		`json:"size"`
	DownloadCount		uint64		`json:"download_count"`
	UploadDate			string		`json:"upload_date"`
	UploaderUsername	string		`json:"uploader_username"`
	FileInfo			FileInfo	`json:"file_info"`
	Page				string		`json:"page"`
	RssFeed				string		`json:"rss_feed"`
	MagnetURI			string		`json:"magnet_uri"`
}

/*
GetDownload returns a TorrentDownload
*/
func (t Torrent) GetDownload() (TorrentDownload, error) {
	return Download(t.Hash)
}

/*
GetInfo returns a TorrentResults object containing torrent info
*/
func (t Torrent) GetInfo() (TorrentResults, error) {
	return Info(t.Hash)
}

/*
GetIMDb returns an IMDb movie information object.
*/
func (t Torrent) GetIMDb() (IMDb, error) {
	return Imdb(t.ImdbID)
}

/*
GetDescription returns a TorrentDescription containing a base64 encoded HTML description,
or a TorrentDescription containing a plain text description if true is passed as the
first parameter.
*/
func (t Torrent) GetDescription(params ...bool) (result TorrentDescription, err error) {
	decode := false
	if (len(params) > 0) {
		decode = params[0]
	}
	return Description(t.ImdbID, decode)
}

/*
TorrentResults contains information about an API response and holds an array of Torrent objects
*/
type TorrentResults struct {
	Results				uint64		`json:"results"`
	StatusCode			uint16		`json:"statuscode"`
	ResponseTime		float32		`json:"responsetime"`
	Torrents			[]Torrent	`json:"torrents"`
}

/*
TorrentCount contains a Count from a count API response
*/
type TorrentCount struct {
	StatusCode			uint16		`json:"statuscode"`
	Count				uint64		`json:"message"`
}

/*
TorrentDescription contains a Description from a description API response
*/
type TorrentDescription struct {
	StatusCode			uint16		`json:"statuscode"`
	Description			string		`json:"message"`
}

/*
TorrentDownload contains a Uri from a download API response
*/
type TorrentDownload struct {
	StatusCode			uint16		`json:"statuscode"`
	URI					string		`json:"message"`
}

/*
IMDb contains movie information from an imdb API response
*/
type IMDb struct {
	ID					uint64		`json:"id"`
	ImdbID				string		`json:"imdbID"`
	Title				string		`json:"Title"`
	Year				uint16		`json:"Year"`
	Rating				float32		`json:"Rating"`
	Runtime				string		`json:"Runtime"`
	Genre				string		`json:"Genre"`
	Released			string		`json:"Released"`
	Director			string		`json:"Director"`
	Writer				string		`json:"Writer"`
	Cast				string		`json:"Cast"`
	Metacritic			string		`json:"Metacritic"`
	ImdbRating			string		`json:"imdbRating"`
	ImdbVotes			string		`json:"imdbVotes"`
	Poster				string		`json:"Poster"`
	Plot				string		`json:"Plot"`
	FullPlot			string		`json:"FullPlot"`
	Language			string		`json:"Language"`
	Country				string		`json:"Country"`
	Awards				string		`json:"Awards"`
	LastUpdated			string		`json:"lastUpdated"`
	Type				string		`json:"Type"`
}<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"

	"github.com/go-telegram-bot-api/telegram-bot-api"
)

func main() {
	bot, err := tgbotapi.NewBotAPI(os.Getenv("UDOIT_API_TOKEN"))
	if err != nil {
		log.Panicf("failed to init bot api: %s", err)
	}

	log.Printf("authorized on account %s", bot.Self.UserName)
	bot.Debug = true

	updates, err := bot.GetUpdatesChan(tgbotapi.UpdateConfig{Timeout: 60})
	if err != nil {
		log.Panicf("failed to get updates: %s", err)
	}

	for update := range updates {
		if update.Message == nil {
			continue
		}

		log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)

		msg := tgbotapi.NewMessage(update.Message.Chat.ID, update.Message.Text)
		msg.ReplyToMessageID = update.Message.MessageID
		_, err = bot.Send(msg)
		if err != nil {
			log.Printf("failed to send message: %s", err)
		}
	}
}
<commit_msg>webhook or get updates (#7)<commit_after>package main

import (
	"log"
	"os"

	"github.com/go-telegram-bot-api/telegram-bot-api"
)

func getUpdatesChan(bot *tgbotapi.BotAPI) (tgbotapi.UpdatesChannel, error) {
	webhook := os.Getenv("UDOIT_WEBHOOK") != ""

	if webhook {
		_, err := bot.SetWebhook(tgbotapi.NewWebhook("")) // todo url
		if err != nil {
			log.Panicf("failed to set webhook: %s", err)
		}

		return bot.ListenForWebhook("/" + bot.Token), nil
	}

	return bot.GetUpdatesChan(tgbotapi.UpdateConfig{Timeout: 60})
}

func main() {
	bot, err := tgbotapi.NewBotAPI(os.Getenv("UDOIT_API_TOKEN"))
	if err != nil {
		log.Panicf("failed to init bot api: %s", err)
	}

	log.Printf("authorized on account %s", bot.Self.UserName)
	bot.Debug = true

	updates, err := getUpdatesChan(bot)
	if err != nil {
		log.Panicf("failed to get updates: %s", err)
	}

	for update := range updates {
		if update.Message == nil {
			continue
		}

		log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)

		msg := tgbotapi.NewMessage(update.Message.Chat.ID, update.Message.Text)
		msg.ReplyToMessageID = update.Message.MessageID
		_, err = bot.Send(msg)
		if err != nil {
			log.Printf("failed to send message: %s", err)
		}
	}
}
<|endoftext|>


<commit_before><commit_msg>CloudWatch: Fix custom metrics (#28391)<commit_after><|endoftext|>


<commit_before>package hub

import (
	"sync"
	"time"

	"github.com/v2ray/v2ray-core/app/dispatcher"
	"github.com/v2ray/v2ray-core/common/alloc"
	"github.com/v2ray/v2ray-core/common/log"
	v2net "github.com/v2ray/v2ray-core/common/net"
	"github.com/v2ray/v2ray-core/transport/ray"
)

type UDPResponseCallback func(destination v2net.Destination, payload *alloc.Buffer)

type TimedInboundRay struct {
	name       string
	inboundRay ray.InboundRay
	accessed   chan bool
	server     *UDPServer
	sync.RWMutex
}

func NewTimedInboundRay(name string, inboundRay ray.InboundRay) *TimedInboundRay {
	r := &TimedInboundRay{
		name:       name,
		inboundRay: inboundRay,
		accessed:   make(chan bool),
	}
	go r.Monitor()
	return r
}

func (this *TimedInboundRay) Monitor() {
	for {
		time.Sleep(time.Second * 16)
		select {
		case <-this.accessed:
		default:
			// Ray not accessed for a while, assuming communication is dead.
			this.Release()
			return
		}
	}
}

func (this *TimedInboundRay) InboundInput() ray.OutputStream {
	this.RLock()
	defer this.RUnlock()
	if this.inboundRay == nil {
		return nil
	}
	select {
	case this.accessed <- true:
	default:
	}
	return this.inboundRay.InboundInput()
}

func (this *TimedInboundRay) InboundOutput() ray.InputStream {
	this.RLock()
	defer this.RUnlock()
	if this.inboundRay == nil {
		return nil
	}
	select {
	case this.accessed <- true:
	default:
	}
	return this.inboundRay.InboundOutput()
}

func (this *TimedInboundRay) Release() {
	log.Debug("UDP Server: Releasing TimedInboundRay: ", this.name)
	this.Lock()
	defer this.Unlock()
	if this.server == nil {
		return
	}
	this.server.RemoveRay(this.name)
	this.server = nil
	this.inboundRay.InboundInput().Close()
	this.inboundRay.InboundOutput().Release()
	this.inboundRay = nil
}

type UDPServer struct {
	sync.RWMutex
	conns            map[string]*TimedInboundRay
	packetDispatcher dispatcher.PacketDispatcher
}

func NewUDPServer(packetDispatcher dispatcher.PacketDispatcher) *UDPServer {
	return &UDPServer{
		conns:            make(map[string]*TimedInboundRay),
		packetDispatcher: packetDispatcher,
	}
}

func (this *UDPServer) RemoveRay(name string) {
	this.Lock()
	defer this.Unlock()
	delete(this.conns, name)
}

func (this *UDPServer) locateExistingAndDispatch(name string, payload *alloc.Buffer) bool {
	log.Debug("UDP Server: Locating existing connection for ", name)
	this.RLock()
	defer this.RUnlock()
	if entry, found := this.conns[name]; found {
		outputStream := entry.InboundInput()
		if outputStream == nil {
			return false
		}
		err := outputStream.Write(payload)
		if err != nil {
			go this.RemoveRay(name)
			return false
		}
		return true
	}
	return false
}

func (this *UDPServer) Dispatch(source v2net.Destination, destination v2net.Destination, payload *alloc.Buffer, callback UDPResponseCallback) {
	destString := source.Address().String() + "-" + destination.NetAddr()
	log.Debug("UDP Server: Dispatch request: ", destString)
	if this.locateExistingAndDispatch(destString, payload) {
		return
	}

	log.Info("UDP Server: establishing new connection for ", destString)
	inboundRay := this.packetDispatcher.DispatchToOutbound(destination)
	timedInboundRay := NewTimedInboundRay(destString, inboundRay)
	outputStream := timedInboundRay.InboundInput()
	if outputStream != nil {
		outputStream.Write(payload)
	}

	this.Lock()
	this.conns[destString] = timedInboundRay
	this.Unlock()
	go this.handleConnection(timedInboundRay, source, callback)
}

func (this *UDPServer) handleConnection(inboundRay *TimedInboundRay, source v2net.Destination, callback UDPResponseCallback) {
	for {
		inputStream := inboundRay.InboundOutput()
		if inputStream == nil {
			break
		}
		data, err := inboundRay.InboundOutput().Read()
		if err != nil {
			break
		}
		callback(source, data)
	}
	inboundRay.Release()
}
<commit_msg>fix udp connection mapping<commit_after>package hub

import (
	"sync"
	"time"

	"github.com/v2ray/v2ray-core/app/dispatcher"
	"github.com/v2ray/v2ray-core/common/alloc"
	"github.com/v2ray/v2ray-core/common/log"
	v2net "github.com/v2ray/v2ray-core/common/net"
	"github.com/v2ray/v2ray-core/transport/ray"
)

type UDPResponseCallback func(destination v2net.Destination, payload *alloc.Buffer)

type TimedInboundRay struct {
	name       string
	inboundRay ray.InboundRay
	accessed   chan bool
	server     *UDPServer
	sync.RWMutex
}

func NewTimedInboundRay(name string, inboundRay ray.InboundRay) *TimedInboundRay {
	r := &TimedInboundRay{
		name:       name,
		inboundRay: inboundRay,
		accessed:   make(chan bool),
	}
	go r.Monitor()
	return r
}

func (this *TimedInboundRay) Monitor() {
	for {
		time.Sleep(time.Second * 16)
		select {
		case <-this.accessed:
		default:
			// Ray not accessed for a while, assuming communication is dead.
			this.Release()
			return
		}
	}
}

func (this *TimedInboundRay) InboundInput() ray.OutputStream {
	this.RLock()
	defer this.RUnlock()
	if this.inboundRay == nil {
		return nil
	}
	select {
	case this.accessed <- true:
	default:
	}
	return this.inboundRay.InboundInput()
}

func (this *TimedInboundRay) InboundOutput() ray.InputStream {
	this.RLock()
	defer this.RUnlock()
	if this.inboundRay == nil {
		return nil
	}
	select {
	case this.accessed <- true:
	default:
	}
	return this.inboundRay.InboundOutput()
}

func (this *TimedInboundRay) Release() {
	log.Debug("UDP Server: Releasing TimedInboundRay: ", this.name)
	this.Lock()
	defer this.Unlock()
	if this.server == nil {
		return
	}
	this.server.RemoveRay(this.name)
	this.server = nil
	this.inboundRay.InboundInput().Close()
	this.inboundRay.InboundOutput().Release()
	this.inboundRay = nil
}

type UDPServer struct {
	sync.RWMutex
	conns            map[string]*TimedInboundRay
	packetDispatcher dispatcher.PacketDispatcher
}

func NewUDPServer(packetDispatcher dispatcher.PacketDispatcher) *UDPServer {
	return &UDPServer{
		conns:            make(map[string]*TimedInboundRay),
		packetDispatcher: packetDispatcher,
	}
}

func (this *UDPServer) RemoveRay(name string) {
	this.Lock()
	defer this.Unlock()
	delete(this.conns, name)
}

func (this *UDPServer) locateExistingAndDispatch(name string, payload *alloc.Buffer) bool {
	log.Debug("UDP Server: Locating existing connection for ", name)
	this.RLock()
	defer this.RUnlock()
	if entry, found := this.conns[name]; found {
		outputStream := entry.InboundInput()
		if outputStream == nil {
			return false
		}
		err := outputStream.Write(payload)
		if err != nil {
			go this.RemoveRay(name)
			return false
		}
		return true
	}
	return false
}

func (this *UDPServer) Dispatch(source v2net.Destination, destination v2net.Destination, payload *alloc.Buffer, callback UDPResponseCallback) {
	destString := source.NetAddr() + "-" + destination.NetAddr()
	log.Debug("UDP Server: Dispatch request: ", destString)
	if this.locateExistingAndDispatch(destString, payload) {
		return
	}

	log.Info("UDP Server: establishing new connection for ", destString)
	inboundRay := this.packetDispatcher.DispatchToOutbound(destination)
	timedInboundRay := NewTimedInboundRay(destString, inboundRay)
	outputStream := timedInboundRay.InboundInput()
	if outputStream != nil {
		outputStream.Write(payload)
	}

	this.Lock()
	this.conns[destString] = timedInboundRay
	this.Unlock()
	go this.handleConnection(timedInboundRay, source, callback)
}

func (this *UDPServer) handleConnection(inboundRay *TimedInboundRay, source v2net.Destination, callback UDPResponseCallback) {
	for {
		inputStream := inboundRay.InboundOutput()
		if inputStream == nil {
			break
		}
		data, err := inboundRay.InboundOutput().Read()
		if err != nil {
			break
		}
		callback(source, data)
	}
	inboundRay.Release()
}
<|endoftext|>


<commit_before>/* this is blockchain technology.  Well, except without the blocks.
Really it's header chain technology.
The blocks themselves don't really make a chain.  Just the headers do.
*/

package uspv

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"math/big"
	"os"

	"github.com/adiabat/btcd/blockchain"

	"github.com/adiabat/btcd/wire"
	"github.com/mit-dci/lit/coinparam"
)

// checkProofOfWork verifies the header hashes into something
// lower than specified by the 4-byte bits field.
func checkProofOfWork(header wire.BlockHeader, p *coinparam.Params, height int32) bool {

	target := blockchain.CompactToBig(header.Bits)

	// The target must more than 0.  Why can you even encode negative...
	if target.Sign() <= 0 {
		log.Printf("block target %064x is neagtive(??)\n", target.Bytes())
		return false
	}
	// The target must be less than the maximum allowed (difficulty 1)
	if target.Cmp(p.PowLimit) > 0 {
		log.Printf("block target %064x is "+
			"higher than max of %064x", target, p.PowLimit.Bytes())
		return false
	}

	// The header hash must be less than the claimed target in the header.
	var buf bytes.Buffer
	_ = wire.WriteBlockHeader(&buf, 0, &header)

	blockHash := p.PoWFunction(buf.Bytes(), height)

	hashNum := new(big.Int)

	hashNum = blockchain.HashToBig(&blockHash)
	if hashNum.Cmp(target) > 0 {
		log.Printf("block hash %064x is higher than "+
			"required target of %064x", hashNum, target)
		return false
	}
	return true
}

// GetHeaderAtHeight gives back a header at the specified height
func (s *SPVCon) GetHeaderAtHeight(h int32) (*wire.BlockHeader, error) {
	s.headerMutex.Lock()
	defer s.headerMutex.Unlock()

	// height is reduced by startHeight
	h = h - s.Param.StartHeight

	// seek to that header
	_, err := s.headerFile.Seek(int64(80*h), os.SEEK_SET)
	if err != nil {
		return nil, err
	}

	hdr := new(wire.BlockHeader)
	err = hdr.Deserialize(s.headerFile)
	if err != nil {
		return nil, err
	}

	return hdr, nil
}

// GetHeaderAtHeight gives back a header at the specified height
func (s *SPVCon) GetHeaderTipHeight() int32 {
	s.headerMutex.Lock() // start header file ops
	defer s.headerMutex.Unlock()
	info, err := s.headerFile.Stat()
	if err != nil {
		log.Printf("Header file error: %s", err.Error())
		return 0
	}
	headerFileSize := info.Size()
	if headerFileSize == 0 || headerFileSize%80 != 0 { // header file broken
		// try to fix it!
		s.headerFile.Truncate(headerFileSize - (headerFileSize % 80))
		log.Printf("ERROR: Header file not a multiple of 80 bytes. Truncating")
	}
	// subtract 1 as we want the start of the tip offset, not the end
	return int32(headerFileSize/80) + s.Param.StartHeight - 1
}

// FindHeader will try to find where the header you give it is.
// it runs backwards to find it and gives up after 1000 headers
func FindHeader(r io.ReadSeeker, hdr wire.BlockHeader) (int32, error) {

	var cur wire.BlockHeader

	for tries := 1; tries < 2200; tries++ {
		offset, err := r.Seek(int64(-80*tries), os.SEEK_END)
		if err != nil {
			return -1, err
		}

		//	for blkhash.IsEqual(&target) {
		err = cur.Deserialize(r)
		if err != nil {
			return -1, err
		}
		curhash := cur.BlockHash()

		//		fmt.Printf("try %d %s\n", tries, curhash.String())

		if hdr.PrevBlock.IsEqual(&curhash) {
			return int32(offset / 80), nil
		}
	}

	return 0, nil
}

// CheckHeaderChain takes in the headers message and sees if they all validate.
// This function also needs read access to the previous headers.
// Does not deal with re-orgs; assumes new headers link to tip
// returns true if *all* headers are cool, false if there is any problem
// Note we don't know what the height is, just the relative height.
// returnin nil means it worked
// returns an int32 usually 0, but if there's a reorg, shows what height to
// reorg back to before adding on the headers
func CheckHeaderChain(
	r io.ReadSeeker, inHeaders []*wire.BlockHeader,
	p *coinparam.Params) (int32, error) {

	// make sure we actually got new headers
	if len(inHeaders) < 1 {
		return 0, fmt.Errorf(
			"CheckHeaderChain: headers message doesn't have any headers.")
	}

	// first, look through all the incoming headers to make sure
	// they're at least self-consistent.  Do this before even
	// checking that they link to anything; it's all in-ram and quick
	for i, hdr := range inHeaders {
		// check they link to each other
		// That whole 'blockchain' thing.
		if i > 1 {
			hash := inHeaders[i-1].BlockHash()
			if !hdr.PrevBlock.IsEqual(&hash) {
				return 0, fmt.Errorf(
					"headers %d and %d in header message don't link", i, i-1)
			}
		}

		// check that header version is non-negative (fork detect)
		if hdr.Version < 0 {
			return 0, fmt.Errorf(
				"header %d in message has negative version (hard fork?)", i)
		}
	}
	// incoming header message is internally consistent, now check that it
	// links with what we have on disk

	epochLength := int32(p.TargetTimespan / p.TargetTimePerBlock)

	if p.MinHeaders > 0 {
		epochLength = p.MinHeaders
	}

	// seek to start of last header
	pos, err := r.Seek(-80, os.SEEK_END)
	if err != nil {
		return 0, err
	}
	log.Printf("header file position: %d\n", pos)
	if pos%80 != 0 {
		return 0, fmt.Errorf(
			"CheckHeaderChain: Header file not a multiple of 80 bytes.")
	}

	// we know incoming height; it's startheight + all the headers on disk + 1
	height := int32(pos/80) + p.StartHeight + 1

	// see if we don't have enough & load em all.
	var numheaders int32 // number of headers to read

	// load only last epoch if there are a lot on disk
	if pos > int64(80*(epochLength+1)) {
		_, err = r.Seek(int64(-80*(epochLength+1)), os.SEEK_END)
		numheaders = epochLength + 1
	} else { // otherwise load everything, start at byte 0
		_, err = r.Seek(0, os.SEEK_SET)
		numheaders = height - p.StartHeight
	}
	if err != nil { // seems like it will always be ok here..?
		return 0, err
	}

	// weird off-by-1 stuff here; makes numheaders, incluing the 0th
	oldHeaders := make([]*wire.BlockHeader, numheaders)
	log.Printf("made %d header slice\n", len(oldHeaders))
	// load a bunch of headers from disk into ram
	for i, _ := range oldHeaders {
		// read from file at current offset
		oldHeaders[i] = new(wire.BlockHeader)
		err = oldHeaders[i].Deserialize(r)
		if err != nil {
			log.Printf("CheckHeaderChain ran out of file at oldheader %d\n", i)
			return 0, err
		}
	}

	tiphash := oldHeaders[len(oldHeaders)-1].BlockHash()

	var attachHeight int32
	// make sure the first header in the message points to our on-disk tip
	if !inHeaders[0].PrevBlock.IsEqual(&tiphash) {

		// find where it points to

		attachHeight, err = FindHeader(r, *inHeaders[0])
		if err != nil {
			return 0, fmt.Errorf(
				"CheckHeaderChain: header message doesn't attach to tip or anywhere.")
		}

		// adjust attachHeight by adding the startheight
		attachHeight += p.StartHeight

		log.Printf("Header %s attaches at height %d\n",
			inHeaders[0].BlockHash().String(), attachHeight)

		// TODO check for more work here instead of length.  This is wrong...
		// if we've been given insufficient headers, don't reorg, but
		// ask for more headers.
		if attachHeight+int32(len(inHeaders)) < height {
			return -1, fmt.Errorf(
				"reorg message up to height %d, but have up to %d",
				attachHeight+int32(len(inHeaders)), height-1)
		}

		log.Printf("reorg from height %d to %d",
			height-1, attachHeight+int32(len(inHeaders)))

		// reorg is go, snip to attach height
		reorgDepth := height - attachHeight
		oldHeaders = oldHeaders[:numheaders-reorgDepth]
	}

	prevHeaders := oldHeaders

	// check difficulty adjustments in the new headers
	// since we call this many times, append each time
	for i, hdr := range inHeaders {
		// check if there's a valid proof of work.  That whole "Bitcoin" thing.
		if !checkProofOfWork(*hdr, p, height+int32(i)) {
			return 0, fmt.Errorf("header %d in message has bad proof of work", i)
		}

		// build slice of "previous" headers
		prevHeaders = append(prevHeaders, inHeaders[i])
		rightBits, err := p.DiffCalcFunction(prevHeaders, height+int32(i), p)
		if err != nil {
			return 0, fmt.Errorf("Error calculating Block %d %s difficuly. %s",
				int(height)+i, hdr.BlockHash().String(), err.Error())
		}

		// vertcoin diff adjustment not yet implemented
		// TODO - get rid of coin specific workaround
		if hdr.Bits != rightBits && (p.Name != "vtctest" && p.Name != "vtc") {
			return 0, fmt.Errorf("Block %d %s incorrect difficuly.  Read %x, expect %x",
				int(height)+i, hdr.BlockHash().String(), hdr.Bits, rightBits)
		}
	}

	return attachHeight, nil
}
<commit_msg>Fix VTC main net sync from 0 from archival nodes (#155)<commit_after>/* this is blockchain technology.  Well, except without the blocks.
Really it's header chain technology.
The blocks themselves don't really make a chain.  Just the headers do.
*/

package uspv

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"math/big"
	"os"

	"github.com/adiabat/btcd/blockchain"

	"github.com/adiabat/btcd/wire"
	"github.com/mit-dci/lit/coinparam"
)

// checkProofOfWork verifies the header hashes into something
// lower than specified by the 4-byte bits field.
func checkProofOfWork(header wire.BlockHeader, p *coinparam.Params, height int32) bool {

	target := blockchain.CompactToBig(header.Bits)

	// The target must more than 0.  Why can you even encode negative...
	if target.Sign() <= 0 {
		log.Printf("block target %064x is neagtive(??)\n", target.Bytes())
		return false
	}
	// The target must be less than the maximum allowed (difficulty 1)
	if target.Cmp(p.PowLimit) > 0 {
		log.Printf("block target %064x is "+
			"higher than max of %064x", target, p.PowLimit.Bytes())
		return false
	}

	// The header hash must be less than the claimed target in the header.
	var buf bytes.Buffer
	_ = wire.WriteBlockHeader(&buf, 0, &header)

	blockHash := p.PoWFunction(buf.Bytes(), height)

	hashNum := new(big.Int)

	hashNum = blockchain.HashToBig(&blockHash)
	if hashNum.Cmp(target) > 0 {
		log.Printf("block hash %064x is higher than "+
			"required target of %064x", hashNum, target)
		return false
	}
	return true
}

// GetHeaderAtHeight gives back a header at the specified height
func (s *SPVCon) GetHeaderAtHeight(h int32) (*wire.BlockHeader, error) {
	s.headerMutex.Lock()
	defer s.headerMutex.Unlock()

	// height is reduced by startHeight
	h = h - s.Param.StartHeight

	// seek to that header
	_, err := s.headerFile.Seek(int64(80*h), os.SEEK_SET)
	if err != nil {
		return nil, err
	}

	hdr := new(wire.BlockHeader)
	err = hdr.Deserialize(s.headerFile)
	if err != nil {
		return nil, err
	}

	return hdr, nil
}

// GetHeaderAtHeight gives back a header at the specified height
func (s *SPVCon) GetHeaderTipHeight() int32 {
	s.headerMutex.Lock() // start header file ops
	defer s.headerMutex.Unlock()
	info, err := s.headerFile.Stat()
	if err != nil {
		log.Printf("Header file error: %s", err.Error())
		return 0
	}
	headerFileSize := info.Size()
	if headerFileSize == 0 || headerFileSize%80 != 0 { // header file broken
		// try to fix it!
		s.headerFile.Truncate(headerFileSize - (headerFileSize % 80))
		log.Printf("ERROR: Header file not a multiple of 80 bytes. Truncating")
	}
	// subtract 1 as we want the start of the tip offset, not the end
	return int32(headerFileSize/80) + s.Param.StartHeight - 1
}

// FindHeader will try to find where the header you give it is.
// it runs backwards to find it and gives up after 1000 headers
func FindHeader(r io.ReadSeeker, hdr wire.BlockHeader) (int32, error) {

	var cur wire.BlockHeader

	for tries := 1; tries < 2200; tries++ {
		offset, err := r.Seek(int64(-80*tries), os.SEEK_END)
		if err != nil {
			return -1, err
		}

		//	for blkhash.IsEqual(&target) {
		err = cur.Deserialize(r)
		if err != nil {
			return -1, err
		}
		curhash := cur.BlockHash()

		//		fmt.Printf("try %d %s\n", tries, curhash.String())

		if hdr.PrevBlock.IsEqual(&curhash) {
			return int32(offset / 80), nil
		}
	}

	return 0, nil
}

// CheckHeaderChain takes in the headers message and sees if they all validate.
// This function also needs read access to the previous headers.
// Does not deal with re-orgs; assumes new headers link to tip
// returns true if *all* headers are cool, false if there is any problem
// Note we don't know what the height is, just the relative height.
// returnin nil means it worked
// returns an int32 usually 0, but if there's a reorg, shows what height to
// reorg back to before adding on the headers
func CheckHeaderChain(
	r io.ReadSeeker, inHeaders []*wire.BlockHeader,
	p *coinparam.Params) (int32, error) {

	// make sure we actually got new headers
	if len(inHeaders) < 1 {
		return 0, fmt.Errorf(
			"CheckHeaderChain: headers message doesn't have any headers.")
	}

	// first, look through all the incoming headers to make sure
	// they're at least self-consistent.  Do this before even
	// checking that they link to anything; it's all in-ram and quick
	for i, hdr := range inHeaders {
		// check they link to each other
		// That whole 'blockchain' thing.
		if i > 1 {
			hash := inHeaders[i-1].BlockHash()
			if !hdr.PrevBlock.IsEqual(&hash) {
				return 0, fmt.Errorf(
					"headers %d and %d in header message don't link", i, i-1)
			}
		}

		// check that header version is non-negative (fork detect)
		if hdr.Version < 0 {
			return 0, fmt.Errorf(
				"header %d in message has negative version (hard fork?)", i)
		}
	}
	// incoming header message is internally consistent, now check that it
	// links with what we have on disk

	epochLength := int32(p.TargetTimespan / p.TargetTimePerBlock)

	if p.MinHeaders > 0 {
		epochLength = p.MinHeaders
	}

	// seek to start of last header
	pos, err := r.Seek(-80, os.SEEK_END)
	if err != nil {
		return 0, err
	}
	log.Printf("header file position: %d\n", pos)
	if pos%80 != 0 {
		return 0, fmt.Errorf(
			"CheckHeaderChain: Header file not a multiple of 80 bytes.")
	}

	// we know incoming height; it's startheight + all the headers on disk + 1
	height := int32(pos/80) + p.StartHeight + 1

	// see if we don't have enough & load em all.
	var numheaders int32 // number of headers to read

	// load only last epoch if there are a lot on disk
	if pos > int64(80*(epochLength+1)) {
		_, err = r.Seek(int64(-80*(epochLength+1)), os.SEEK_END)
		numheaders = epochLength + 1
	} else { // otherwise load everything, start at byte 0
		_, err = r.Seek(0, os.SEEK_SET)
		numheaders = height - p.StartHeight
	}
	if err != nil { // seems like it will always be ok here..?
		return 0, err
	}

	// weird off-by-1 stuff here; makes numheaders, incluing the 0th
	oldHeaders := make([]*wire.BlockHeader, numheaders)
	log.Printf("made %d header slice\n", len(oldHeaders))
	// load a bunch of headers from disk into ram
	for i, _ := range oldHeaders {
		// read from file at current offset
		oldHeaders[i] = new(wire.BlockHeader)
		err = oldHeaders[i].Deserialize(r)
		if err != nil {
			log.Printf("CheckHeaderChain ran out of file at oldheader %d\n", i)
			return 0, err
		}
	}

	tiphash := oldHeaders[len(oldHeaders)-1].BlockHash()

	var attachHeight int32
	// make sure the first header in the message points to our on-disk tip
	if !inHeaders[0].PrevBlock.IsEqual(&tiphash) {

		// find where it points to

		attachHeight, err = FindHeader(r, *inHeaders[0])
		if err != nil {
			return 0, fmt.Errorf(
				"CheckHeaderChain: header message doesn't attach to tip or anywhere.")
		}

		// adjust attachHeight by adding the startheight
		attachHeight += p.StartHeight

		log.Printf("Header %s attaches at height %d\n",
			inHeaders[0].BlockHash().String(), attachHeight)

		// TODO check for more work here instead of length.  This is wrong...
		// if we've been given insufficient headers, don't reorg, but
		// ask for more headers.
		if attachHeight+int32(len(inHeaders)) < height {
			return -1, fmt.Errorf(
				"reorg message up to height %d, but have up to %d",
				attachHeight+int32(len(inHeaders)), height-1)
		}

		log.Printf("reorg from height %d to %d",
			height-1, attachHeight+int32(len(inHeaders)))

		// reorg is go, snip to attach height
		reorgDepth := height - attachHeight
		oldHeaders = oldHeaders[:numheaders-reorgDepth]
	}

	prevHeaders := oldHeaders

	// check difficulty adjustments in the new headers
	// since we call this many times, append each time
	for i, hdr := range inHeaders {
		if height+int32(i) > p.AssumeDiffBefore {
			// check if there's a valid proof of work.  That whole "Bitcoin" thing.
			if !checkProofOfWork(*hdr, p, height+int32(i)) {
				return 0, fmt.Errorf("header %d in message has bad proof of work", i)
			}

			// build slice of "previous" headers
			prevHeaders = append(prevHeaders, inHeaders[i])
			rightBits, err := p.DiffCalcFunction(prevHeaders, height+int32(i), p)
			if err != nil {
				return 0, fmt.Errorf("Error calculating Block %d %s difficuly. %s",
					int(height)+i, hdr.BlockHash().String(), err.Error())
			}

			// vertcoin diff adjustment not yet implemented
			// TODO - get rid of coin specific workaround
			if hdr.Bits != rightBits && (p.Name != "vtctest" && p.Name != "vtc") {
				return 0, fmt.Errorf("Block %d %s incorrect difficuly.  Read %x, expect %x",
					int(height)+i, hdr.BlockHash().String(), hdr.Bits, rightBits)
			}
		}
	}

	return attachHeight, nil
}
<|endoftext|>


<commit_before>package util

import (
	"fmt"
	"sort"
)

type Module struct {
	Name    string
	Handler func()
}

var PrintModuleInitLog = false

type modulelist []Module

func (m modulelist) Len() int {
	return len(m)
}
func (m modulelist) Swap(i, j int) {
	m[i], m[j] = m[j], m[i]
}
func (m modulelist) Less(i, j int) bool {
	return m[i].Name < m[j].Name
}

var Modules = modulelist{}

func RegisteModule(name string, handler func()) Module {
	m := Module{Name: name, Handler: handler}
	Modules = append(Modules, m)
	return m
}

func InitModulesOrderByName() {
	sort.Sort(Modules)
	for k := range Modules {
		if PrintModuleInitLog {
			fmt.Println("Util: Init module " + Modules[k].Name)
		}
		Modules[k].Handler()
	}
}
<commit_msg>update<commit_after>package util

import (
	"fmt"
	"sort"
)

type Module struct {
	Name    string
	Handler func()
}

var PrintModuleInitLog = false

type modulelist []Module

func (m modulelist) Len() int {
	return len(m)
}
func (m modulelist) Swap(i, j int) {
	m[i], m[j] = m[j], m[i]
}
func (m modulelist) Less(i, j int) bool {
	return m[i].Name < m[j].Name
}

var Modules = modulelist{}

func RegisteModule(name string, handler func()) Module {
	m := Module{Name: name, Handler: handler}
	Modules = append(Modules, m)
	return m
}

func InitModulesOrderByName() {
	sort.Sort(Modules)
	for k := range Modules {
		if PrintModuleInitLog {
			fmt.Println("Herb-go util debug: Init module " + Modules[k].Name)
		}
		Modules[k].Handler()
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 Tigera Inc
//
// 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 utils

import (
	"errors"
	"flag"
	"fmt"
	"net"
	"os"
	"regexp"

	log "github.com/Sirupsen/logrus"

	"strings"

	"github.com/containernetworking/cni/pkg/ipam"
	"github.com/containernetworking/cni/pkg/skel"
	"github.com/containernetworking/cni/pkg/types"
	"github.com/golang/glog"
	"github.com/projectcalico/libcalico-go/lib/api"
	"github.com/projectcalico/libcalico-go/lib/client"
	cnet "github.com/projectcalico/libcalico-go/lib/net"
)

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

// ValidateNetworkName checks that the network name meets felix's expectations
func ValidateNetworkName(name string) error {
	matched, err := regexp.MatchString(`^[a-zA-Z0-9_\.\-]+$`, name)
	if err != nil {
		return err
	}
	if !matched {
		return errors.New("Invalid characters detected in the given network name. " +
			"Only letters a-z, numbers 0-9, and symbols _.- are supported.")
	}
	return nil
}

// AddIgnoreUnknownArgs appends the 'IgnoreUnknown=1' option to CNI_ARGS before calling the IPAM plugin. Otherwise, it will
// complain about the Kubernetes arguments. See https://github.com/kubernetes/kubernetes/pull/24983
func AddIgnoreUnknownArgs() error {
	cniArgs := "IgnoreUnknown=1"
	if os.Getenv("CNI_ARGS") != "" {
		cniArgs = fmt.Sprintf("%s;%s", cniArgs, os.Getenv("CNI_ARGS"))
	}
	return os.Setenv("CNI_ARGS", cniArgs)
}

func CreateResultFromEndpoint(ep *api.WorkloadEndpoint) (*types.Result, error) {
	result := &types.Result{}

	for _, v := range ep.Spec.IPNetworks {
		unparsedIP := fmt.Sprintf(`{"ip": "%s"}`, v.String())
		parsedIP := types.IPConfig{}
		if err := parsedIP.UnmarshalJSON([]byte(unparsedIP)); err != nil {
			log.Errorf("Error unmarshalling existing endpoint IP: %s", err)
			return nil, err
		}

		if len(v.IP) == net.IPv4len {
			result.IP4 = &parsedIP
		} else {
			result.IP6 = &parsedIP
		}
	}

	return result, nil
}

func GetIdentifiers(args *skel.CmdArgs) (workloadID string, orchestratorID string, err error) {
	// Determine if running under k8s by checking the CNI args
	k8sArgs := K8sArgs{}
	if err = types.LoadArgs(args.Args, &k8sArgs); err != nil {
		return workloadID, orchestratorID, err
	}

	if string(k8sArgs.K8S_POD_NAMESPACE) != "" && string(k8sArgs.K8S_POD_NAME) != "" {
		workloadID = fmt.Sprintf("%s.%s", k8sArgs.K8S_POD_NAMESPACE, k8sArgs.K8S_POD_NAME)
		orchestratorID = "k8s"
	} else {
		workloadID = args.ContainerID
		orchestratorID = "cni"
	}
	return workloadID, orchestratorID, nil
}

func PopulateEndpointNets(endpoint *api.WorkloadEndpoint, result *types.Result) error {
	if result.IP4 == nil && result.IP6 == nil {
		return errors.New("IPAM plugin did not return any IP addresses")
	}

	if result.IP4 != nil {
		result.IP4.IP.Mask = net.CIDRMask(32, 32)
		endpoint.Spec.IPNetworks = append(endpoint.Spec.IPNetworks, cnet.IPNet{result.IP4.IP})
	}

	if result.IP6 != nil {
		result.IP6.IP.Mask = net.CIDRMask(128, 128)
		endpoint.Spec.IPNetworks = append(endpoint.Spec.IPNetworks, cnet.IPNet{result.IP6.IP})
	}

	return nil
}

func CreateClient(conf NetConf) (*client.Client, error) {
	if err := ValidateNetworkName(conf.Name); err != nil {
		return nil, err
	}

	// Use the config file to override environment variables.
	// These variables will be loaded into the client config.
	if conf.EtcdAuthority != "" {
		if err := os.Setenv("ETCD_AUTHORITY", conf.EtcdAuthority); err != nil {
			return nil, err
		}
	}
	if conf.EtcdEndpoints != "" {
		if err := os.Setenv("ETCD_ENDPOINTS", conf.EtcdEndpoints); err != nil {
			return nil, err
		}
	}
	if conf.EtcdScheme != "" {
		if err := os.Setenv("ETCD_SCHEME", conf.EtcdScheme); err != nil {
			return nil, err
		}
	}
	if conf.EtcdKeyFile != "" {
		if err := os.Setenv("ETCD_KEY_FILE", conf.EtcdKeyFile); err != nil {
			return nil, err
		}
	}
	if conf.EtcdCertFile != "" {
		if err := os.Setenv("ETCD_CERT_FILE", conf.EtcdCertFile); err != nil {
			return nil, err
		}
	}
	if conf.EtcdCaCertFile != "" {
		if err := os.Setenv("ETCD_CA_CERT_FILE", conf.EtcdCaCertFile); err != nil {
			return nil, err
		}
	}
	if conf.DatastoreType != "" {
		if err := os.Setenv("DATASTORE_TYPE", conf.DatastoreType); err != nil {
			return nil, err
		}
	}

	// Set Kubernetes specific variables for use with the Kubernetes libcalico backend.
	if conf.Kubernetes.Kubeconfig != "" {
		if err := os.Setenv("KUBECONFIG", conf.Kubernetes.Kubeconfig); err != nil {
			return nil, err
		}
	}
	if conf.Kubernetes.K8sAPIRoot != "" {
		if err := os.Setenv("K8S_API_ENDPOINT", conf.Kubernetes.K8sAPIRoot); err != nil {
			return nil, err
		}
	}
	if conf.Policy.K8sAuthToken != "" {
		if err := os.Setenv("K8S_API_TOKEN", conf.Policy.K8sAuthToken); err != nil {
			return nil, err
		}
	}
	log.Infof("Configured environment: %+v", os.Environ())

	// Load the client config from the current environment.
	clientConfig, err := client.LoadClientConfig("")
	if err != nil {
		return nil, err
	}

	// Create a new client.
	calicoClient, err := client.New(*clientConfig)
	if err != nil {
		return nil, err
	}
	return calicoClient, nil
}

// ReleaseIPAM is called to cleanup IPAM allocations if something goes wrong during
// CNI ADD execution.
func ReleaseIPAllocation(logger *log.Entry, ipamType string, stdinData []byte) {
	logger.Info("Cleaning up IP allocations for failed ADD")
	if err := os.Setenv("CNI_COMMAND", "DEL"); err != nil {
		// Failed to set CNI_COMMAND to DEL.
		logger.Warning("Failed to set CNI_COMMAND=DEL")
	} else {
		if err := ipam.ExecDel(ipamType, stdinData); err != nil {
			// Failed to cleanup the IP allocation.
			logger.Warning("Failed to clean up IP allocations for failed ADD")
		}
	}
}

// Set up logging for both Calico and libcalico usng the provided log level,
func ConfigureLogging(logLevel string) {
	// Debug is _everything_
	// Info is just CNI info level logs
	// Warning is the default - and again is just CNI logs
	if strings.EqualFold(logLevel, "debug") {
		// Enable glogging for libcalico
		_ = flag.Set("logtostderr", "true")
		_ = flag.Set("v", "10")
		_ = flag.Set("stderrthreshold", "10")
		flag.Parse()
		glog.Info("libcalico glog logging configured")

		// Change logging level for CNI plugin
		log.SetLevel(log.DebugLevel)
	} else if strings.EqualFold(logLevel, "info") {
		log.SetLevel(log.InfoLevel)
	} else {
		// Default level
		log.SetLevel(log.WarnLevel)
	}

	log.SetOutput(os.Stderr)
}

// Create a logger which always includes common fields
func CreateContextLogger(workload string) *log.Entry {
	// A common pattern is to re-use fields between logging statements by re-using
	// the logrus.Entry returned from WithFields()
	contextLogger := log.WithFields(log.Fields{
		"Workload": workload,
	})

	return contextLogger
}
<commit_msg>Clean up logging config<commit_after>// Copyright 2015 Tigera Inc
//
// 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 utils

import (
	"errors"
	"fmt"
	"net"
	"os"
	"regexp"

	log "github.com/Sirupsen/logrus"

	"strings"

	"github.com/containernetworking/cni/pkg/ipam"
	"github.com/containernetworking/cni/pkg/skel"
	"github.com/containernetworking/cni/pkg/types"
	"github.com/projectcalico/libcalico-go/lib/api"
	"github.com/projectcalico/libcalico-go/lib/client"
	cnet "github.com/projectcalico/libcalico-go/lib/net"
)

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

// ValidateNetworkName checks that the network name meets felix's expectations
func ValidateNetworkName(name string) error {
	matched, err := regexp.MatchString(`^[a-zA-Z0-9_\.\-]+$`, name)
	if err != nil {
		return err
	}
	if !matched {
		return errors.New("Invalid characters detected in the given network name. " +
			"Only letters a-z, numbers 0-9, and symbols _.- are supported.")
	}
	return nil
}

// AddIgnoreUnknownArgs appends the 'IgnoreUnknown=1' option to CNI_ARGS before calling the IPAM plugin. Otherwise, it will
// complain about the Kubernetes arguments. See https://github.com/kubernetes/kubernetes/pull/24983
func AddIgnoreUnknownArgs() error {
	cniArgs := "IgnoreUnknown=1"
	if os.Getenv("CNI_ARGS") != "" {
		cniArgs = fmt.Sprintf("%s;%s", cniArgs, os.Getenv("CNI_ARGS"))
	}
	return os.Setenv("CNI_ARGS", cniArgs)
}

func CreateResultFromEndpoint(ep *api.WorkloadEndpoint) (*types.Result, error) {
	result := &types.Result{}

	for _, v := range ep.Spec.IPNetworks {
		unparsedIP := fmt.Sprintf(`{"ip": "%s"}`, v.String())
		parsedIP := types.IPConfig{}
		if err := parsedIP.UnmarshalJSON([]byte(unparsedIP)); err != nil {
			log.Errorf("Error unmarshalling existing endpoint IP: %s", err)
			return nil, err
		}

		if len(v.IP) == net.IPv4len {
			result.IP4 = &parsedIP
		} else {
			result.IP6 = &parsedIP
		}
	}

	return result, nil
}

func GetIdentifiers(args *skel.CmdArgs) (workloadID string, orchestratorID string, err error) {
	// Determine if running under k8s by checking the CNI args
	k8sArgs := K8sArgs{}
	if err = types.LoadArgs(args.Args, &k8sArgs); err != nil {
		return workloadID, orchestratorID, err
	}

	if string(k8sArgs.K8S_POD_NAMESPACE) != "" && string(k8sArgs.K8S_POD_NAME) != "" {
		workloadID = fmt.Sprintf("%s.%s", k8sArgs.K8S_POD_NAMESPACE, k8sArgs.K8S_POD_NAME)
		orchestratorID = "k8s"
	} else {
		workloadID = args.ContainerID
		orchestratorID = "cni"
	}
	return workloadID, orchestratorID, nil
}

func PopulateEndpointNets(endpoint *api.WorkloadEndpoint, result *types.Result) error {
	if result.IP4 == nil && result.IP6 == nil {
		return errors.New("IPAM plugin did not return any IP addresses")
	}

	if result.IP4 != nil {
		result.IP4.IP.Mask = net.CIDRMask(32, 32)
		endpoint.Spec.IPNetworks = append(endpoint.Spec.IPNetworks, cnet.IPNet{result.IP4.IP})
	}

	if result.IP6 != nil {
		result.IP6.IP.Mask = net.CIDRMask(128, 128)
		endpoint.Spec.IPNetworks = append(endpoint.Spec.IPNetworks, cnet.IPNet{result.IP6.IP})
	}

	return nil
}

func CreateClient(conf NetConf) (*client.Client, error) {
	if err := ValidateNetworkName(conf.Name); err != nil {
		return nil, err
	}

	// Use the config file to override environment variables.
	// These variables will be loaded into the client config.
	if conf.EtcdAuthority != "" {
		if err := os.Setenv("ETCD_AUTHORITY", conf.EtcdAuthority); err != nil {
			return nil, err
		}
	}
	if conf.EtcdEndpoints != "" {
		if err := os.Setenv("ETCD_ENDPOINTS", conf.EtcdEndpoints); err != nil {
			return nil, err
		}
	}
	if conf.EtcdScheme != "" {
		if err := os.Setenv("ETCD_SCHEME", conf.EtcdScheme); err != nil {
			return nil, err
		}
	}
	if conf.EtcdKeyFile != "" {
		if err := os.Setenv("ETCD_KEY_FILE", conf.EtcdKeyFile); err != nil {
			return nil, err
		}
	}
	if conf.EtcdCertFile != "" {
		if err := os.Setenv("ETCD_CERT_FILE", conf.EtcdCertFile); err != nil {
			return nil, err
		}
	}
	if conf.EtcdCaCertFile != "" {
		if err := os.Setenv("ETCD_CA_CERT_FILE", conf.EtcdCaCertFile); err != nil {
			return nil, err
		}
	}
	if conf.DatastoreType != "" {
		if err := os.Setenv("DATASTORE_TYPE", conf.DatastoreType); err != nil {
			return nil, err
		}
	}

	// Set Kubernetes specific variables for use with the Kubernetes libcalico backend.
	if conf.Kubernetes.Kubeconfig != "" {
		if err := os.Setenv("KUBECONFIG", conf.Kubernetes.Kubeconfig); err != nil {
			return nil, err
		}
	}
	if conf.Kubernetes.K8sAPIRoot != "" {
		if err := os.Setenv("K8S_API_ENDPOINT", conf.Kubernetes.K8sAPIRoot); err != nil {
			return nil, err
		}
	}
	if conf.Policy.K8sAuthToken != "" {
		if err := os.Setenv("K8S_API_TOKEN", conf.Policy.K8sAuthToken); err != nil {
			return nil, err
		}
	}
	log.Infof("Configured environment: %+v", os.Environ())

	// Load the client config from the current environment.
	clientConfig, err := client.LoadClientConfig("")
	if err != nil {
		return nil, err
	}

	// Create a new client.
	calicoClient, err := client.New(*clientConfig)
	if err != nil {
		return nil, err
	}
	return calicoClient, nil
}

// ReleaseIPAM is called to cleanup IPAM allocations if something goes wrong during
// CNI ADD execution.
func ReleaseIPAllocation(logger *log.Entry, ipamType string, stdinData []byte) {
	logger.Info("Cleaning up IP allocations for failed ADD")
	if err := os.Setenv("CNI_COMMAND", "DEL"); err != nil {
		// Failed to set CNI_COMMAND to DEL.
		logger.Warning("Failed to set CNI_COMMAND=DEL")
	} else {
		if err := ipam.ExecDel(ipamType, stdinData); err != nil {
			// Failed to cleanup the IP allocation.
			logger.Warning("Failed to clean up IP allocations for failed ADD")
		}
	}
}

// Set up logging for both Calico and libcalico usng the provided log level,
func ConfigureLogging(logLevel string) {
	if strings.EqualFold(logLevel, "debug") {
		log.SetLevel(log.DebugLevel)
	} else if strings.EqualFold(logLevel, "info") {
		log.SetLevel(log.InfoLevel)
	} else {
		// Default level
		log.SetLevel(log.WarnLevel)
	}

	log.SetOutput(os.Stderr)
}

// Create a logger which always includes common fields
func CreateContextLogger(workload string) *log.Entry {
	// A common pattern is to re-use fields between logging statements by re-using
	// the logrus.Entry returned from WithFields()
	contextLogger := log.WithFields(log.Fields{
		"Workload": workload,
	})

	return contextLogger
}
<|endoftext|>


<commit_before>package utils

import (
	"crypto/md5"
	"encoding/binary"
	"encoding/gob"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"hash"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"os/signal"
	"path"
	"strconv"
	"strings"
	"syscall"
)

var (
	exitWaiting   bool
	exitCallbacks []func()
)

func CatchExit(callback func()) {
	if callback == nil {
		return
	}
	exitCallbacks = append(exitCallbacks, callback)

	if exitWaiting {
		return
	}
	exitWaiting = true

	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGINT, syscall.SIGHUP, syscall.SIGQUIT)

		for {
			fmt.Println("^C")
			for _, callback := range exitCallbacks {
				callback()
			}
			os.Exit(1)
		}
	}()
}

func Contains(items interface{}, item interface{}) (ok bool) {
	switch a := items.(type) {
	case string:
		if len(a) == 0 {
			return
		}
		sep, yes := item.(string)
		ok = yes && strings.Index(a, sep) > -1
		return
	case []string:
		if len(a) == 0 {
			return
		}
		s, yes := item.(string)
		if yes {
			for _, c := range a {
				if c == s {
					ok = true
					return
				}
			}
		}
		return
	case []int:
		if len(a) == 0 {
			return
		}
		i, yes := item.(int)
		if yes {
			for _, c := range a {
				if c == i {
					return true
				}
			}
		}
		return
	default:
		return
	}
}

func CopyFile(src string, dst string) (n int64, err error) {
	if src == dst {
		return
	}

	in, err := os.Open(src)
	if err != nil {
		return
	}
	defer in.Close()

	out, err := os.Create(dst)
	if err != nil {
		return
	}
	defer func() {
		if e := out.Close(); e != nil {
			err = e
		}
	}()

	n, err = io.Copy(out, in)
	if err != nil {
		return
	}

	err = out.Sync()
	if err != nil {
		return
	}

	si, err := os.Stat(src)
	if err != nil {
		return
	}
	err = os.Chmod(dst, si.Mode())
	if err != nil {
		return
	}

	return
}

func CopyDir(src string, dst string) (err error) {
	src = CleanPath(src, false)
	dst = CleanPath(dst, false)
	if src == dst {
		return
	}

	si, err := os.Stat(src)
	if err != nil {
		return err
	}
	if !si.IsDir() {
		return fmt.Errorf("source is not a directory")
	}

	_, err = os.Stat(dst)
	if err != nil && !os.IsNotExist(err) {
		return
	}
	if err == nil {
		return fmt.Errorf("destination already exists")
	}

	err = os.MkdirAll(dst, si.Mode())
	if err != nil {
		return
	}

	entries, err := ioutil.ReadDir(src)
	if err != nil {
		return
	}

	for _, entry := range entries {
		srcPath := path.Join(src, entry.Name())
		dstPath := path.Join(dst, entry.Name())

		if entry.IsDir() {
			err = CopyDir(srcPath, dstPath)
			if err != nil {
				return
			}
		} else {
			// Skip symlinks.
			if entry.Mode()&os.ModeSymlink != 0 {
				continue
			}

			_, err = CopyFile(srcPath, dstPath)
			if err != nil {
				return
			}
		}
	}

	return
}

func HashString(hasher, input interface{}) string {
	h, ok := hasher.(hash.Hash)
	if !ok {
		h = md5.New()
	}
	switch v := input.(type) {
	case []byte:
		h.Write(v)
	case string:
		h.Write([]byte(v))
	case io.Reader:
		io.Copy(h, v)
	}
	return hex.EncodeToString(h.Sum(nil))
}

func UnmarshalJSONFile(filename string, v interface{}) (err error) {
	f, err := os.Open(filename)
	if err != nil {
		return
	}
	defer f.Close()
	return json.NewDecoder(f).Decode(v)
}

func MarshalJSONFile(filename string, v interface{}) (err error) {
	f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
	if err != nil {
		return
	}
	defer f.Close()
	return json.NewEncoder(f).Encode(v)
}

func GetHttpJSON(url string, v interface{}) (err error) {
	resp, err := http.Get(url)
	if err != nil {
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		err = errors.New(resp.Status)
		return
	}

	err = json.NewDecoder(resp.Body).Decode(&v)
	return
}

func UnmarshalGobFile(filename string, v interface{}) (err error) {
	f, err := os.Open(filename)
	if err != nil {
		return
	}
	defer f.Close()
	return gob.NewDecoder(f).Decode(v)
}

func MarshalGobFile(filename string, v interface{}) (err error) {
	f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
	if err != nil {
		return
	}
	defer f.Close()
	return gob.NewEncoder(f).Encode(v)
}

func SplitByFirstByte(s string, c byte) (string, string) {
	for i, l := 0, len(s); i < l; i++ {
		if s[i] == c {
			return s[:i], s[i+1:]
		}
	}
	return s, ""
}

func SplitByLastByte(s string, c byte) (string, string) {
	for i := len(s) - 1; i >= 0; i-- {
		if s[i] == c {
			return s[:i], s[i+1:]
		}
	}
	return s, ""
}

func FileExt(filename string) (ext string) {
	for i := len(filename) - 1; i > 0; i-- {
		if filename[i] == '.' {
			ext = filename[i+1:]
			break
		}
	}
	return
}

func ParseLines(s string, keepEmptyLine bool) (lines []string) {
	for i, j, l := 0, 0, len(s); i < l; i++ {
		switch s[i] {
		case '\r', '\n':
			if i > j {
				lines = append(lines, s[j:i])
			} else if i == j && keepEmptyLine {
				lines = append(lines, "")
			}
			j = i + 1
			if s[i] == '\r' && i+1 < l && s[i+1] == '\n' {
				if i == l-2 && keepEmptyLine {
					lines = append(lines, "")
				}
				i++
				j++
			}
		default:
			if i == l-1 && j < l {
				lines = append(lines, s[j:])
			}
		}
	}
	return
}

func ToNumber(v interface{}) (f float64, ok bool) {
	ok = true
	switch i := v.(type) {
	case string:
		var err error
		f, err = strconv.ParseFloat(i, 64)
		if err != nil {
			ok = false
		}
	case int:
		f = float64(i)
	case int8:
		f = float64(i)
	case int16:
		f = float64(i)
	case int32:
		f = float64(i)
	case int64:
		f = float64(i)
	case uint:
		f = float64(i)
	case uint8:
		f = float64(i)
	case uint16:
		f = float64(i)
	case uint32:
		f = float64(i)
	case uint64:
		f = float64(i)
	case float32:
		f = float64(i)
	case float64:
		f = i
	default:
		ok = false
	}
	return
}

// PathClean has the same function with path.Clean(strings.Replace(strings.TrimSpace(s), "\\", "/", -1)),
// but it's faster!
func CleanPath(path string, toLower bool) string {
	pl := len(path)
	if pl == 0 {
		return "."
	}
	var n int
	var c byte
	var root bool
	var newpath = make([]byte, pl)
	for i := 0; i < pl; i++ {
		switch c = path[i]; c {
		case ' ':
			if n == 0 {
				continue
			}
			newpath[n] = ' '
			n++
		case '/', '\\':
			if n > 0 {
				if newpath[n-1] == '/' {
					continue
				} else if newpath[n-1] == '.' && n > 1 && newpath[n-2] == '/' {
					n--
					continue
				}
			}
			if n == 0 {
				root = true
			}
			newpath[n] = '/'
			n++
		case '.':
			if n > 1 && newpath[n-1] == '.' && newpath[n-2] == '/' {
				if n = n - 2; n > 0 {
					for n = n - 1; n > 0; n-- {
						if newpath[n] == '/' {
							break
						}
					}
				}
				continue
			}
			newpath[n] = '.'
			n++
		default:
			if toLower && c >= 'A' && c <= 'Z' {
				c += 32
			}
			newpath[n] = c
			n++
		}
	}
	// trim right spaces
	if n > 0 && newpath[n-1] == ' ' {
		for n > 0 && newpath[n-1] == ' ' {
			n--
		}
	}
	if n > 1 && newpath[n-1] == '.' && newpath[n-2] == '/' {
		n--
	}
	if n > 0 && newpath[n-1] == '/' && (!root || n > 1) {
		n--
	}
	if n == 0 {
		return "."
	}
	return string(newpath[:n])
}

func Ipv4ToLong(ipStr string) uint32 {
	ip := net.ParseIP(ipStr)
	if ip == nil {
		return 0
	}
	ip = ip.To4()
	return binary.BigEndian.Uint32(ip)
}

func LongToIpv4(ipLong uint32) string {
	ipByte := make([]byte, 4)
	binary.BigEndian.PutUint32(ipByte, ipLong)
	ip := net.IP(ipByte)
	return ip.String()
}

func GetLocalIps() (ips []string, err error) {
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		return
	}

	for _, addr := range addrs {
		if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
			if ipnet.IP.To4() != nil {
				ips = append(ips, ipnet.IP.String())
			}
		}
	}

	if len(ips) == 0 {
		err = errors.New("not found")
	}
	return
}
<commit_msg>remove CatchExit message<commit_after>package utils

import (
	"crypto/md5"
	"encoding/binary"
	"encoding/gob"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"hash"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"os/signal"
	"path"
	"strconv"
	"strings"
	"syscall"
)

var (
	exitWaiting   bool
	exitCallbacks []func()
)

func CatchExit(callback func()) {
	if callback == nil {
		return
	}
	exitCallbacks = append(exitCallbacks, callback)

	if exitWaiting {
		return
	}
	exitWaiting = true

	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGINT, syscall.SIGHUP, syscall.SIGQUIT)

		for {
			<-c
			for _, callback := range exitCallbacks {
				callback()
			}
			os.Exit(1)
		}
	}()
}

func Contains(items interface{}, item interface{}) (ok bool) {
	switch a := items.(type) {
	case string:
		if len(a) == 0 {
			return
		}
		sep, yes := item.(string)
		ok = yes && strings.Index(a, sep) > -1
		return
	case []string:
		if len(a) == 0 {
			return
		}
		s, yes := item.(string)
		if yes {
			for _, c := range a {
				if c == s {
					ok = true
					return
				}
			}
		}
		return
	case []int:
		if len(a) == 0 {
			return
		}
		i, yes := item.(int)
		if yes {
			for _, c := range a {
				if c == i {
					return true
				}
			}
		}
		return
	default:
		return
	}
}

func CopyFile(src string, dst string) (n int64, err error) {
	if src == dst {
		return
	}

	in, err := os.Open(src)
	if err != nil {
		return
	}
	defer in.Close()

	out, err := os.Create(dst)
	if err != nil {
		return
	}
	defer func() {
		if e := out.Close(); e != nil {
			err = e
		}
	}()

	n, err = io.Copy(out, in)
	if err != nil {
		return
	}

	err = out.Sync()
	if err != nil {
		return
	}

	si, err := os.Stat(src)
	if err != nil {
		return
	}
	err = os.Chmod(dst, si.Mode())
	if err != nil {
		return
	}

	return
}

func CopyDir(src string, dst string) (err error) {
	src = CleanPath(src, false)
	dst = CleanPath(dst, false)
	if src == dst {
		return
	}

	si, err := os.Stat(src)
	if err != nil {
		return err
	}
	if !si.IsDir() {
		return errors.New("source is not a directory")
	}

	_, err = os.Stat(dst)
	if err != nil && !os.IsNotExist(err) {
		return
	}
	if err == nil {
		return errors.New("destination already exists")
	}

	err = os.MkdirAll(dst, si.Mode())
	if err != nil {
		return
	}

	entries, err := ioutil.ReadDir(src)
	if err != nil {
		return
	}

	for _, entry := range entries {
		srcPath := path.Join(src, entry.Name())
		dstPath := path.Join(dst, entry.Name())

		if entry.IsDir() {
			err = CopyDir(srcPath, dstPath)
			if err != nil {
				return
			}
		} else {
			// Skip symlinks.
			if entry.Mode()&os.ModeSymlink != 0 {
				continue
			}

			_, err = CopyFile(srcPath, dstPath)
			if err != nil {
				return
			}
		}
	}

	return
}

func HashString(hasher, input interface{}) string {
	h, ok := hasher.(hash.Hash)
	if !ok {
		h = md5.New()
	}
	switch v := input.(type) {
	case []byte:
		h.Write(v)
	case string:
		h.Write([]byte(v))
	case io.Reader:
		io.Copy(h, v)
	}
	return hex.EncodeToString(h.Sum(nil))
}

func UnmarshalJSONFile(filename string, v interface{}) (err error) {
	f, err := os.Open(filename)
	if err != nil {
		return
	}
	defer f.Close()
	return json.NewDecoder(f).Decode(v)
}

func MarshalJSONFile(filename string, v interface{}) (err error) {
	f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
	if err != nil {
		return
	}
	defer f.Close()
	return json.NewEncoder(f).Encode(v)
}

func GetHttpJSON(url string, v interface{}) (err error) {
	resp, err := http.Get(url)
	if err != nil {
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		err = errors.New(resp.Status)
		return
	}

	err = json.NewDecoder(resp.Body).Decode(&v)
	return
}

func UnmarshalGobFile(filename string, v interface{}) (err error) {
	f, err := os.Open(filename)
	if err != nil {
		return
	}
	defer f.Close()
	return gob.NewDecoder(f).Decode(v)
}

func MarshalGobFile(filename string, v interface{}) (err error) {
	f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
	if err != nil {
		return
	}
	defer f.Close()
	return gob.NewEncoder(f).Encode(v)
}

func SplitByFirstByte(s string, c byte) (string, string) {
	for i, l := 0, len(s); i < l; i++ {
		if s[i] == c {
			return s[:i], s[i+1:]
		}
	}
	return s, ""
}

func SplitByLastByte(s string, c byte) (string, string) {
	for i := len(s) - 1; i >= 0; i-- {
		if s[i] == c {
			return s[:i], s[i+1:]
		}
	}
	return s, ""
}

func FileExt(filename string) (ext string) {
	for i := len(filename) - 1; i > 0; i-- {
		if filename[i] == '.' {
			ext = filename[i+1:]
			break
		}
	}
	return
}

func ParseLines(s string, keepEmptyLine bool) (lines []string) {
	for i, j, l := 0, 0, len(s); i < l; i++ {
		switch s[i] {
		case '\r', '\n':
			if i > j {
				lines = append(lines, s[j:i])
			} else if i == j && keepEmptyLine {
				lines = append(lines, "")
			}
			j = i + 1
			if s[i] == '\r' && i+1 < l && s[i+1] == '\n' {
				if i == l-2 && keepEmptyLine {
					lines = append(lines, "")
				}
				i++
				j++
			}
		default:
			if i == l-1 && j < l {
				lines = append(lines, s[j:])
			}
		}
	}
	return
}

func ToNumber(v interface{}) (f float64, ok bool) {
	ok = true
	switch i := v.(type) {
	case string:
		var err error
		f, err = strconv.ParseFloat(i, 64)
		if err != nil {
			ok = false
		}
	case int:
		f = float64(i)
	case int8:
		f = float64(i)
	case int16:
		f = float64(i)
	case int32:
		f = float64(i)
	case int64:
		f = float64(i)
	case uint:
		f = float64(i)
	case uint8:
		f = float64(i)
	case uint16:
		f = float64(i)
	case uint32:
		f = float64(i)
	case uint64:
		f = float64(i)
	case float32:
		f = float64(i)
	case float64:
		f = i
	default:
		ok = false
	}
	return
}

// PathClean has the same function with path.Clean(strings.Replace(strings.TrimSpace(s), "\\", "/", -1)),
// but it's faster!
func CleanPath(path string, toLower bool) string {
	pl := len(path)
	if pl == 0 {
		return "."
	}
	var n int
	var c byte
	var root bool
	var newpath = make([]byte, pl)
	for i := 0; i < pl; i++ {
		switch c = path[i]; c {
		case ' ':
			if n == 0 {
				continue
			}
			newpath[n] = ' '
			n++
		case '/', '\\':
			if n > 0 {
				if newpath[n-1] == '/' {
					continue
				} else if newpath[n-1] == '.' && n > 1 && newpath[n-2] == '/' {
					n--
					continue
				}
			}
			if n == 0 {
				root = true
			}
			newpath[n] = '/'
			n++
		case '.':
			if n > 1 && newpath[n-1] == '.' && newpath[n-2] == '/' {
				if n = n - 2; n > 0 {
					for n = n - 1; n > 0; n-- {
						if newpath[n] == '/' {
							break
						}
					}
				}
				continue
			}
			newpath[n] = '.'
			n++
		default:
			if toLower && c >= 'A' && c <= 'Z' {
				c += 32
			}
			newpath[n] = c
			n++
		}
	}
	// trim right spaces
	if n > 0 && newpath[n-1] == ' ' {
		for n > 0 && newpath[n-1] == ' ' {
			n--
		}
	}
	if n > 1 && newpath[n-1] == '.' && newpath[n-2] == '/' {
		n--
	}
	if n > 0 && newpath[n-1] == '/' && (!root || n > 1) {
		n--
	}
	if n == 0 {
		return "."
	}
	return string(newpath[:n])
}

func Ipv4ToLong(ipStr string) uint32 {
	ip := net.ParseIP(ipStr)
	if ip == nil {
		return 0
	}
	ip = ip.To4()
	return binary.BigEndian.Uint32(ip)
}

func LongToIpv4(ipLong uint32) string {
	ipByte := make([]byte, 4)
	binary.BigEndian.PutUint32(ipByte, ipLong)
	ip := net.IP(ipByte)
	return ip.String()
}

func GetLocalIps() (ips []string, err error) {
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		return
	}

	for _, addr := range addrs {
		if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
			if ipnet.IP.To4() != nil {
				ips = append(ips, ipnet.IP.String())
			}
		}
	}

	if len(ips) == 0 {
		err = errors.New("not found")
	}
	return
}
<|endoftext|>


<commit_before>package utils

import (
	"encoding/csv"
	"fmt"
	"io"
	"math"
	"math/big"
	"os"
)

//WriteMsg - Just a wrapper of fmt.Print()
func WriteMsg(s string) {
	fmt.Println(s)
}

// DecodeDecimal - What the Hell
func DecodeDecimal(b []byte, m *big.Int) (bool, int) {

	//bigint word size (*--> src/pkg/math/big/arith.go)
	const (
		dec128Bias = 6176
		// Compute the size _S of a Word in bytes.
		_m    = ^big.Word(0)
		_logS = _m>>8&1 + _m>>16&1 + _m>>32&1
		_S    = 1 << _logS
	)

	neg := (b[15] & 0x80) != 0
	exp := int((((uint16(b[15])<<8)|uint16(b[14]))<<1)>>2) - dec128Bias

	b14 := b[14]  // save b[14]
	b[14] &= 0x01 // keep the mantissa bit (rest: sign and exp)

	//most significand byte
	msb := 14
	for msb > 0 {
		if b[msb] != 0 {
			break
		}
		msb--
	}

	//calc number of words
	numWords := (msb / _S) + 1
	w := make([]big.Word, numWords)

	k := numWords - 1
	d := big.Word(0)
	for i := msb; i >= 0; i-- {
		d |= big.Word(b[i])
		if k*_S == i {
			w[k] = d
			k--
			d = 0
		}
		d <<= 8
	}
	b[14] = b14 // restore b[14]
	m.SetBits(w)
	return neg, exp
}

// BigIntToFloat - Convert to float
func BigIntToFloat(sign bool, m *big.Int, exp int) float64 {
	var neg int64
	if sign {
		neg = -1
	} else {
		neg = 1
	}

	return float64(neg*m.Int64()) * math.Pow10(exp)
}

// ReadCsv - Read CSV file and return as string slice
func ReadCsv(f string, comma rune) (rec [][]string, count int) {
	file, err := os.Open(f)
	if err != nil {
		fmt.Println("Error: ", err)
		return
	}
	defer file.Close()

	reader := csv.NewReader(file)
	reader.Comma = comma

	lineCount := 0

	var WholeRecord [][]string

	for {
		record, err := reader.Read()
		if err == io.EOF {
			break
		} else if err != nil {
			fmt.Println("Error: ", err)
			return
		}
		lineCount++
		WholeRecord = append(WholeRecord, record)
	}
	return WholeRecord, lineCount
}
<commit_msg>removed to new folder (follow go vendor suggestion)<commit_after><|endoftext|>


<commit_before>// Package utils provides useful helper functions for working with Images and
// Colors.
package utils

import (
	"fmt"
	"os"
	"flag"

	"image"
	"image/png"
	"image/color"

	_ "image/jpeg"
	_ "image/gif"
)

// ReadStdin reads an image file from standard input.
func ReadStdin() image.Image {
	img, _, _ := image.Decode(os.Stdin)

	return img
}

// WriteStdout writes an Image to standard output.
func WriteStdout(img image.Image) {
	png.Encode(os.Stdout, img)
}

// Warn prints a message to standard error
func Warn(s... interface{}) {
	fmt.Fprintln(os.Stderr, s...)
}

// NormalisedRGBA returns the RGBA colour channel values of a Color in a
// normalised form.
func NormalisedRGBA(c color.Color) (rn, gn, bn, an uint32) {
	d := color.NRGBAModel.Convert(c).(color.NRGBA)
	r := d.R; g := d.G; b := d.B; a := d.A

	// Need to do some crazy type conversions first
	rn = uint32(uint8(r))
	gn = uint32(uint8(g))
	bn = uint32(uint8(b))
	an = uint32(uint8(a))

	return
}

// NormalisedRGBAf returns the RGBA colour channel values as floating point
// numbers with values from 0 to 255.
func NormalisedRGBAf(c color.Color) (rn, gn, bn, an float64) {
	r, g, b, a := NormalisedRGBA(c)

	rn = float64(r)
	gn = float64(g)
	bn = float64(b)
	an = float64(a)

	return
}

// RatioRGBA returns the RGBA colour channel values as floating point numbers
// with values from 0 to 1.
func RatioRGBA(c color.Color) (rn, gn, bn, an float64) {
	r, g, b, a := NormalisedRGBAf(c)

	rn = r / 255
	gn = g / 255
	bn = b / 255
	an = a / 255

	return
}

// Truncate takes a colour channel value and forces it into the range 0 to 255
// by setting any value below 0 to 0 and and any above 255 to 255.
func Truncate(n uint32) uint32 {
	if n < 0 { return 0 } else if n > 255 { return 255 }
	return n
}

// Truanctef is identical to Truncate but takes and returns a float64.
func Truncatef(n float64) float64 {
	if n < 0 { return 0 } else if n > 255 { return 255 }
	return n
}

// Closeness calculates the "closeness" of two colours by finding the sum of
// differences in each colour channel.
func Closeness(one, two color.Color) uint32 {
	a, b, c, d := NormalisedRGBA(one)
	w, x, y, z := NormalisedRGBA(two)

	return (a - w) + (b - x) + (c - y) + (d - z)
}

// Average takes a list of colours and returns the average.
func Average(cs... color.Color) color.Color {
	var red, green, blue, alpha uint32
	red = 0; green = 0; blue = 0; alpha = 0

	for i := 0; i < len(cs); i++ {
		r, g, b, a := NormalisedRGBA(cs[i])

		red += r; green += g; blue += b; alpha += a
	}

	return color.NRGBA{
		uint8(red   / uint32(len(cs))),
		uint8(green / uint32(len(cs))),
		uint8(blue  / uint32(len(cs))),
		uint8(alpha / uint32(len(cs))),
	}
}

// Min returns the smallest value in the list of uint32s given.
func Min(ns... uint32) (n uint32) {
	if len(ns) > 0 {
		n = ns[0]
	}
	for i := 1; i < len(ns); i++ {
		if ns[i] < n {
			n = ns[i]
		}
	}
	return
}

// Minf returns the smallest value in the list of float64s given.
func Minf(ns... float64) (n float64) {
	if len(ns) > 0 {
		n = ns[0]
	}
	for i := 1; i < len(ns); i++ {
		if ns[i] < n {
			n = ns[i]
		}
	}
	return
}

// Max returns the largest value in the list of uint32s given.
func Max(ns... uint32) (n uint32) {
	if len(ns) > 0 {
		n = ns[0]
	}
	for i := 1; i < len(ns); i++ {
		if ns[i] > n {
			n = ns[i]
		}
	}
	return
}

// Maxf returns the largest value in the list of float64s given.
func Maxf(ns... float64) (n float64) {
	if len(ns) > 0 {
		n = ns[0]
	}
	for i := 1; i < len(ns); i++ {
		if ns[i] > n {
			n = ns[i]
		}
	}
	return
}

// EachColor iterates through each pixel of the Image, applying the function
// to each colour.
func EachColor(img image.Image, f func(c color.Color)) {
	b := img.Bounds()

	for y := b.Min.Y; y < b.Max.Y; y++ {
		for x := b.Min.X; x < b.Max.X; x++ {
			f(img.At(x, y))
		}
	}
}

// MapColor iterates through each pixel of the Image and applies the given
// function, drawing the returned colour to a new Image which is then returned.
func MapColor(img image.Image, f func(c color.Color) color.Color) image.Image {
	b := img.Bounds()
	o := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))

	for y := b.Min.Y; y < b.Max.Y; y++ {
		for x := b.Min.X; x < b.Max.X; x++ {
			result := f(img.At(x, y))
			o.Set(x, y, result)
		}
	}

	return o
}

func FlagVisited(name string, flags flag.FlagSet) bool {
	didFind := false
	toFind  := flags.Lookup(name)

	flags.Visit(func (f *flag.Flag) {
		if f == toFind {
			didFind = true
		}
	})

	return didFind
}

// Adjuster is a function which takes a floating point value, most likely
// between 0 and 1, and returns another floating point value, again between 0
// and 1 (though this is not a requirement).
type Adjuster func (float64) float64

// Adder returns an Adjuster which adds the value with to the returned Adjusters
// argument.
func Adder(with float64) Adjuster {
	return func(i float64) float64 {
		return i + with
	}
}

// Multiplier returns an Adjuster which multiplies a given value with ratio.
func Multiplier(ratio float64) Adjuster {
	return func(i float64) float64 {
		return i * ratio
	}
}

// Composable is a function which can be composed with another function of the
// same type. It transforms a Color into another Color.
type Composable func(color.Color) color.Color

// Map takes a Composable function, and returns a function which acts on Images.
func Map(f func() Composable) func(image.Image) image.Image {
	return func(img image.Image) image.Image {
		return MapColor(img, f())
	}
}

// MapAdjuster takes a Composable function and an Adjuster, and returns a
// function which acts on Images.
func MapAdjuster(f func(Adjuster) Composable) func(image.Image, Adjuster) image.Image {
	return func(img image.Image, adj Adjuster) image.Image {
		return MapColor(img, f(adj))
	}
}

// Compose takes a variable list of Composable functions and returns a single
// Composable function which performs each of them sequentially. For example,
//
//   var f Composable = Compose(
//     greyscale.BlueC(),
//     brightness.AdjustC(utils.Adder(0.05)),
//   )
//
//   // Only loops through image once!
//   img = MapColors(img, f)
//
func Compose(fs... Composable) Composable {
	return func(c color.Color) color.Color {
		for _, f := range fs {
			c = f(c)
		}
		return c
	}
}
<commit_msg>Parallelised MapColor function.<commit_after>// Package utils provides useful helper functions for working with Images and
// Colors.
package utils

import (
	"flag"
	"fmt"
	"os"
	"runtime"

	"image"
	"image/color"
	"image/draw"

	"image/png"
	_ "image/jpeg"
	_ "image/gif"
)

// ReadStdin reads an image file from standard input.
func ReadStdin() image.Image {
	img, _, _ := image.Decode(os.Stdin)

	return img
}

// WriteStdout writes an Image to standard output.
func WriteStdout(img image.Image) {
	png.Encode(os.Stdout, img)
}

// Warn prints a message to standard error
func Warn(s... interface{}) {
	fmt.Fprintln(os.Stderr, s...)
}

// NormalisedRGBA returns the RGBA colour channel values of a Color in a
// normalised form.
func NormalisedRGBA(c color.Color) (rn, gn, bn, an uint32) {
	d := color.NRGBAModel.Convert(c).(color.NRGBA)
	r := d.R; g := d.G; b := d.B; a := d.A

	// Need to do some crazy type conversions first
	rn = uint32(uint8(r))
	gn = uint32(uint8(g))
	bn = uint32(uint8(b))
	an = uint32(uint8(a))

	return
}

// NormalisedRGBAf returns the RGBA colour channel values as floating point
// numbers with values from 0 to 255.
func NormalisedRGBAf(c color.Color) (rn, gn, bn, an float64) {
	r, g, b, a := NormalisedRGBA(c)

	rn = float64(r)
	gn = float64(g)
	bn = float64(b)
	an = float64(a)

	return
}

// RatioRGBA returns the RGBA colour channel values as floating point numbers
// with values from 0 to 1.
func RatioRGBA(c color.Color) (rn, gn, bn, an float64) {
	r, g, b, a := NormalisedRGBAf(c)

	rn = r / 255
	gn = g / 255
	bn = b / 255
	an = a / 255

	return
}

// Truncate takes a colour channel value and forces it into the range 0 to 255
// by setting any value below 0 to 0 and and any above 255 to 255.
func Truncate(n uint32) uint32 {
	if n < 0 { return 0 } else if n > 255 { return 255 }
	return n
}

// Truanctef is identical to Truncate but takes and returns a float64.
func Truncatef(n float64) float64 {
	if n < 0 { return 0 } else if n > 255 { return 255 }
	return n
}

// Closeness calculates the "closeness" of two colours by finding the sum of
// differences in each colour channel.
func Closeness(one, two color.Color) uint32 {
	a, b, c, d := NormalisedRGBA(one)
	w, x, y, z := NormalisedRGBA(two)

	return (a - w) + (b - x) + (c - y) + (d - z)
}

// Average takes a list of colours and returns the average.
func Average(cs... color.Color) color.Color {
	var red, green, blue, alpha uint32
	red = 0; green = 0; blue = 0; alpha = 0

	for i := 0; i < len(cs); i++ {
		r, g, b, a := NormalisedRGBA(cs[i])

		red += r; green += g; blue += b; alpha += a
	}

	return color.NRGBA{
		uint8(red   / uint32(len(cs))),
		uint8(green / uint32(len(cs))),
		uint8(blue  / uint32(len(cs))),
		uint8(alpha / uint32(len(cs))),
	}
}

// Min returns the smallest value in the list of uint32s given.
func Min(ns... uint32) (n uint32) {
	if len(ns) > 0 {
		n = ns[0]
	}
	for i := 1; i < len(ns); i++ {
		if ns[i] < n {
			n = ns[i]
		}
	}
	return
}

// Minf returns the smallest value in the list of float64s given.
func Minf(ns... float64) (n float64) {
	if len(ns) > 0 {
		n = ns[0]
	}
	for i := 1; i < len(ns); i++ {
		if ns[i] < n {
			n = ns[i]
		}
	}
	return
}

// Max returns the largest value in the list of uint32s given.
func Max(ns... uint32) (n uint32) {
	if len(ns) > 0 {
		n = ns[0]
	}
	for i := 1; i < len(ns); i++ {
		if ns[i] > n {
			n = ns[i]
		}
	}
	return
}

// Maxf returns the largest value in the list of float64s given.
func Maxf(ns... float64) (n float64) {
	if len(ns) > 0 {
		n = ns[0]
	}
	for i := 1; i < len(ns); i++ {
		if ns[i] > n {
			n = ns[i]
		}
	}
	return
}

// EachColor iterates through each pixel of the Image, applying the function
// to each colour.
func EachColor(img image.Image, f func(c color.Color)) {
	b := img.Bounds()

	for y := b.Min.Y; y < b.Max.Y; y++ {
		for x := b.Min.X; x < b.Max.X; x++ {
			f(img.At(x, y))
		}
	}
}

// MapColor iterates through each pixel of the Image and applies the given
// function, drawing the returned colour to a new Image which is then returned.
func MapColor(img image.Image, f Composable) image.Image {
	// Use maximum number of CPUs available
	nCPU := runtime.NumCPU()
	runtime.GOMAXPROCS(nCPU)

	o := image.NewRGBA(img.Bounds())
	b := img.Bounds()
	w := b.Dx()

	subWidth  := w / nCPU
	lastWidth := subWidth + (w % nCPU)

	for c := 0; c < nCPU; c++ {
		if c < nCPU - 1 {
			rect := image.Rect(c * subWidth, b.Min.Y, (c+1) * subWidth, b.Max.Y)
			go subMapColor(img, f, o, rect)
		} else {
			rect := image.Rect(c * subWidth, b.Min.Y, c * subWidth + lastWidth, b.Max.Y)
			go subMapColor(img, f, o, rect)
		}
	}

	return o
}

// subMapColor is a helper function for working on part of an image. It takes
// the original image, a function to use, a image to write to, and the bounds of
// the original (and therefore the final image) to act upon.
func subMapColor(img image.Image, f Composable, dest draw.Image, bounds image.Rectangle) {
	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			dest.Set(x, y, f(img.At(x, y)))
		}
	}
}

func FlagVisited(name string, flags flag.FlagSet) bool {
	didFind := false
	toFind  := flags.Lookup(name)

	flags.Visit(func (f *flag.Flag) {
		if f == toFind {
			didFind = true
		}
	})

	return didFind
}

// Adjuster is a function which takes a floating point value, most likely
// between 0 and 1, and returns another floating point value, again between 0
// and 1 (though this is not a requirement).
type Adjuster func (float64) float64

// Adder returns an Adjuster which adds the value with to the returned Adjusters
// argument.
func Adder(with float64) Adjuster {
	return func(i float64) float64 {
		return i + with
	}
}

// Multiplier returns an Adjuster which multiplies a given value with ratio.
func Multiplier(ratio float64) Adjuster {
	return func(i float64) float64 {
		return i * ratio
	}
}

// Composable is a function which can be composed with another function of the
// same type. It transforms a Color into another Color.
type Composable func(color.Color) color.Color

// Map takes a Composable function, and returns a function which acts on Images.
func Map(f func() Composable) func(image.Image) image.Image {
	return func(img image.Image) image.Image {
		return MapColor(img, f())
	}
}

// MapAdjuster takes a Composable function and an Adjuster, and returns a
// function which acts on Images.
func MapAdjuster(f func(Adjuster) Composable) func(image.Image, Adjuster) image.Image {
	return func(img image.Image, adj Adjuster) image.Image {
		return MapColor(img, f(adj))
	}
}

// Compose takes a variable list of Composable functions and returns a single
// Composable function which performs each of them sequentially. For example,
//
//   var f Composable = Compose(
//     greyscale.BlueC(),
//     brightness.AdjustC(utils.Adder(0.05)),
//   )
//
//   // Only loops through image once!
//   img = MapColors(img, f)
//
func Compose(fs... Composable) Composable {
	return func(c color.Color) color.Color {
		for _, f := range fs {
			c = f(c)
		}
		return c
	}
}
<|endoftext|>


<commit_before>package butler

import (
	"os"
	"runtime"
	"strings"

	"go.aduro.hr/kmislav/alog"
)

var logger *alog.Logger

func SetLogger(llogger *alog.Logger) {
	logger = llogger
}

func UserHomeDir() string {
	if runtime.GOOS == "windows" {
		home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
		if home == "" {
			home = os.Getenv("USERPROFILE")
		}
		return home
	}
	// fmt.Println(os.Getenv("HOME"))
	return os.Getenv("HOME")
}

//Trims whitespace and new line chars
func strip(v string) string {
	return strings.TrimSpace(strings.Trim(v, "\n"))
}
<commit_msg>{NW} Changed log dependency to go.aduro.hr/alog<commit_after>package butler

import (
	"os"
	"runtime"
	"strings"

	"go.aduro.hr/alog"
)

var logger *alog.Logger

func SetLogger(llogger *alog.Logger) {
	logger = llogger
}

func UserHomeDir() string {
	if runtime.GOOS == "windows" {
		home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
		if home == "" {
			home = os.Getenv("USERPROFILE")
		}
		return home
	}
	// fmt.Println(os.Getenv("HOME"))
	return os.Getenv("HOME")
}

//Trims whitespace and new line chars
func strip(v string) string {
	return strings.TrimSpace(strings.Trim(v, "\n"))
}
<|endoftext|>


<commit_before>package atlas

import (
	"fmt"
	"reflect"
	"strconv"
)

// FillDefinition set a few parameters in a definition list
/*
The goal here is to give a dictionary of string and let it figure out each field's type
depending on the recipient's type in the struct.
*/
func FillDefinition(d *Definition, fields map[string]string) error {
	if d == nil {
		return nil
	}
	sdef := reflect.ValueOf(d).Elem()
	typeOfDef := sdef.Type()
	for k, v := range fields {
		// Check the field is present
		if f, ok := typeOfDef.FieldByName(k); ok {
			// Use the right type
			switch f.Type.Name() {
			case "float":
				vf, _ := strconv.ParseFloat(v, 32)
				sdef.FieldByName(k).SetFloat(vf)
			case "int":
				vi, _ := strconv.ParseInt(v, 10, 32)
				sdef.FieldByName(k).SetInt(vi)
			case "string":
				sdef.FieldByName(k).SetString(v)
			case "bool":
				vb, _ := strconv.ParseBool(v)
				sdef.FieldByName(k).SetBool(vb)
			default:
				return fmt.Errorf("Unsupported type: %s", f.Type.Name())
			}
		}
	}
	return nil
}
<commit_msg>Support arrays for FillDefinition().<commit_after>package atlas

import (
	"fmt"
	"log"
	"reflect"
	"strconv"
	"strings"
)

// FillDefinition set a few parameters in a definition list
/*
The goal here is to give a dictionary of string and let it figure out each field's type
depending on the recipient's type in the struct.
*/
func FillDefinition(d *Definition, fields map[string]string) error {
	if d == nil {
		return nil
	}
	sdef := reflect.ValueOf(d).Elem()
	typeOfDef := sdef.Type()
	for k, v := range fields {
		// Check the field is present
		if f, ok := typeOfDef.FieldByName(k); ok {
			log.Printf("k=%s type=%s-%s", k, f.Type.Name(), f.Type.Kind().String())
			// Use the right type
			switch f.Type.Name() {
			case "float":
				vf, _ := strconv.ParseFloat(v, 32)
				sdef.FieldByName(k).SetFloat(vf)
			case "int":
				vi, _ := strconv.ParseInt(v, 10, 32)
				sdef.FieldByName(k).SetInt(vi)
			case "string":
				sdef.FieldByName(k).SetString(v)
			case "bool":
				vb, _ := strconv.ParseBool(v)
				sdef.FieldByName(k).SetBool(vb)
			case "":
				if f.Type.Kind().String() == "slice" {
					// Special case for "tags" which is an array, not a scalar
					a := strings.Split(v, ",")
					sdef.FieldByName(k).Set(reflect.ValueOf(a))
				}
			default:
				return fmt.Errorf("Unsupported type: %s", f.Type.Name())
			}
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package gopac

import (
	"net"
	"os"
	"regexp"
	"strings"

	"github.com/robertkrimen/otto"
)

const dnsServer = "8.8.8.8:53"

// isPlainHostName return true if there is no domain name in the host.
func isPlainHostName(host string) bool {
	return strings.Index(host, ".") == -1
}

// dnsDomainIs return true if the host is valid for the domain.
func dnsDomainIs(host, domain string) bool {
	if len(host) < len(domain) {
		return false
	}

	return strings.HasSuffix(host, domain)
}

// localHostOrDomainIs returns true if the host matches the specified hostdom,
// or if there is no domain name part in the host, but the unqualified hostdom
// matches.
func localHostOrDomainIs(host, hostdom string) bool {
	if host == hostdom {
		return true
	}

	return strings.LastIndex(hostdom, host+".") == 0
}

// isResolvable returns true if the host is resolvable.
func isResolvable(host string) bool {
	if len(host) == 0 {
		return false
	}

	if _, err := net.ResolveIPAddr("ip4", host); err != nil {
		return false
	}

	return true
}

// isInNet returns true if the IP address of the host matches the specified IP
// address pattern.
// mask is the pattern informing which parts of the IP address to match against.
// 0 means ignore, 255 means match.
func isInNet(host, pattern, mask string) bool {
	if len(host) == 0 {
		return false
	}

	address, err := net.ResolveIPAddr("ip4", host)

	if err != nil {
		return false
	}

	maskIp := net.IPMask(net.ParseIP(mask))
	return address.IP.Mask(maskIp).String() == pattern
}

// dnsResolve returns the IP address of the host.
func dnsResolve(host string) string {
	address, err := net.ResolveIPAddr("ip4", host)

	if err != nil {
		return ""
	}

	return address.String()
}

// myIpAddress returns the IP address of the host machine.
func myIpAddress() otto.Value {
	hostname, err := os.Hostname()

	if err != nil {
		return otto.UndefinedValue()
	}

	address := dnsResolve(hostname)

	if value, err := otto.ToValue(address); err == nil {
		return value
	}

	return otto.UndefinedValue()
}

// dnsDomainLevels returns the number of domain levels in the host.
func dnsDomainLevels(host string) int {
	return strings.Count(host, ".")
}

// shExpMatch returns true if the string matches the specified shell expression.
func shExpMatch(str, shexp string) bool {
	shexp = strings.Replace(shexp, ".", "\\.", -1)
	shexp = strings.Replace(shexp, "?", ".?", -1)
	shexp = strings.Replace(shexp, "*", ".*", -1)
	matched, err := regexp.MatchString(shexp, "^"+str+"$")

	return err == nil && matched
}
<commit_msg>feature(weekdayRange): add built-in weekdayRange function<commit_after>package gopac

import (
	"net"
	"os"
	"regexp"
	"strings"
	"time"

	"github.com/robertkrimen/otto"
)

const dnsServer = "8.8.8.8:53"

var weekDays = map[string]time.Weekday{
	"SUN": time.Sunday,
	"MON": time.Monday,
	"TUE": time.Tuesday,
	"WED": time.Wednesday,
	"THU": time.Thursday,
	"FRI": time.Friday,
	"SAT": time.Saturday,
}

// isPlainHostName return true if there is no domain name in the host.
func isPlainHostName(host string) bool {
	return strings.Index(host, ".") == -1
}

// dnsDomainIs return true if the host is valid for the domain.
func dnsDomainIs(host, domain string) bool {
	if len(host) < len(domain) {
		return false
	}

	return strings.HasSuffix(host, domain)
}

// localHostOrDomainIs returns true if the host matches the specified hostdom,
// or if there is no domain name part in the host, but the unqualified hostdom
// matches.
func localHostOrDomainIs(host, hostdom string) bool {
	if host == hostdom {
		return true
	}

	return strings.LastIndex(hostdom, host+".") == 0
}

// isResolvable returns true if the host is resolvable.
func isResolvable(host string) bool {
	if len(host) == 0 {
		return false
	}

	if _, err := net.ResolveIPAddr("ip4", host); err != nil {
		return false
	}

	return true
}

// isInNet returns true if the IP address of the host matches the specified IP
// address pattern.
// mask is the pattern informing which parts of the IP address to match against.
// 0 means ignore, 255 means match.
func isInNet(host, pattern, mask string) bool {
	if len(host) == 0 {
		return false
	}

	address, err := net.ResolveIPAddr("ip4", host)

	if err != nil {
		return false
	}

	maskIp := net.IPMask(net.ParseIP(mask))
	return address.IP.Mask(maskIp).String() == pattern
}

// dnsResolve returns the IP address of the host.
func dnsResolve(host string) string {
	address, err := net.ResolveIPAddr("ip4", host)

	if err != nil {
		return ""
	}

	return address.String()
}

// myIpAddress returns the IP address of the host machine.
func myIpAddress() otto.Value {
	hostname, err := os.Hostname()

	if err != nil {
		return otto.UndefinedValue()
	}

	address := dnsResolve(hostname)

	if value, err := otto.ToValue(address); err == nil {
		return value
	}

	return otto.UndefinedValue()
}

// dnsDomainLevels returns the number of domain levels in the host.
func dnsDomainLevels(host string) int {
	return strings.Count(host, ".")
}

// shExpMatch returns true if the string matches the specified shell expression.
func shExpMatch(str, shexp string) bool {
	shexp = strings.Replace(shexp, ".", "\\.", -1)
	shexp = strings.Replace(shexp, "?", ".?", -1)
	shexp = strings.Replace(shexp, "*", ".*", -1)
	matched, err := regexp.MatchString(shexp, "^"+str+"$")

	return err == nil && matched
}

// weekdayRange returns true if the current weekday is between wd1 and wd2.
// If wd2 is unspecified, weekdayRange returns true if the weekday matches wd1.
func weekdayRange(wd1, wd2, gmt string) bool {
	if _, ok := weekDays[wd1]; !ok {
		return false
	}

	if wd2 == "GMT" {
		gmt = wd2
		wd2 = ""
	}

	now := time.Now()

	if gmt == "GMT" {
		now = now.UTC()
	}

	if wd2 == "" {
		return now.Weekday() == weekDays[wd1]
	}

	if weekDays[wd1] > weekDays[wd2] {
		weekDay1 := weekDays[wd1]
		weekDays[wd2] = weekDays[wd1]
		weekDays[wd1] = weekDay1
	}

	return weekDays[wd1] <= now.Weekday() && weekDays[wd2] >= now.Weekday()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"

	"github.com/hagen1778/chproxy/log"
)

func doQuery(query, addr string) error {
	resp, err := http.Post(fmt.Sprintf("%s/?query=%s", addr, url.QueryEscape(query)), "", nil)
	if err != nil {
		return fmt.Errorf("error in clickhouse query %q at %q: %s", query, addr, err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		responseBody, _ := ioutil.ReadAll(resp.Body)
		return fmt.Errorf("unexpected status code returned from query %q at %q: %d. Expecting %d. Response body: %q",
			query, addr, resp.StatusCode, http.StatusOK, responseBody)
	}
	return nil
}

func respondWithErr(rw http.ResponseWriter, err error) {
	log.Errorf("proxy failed: %s", err)
	rw.WriteHeader(http.StatusInternalServerError)
	rw.Write([]byte(err.Error()))
}

func extractUserFromRequest(req *http.Request) string {
	if name, _, ok := req.BasicAuth(); ok {
		return name
	}

	if name := req.Form.Get("user"); name != "" {
		return name
	}

	return "default"
}
<commit_msg>add timeout for clickhouse query<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"time"

	"github.com/hagen1778/chproxy/log"
)

var client = &http.Client{
	Timeout: time.Second * 60,
}

func doQuery(query, addr string) error {
	resp, err := client.Post(fmt.Sprintf("%s/?query=%s", addr, url.QueryEscape(query)), "", nil)
	if err != nil {
		return fmt.Errorf("error while executing clickhouse query %q at %q: %s", query, addr, err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		responseBody, _ := ioutil.ReadAll(resp.Body)
		return fmt.Errorf("unexpected status code returned from query %q at %q: %d. Expecting %d. Response body: %q",
			query, addr, resp.StatusCode, http.StatusOK, responseBody)
	}
	return nil
}

func respondWithErr(rw http.ResponseWriter, err error) {
	log.Errorf("proxy failed: %s", err)
	rw.WriteHeader(http.StatusInternalServerError)
	rw.Write([]byte(err.Error()))
}

func extractUserFromRequest(req *http.Request) string {
	if name, _, ok := req.BasicAuth(); ok {
		return name
	}

	if name := req.Form.Get("user"); name != "" {
		return name
	}

	return "default"
}
<|endoftext|>


<commit_before>package main

import (
	"container/list"
	"fmt"
	"strings"
	"time"
	"unicode"
)

func stripSpaces(s string) string {
	return strings.Map(func(r rune) rune {
		if unicode.IsSpace(r) {
			return -1
		}
		return r
	}, s)
}

//lists can't be marshalled to json objects as easily
func nodesListToSlice(l *list.List) []toxNode {
	nodes := make([]toxNode, nodesList.Len())

	i := 0
	for e := nodesList.Front(); e != nil; e = e.Next() {
		node, _ := e.Value.(*toxNode)
		//while we're at it, let's update the last ping string!
		if node.LastPing != 0 {
			node.LastPingString = getSimpleDurationFormat(time.Now().Sub(time.Unix(node.LastPing, 0)))
		}
		nodes[i] = *node
		i++
	}

	return nodes
}

func getSimpleDurationFormat(duration time.Duration) string {
	hours := duration.Hours()

	if hours >= 24 {
		return fmt.Sprintf("%0.0f days", hours/24)
	} else if hours > 1 {
		return fmt.Sprintf("%0.0f hours", hours)
	} else if hours*60 > 1 {
		return fmt.Sprintf("%0.0f minutes", hours*60)
	}

	return fmt.Sprintf("%0.0f seconds", hours*60*60)
}
<commit_msg>Changed getSimpleDurationFormat to distinguish between plural and non plural<commit_after>package main

import (
	"container/list"
	"fmt"
	"strings"
	"time"
	"unicode"
)

func stripSpaces(s string) string {
	return strings.Map(func(r rune) rune {
		if unicode.IsSpace(r) {
			return -1
		}
		return r
	}, s)
}

//lists can't be marshalled to json objects as easily
func nodesListToSlice(l *list.List) []toxNode {
	nodes := make([]toxNode, nodesList.Len())

	i := 0
	for e := nodesList.Front(); e != nil; e = e.Next() {
		node, _ := e.Value.(*toxNode)
		//while we're at it, let's update the last ping string!
		if node.LastPing != 0 {
			node.LastPingString = getSimpleDurationFormat(time.Now().Sub(time.Unix(node.LastPing, 0)))
		}
		nodes[i] = *node
		i++
	}

	return nodes
}

func getSimpleDurationFormat(duration time.Duration) string {
	hours := duration.Hours()
	var format string

	if hours >= 24 {
		format = fmt.Sprintf("%.0f day", hours/24)
	} else if hours > 1 {
		format = fmt.Sprintf("%.0f hour", hours)
	} else if hours*60 > 1 {
		format = fmt.Sprintf("%.0f minute", hours*60)
	} else {
		format = fmt.Sprintf("%.0f second", hours*60*60)
	}

	if strings.Split(format, " ")[0] != "1" {
		format += "s"
	}

	return format
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"path/filepath"
)

func panicIf(err error) {
	if err != nil {
		panic(err.Error())
	}
}

// currentFolderName returns the folder name
// of the current working directory
func currentFolderName() string {
	dir, err := os.Getwd()
	panicIf(err)
	return filepath.Base(dir)
}
<commit_msg>Pass error struct to panic instead of error message<commit_after>package main

import (
	"os"
	"path/filepath"
)

func panicIf(err error) {
	if err != nil {
		panic(err)
	}
}

// currentFolderName returns the folder name
// of the current working directory
func currentFolderName() string {
	dir, err := os.Getwd()
	panicIf(err)
	return filepath.Base(dir)
}
<|endoftext|>


<commit_before>package cors

import "strings"

const toLower = 'a' - 'A'

type converter func(string) string

type wildcard struct {
	prefix string
	suffix string
}

func (w wildcard) match(s string) bool {
	return len(s) >= len(w.prefix)+len(w.suffix) && strings.HasPrefix(s, w.prefix) && strings.HasSuffix(s, w.suffix)
}

// convert converts a list of string using the passed converter function
func convert(s []string, c converter) []string {
	out := []string{}
	for _, i := range s {
		out = append(out, c(i))
	}
	return out
}

// parseHeaderList tokenize + normalize a string containing a list of headers
func parseHeaderList(headerList string) []string {
	l := len(headerList)
	h := make([]byte, 0, l)
	upper := true
	// Estimate the number headers in order to allocate the right splice size
	t := 0
	for i := 0; i < l; i++ {
		if headerList[i] == ',' {
			t++
		}
	}
	headers := make([]string, 0, t)
	for i := 0; i < l; i++ {
		b := headerList[i]
		switch {
		case b >= 'a' && b <= 'z':
			if upper {
				h = append(h, b-toLower)
			} else {
				h = append(h, b)
			}
		case b >= 'A' && b <= 'Z':
			if !upper {
				h = append(h, b+toLower)
			} else {
				h = append(h, b)
			}
		case b == '-' || b == '_' || (b >= '0' && b <= '9'):
			h = append(h, b)
		}

		if b == ' ' || b == ',' || i == l-1 {
			if len(h) > 0 {
				// Flush the found header
				headers = append(headers, string(h))
				h = h[:0]
				upper = true
			}
		} else {
			upper = b == '-' || b == '_'
		}
	}
	return headers
}
<commit_msg>Fix[RFC_7230] RFC-7230 compliance (#103)<commit_after>package cors

import "strings"

const toLower = 'a' - 'A'

type converter func(string) string

type wildcard struct {
	prefix string
	suffix string
}

func (w wildcard) match(s string) bool {
	return len(s) >= len(w.prefix)+len(w.suffix) && strings.HasPrefix(s, w.prefix) && strings.HasSuffix(s, w.suffix)
}

// convert converts a list of string using the passed converter function
func convert(s []string, c converter) []string {
	out := []string{}
	for _, i := range s {
		out = append(out, c(i))
	}
	return out
}

// parseHeaderList tokenize + normalize a string containing a list of headers
func parseHeaderList(headerList string) []string {
	l := len(headerList)
	h := make([]byte, 0, l)
	upper := true
	// Estimate the number headers in order to allocate the right splice size
	t := 0
	for i := 0; i < l; i++ {
		if headerList[i] == ',' {
			t++
		}
	}
	headers := make([]string, 0, t)
	for i := 0; i < l; i++ {
		b := headerList[i]
		switch {
		case b >= 'a' && b <= 'z':
			if upper {
				h = append(h, b-toLower)
			} else {
				h = append(h, b)
			}
		case b >= 'A' && b <= 'Z':
			if !upper {
				h = append(h, b+toLower)
			} else {
				h = append(h, b)
			}
		case b == '-' || b == '_' || b == '.' || (b >= '0' && b <= '9'):
			h = append(h, b)
		}

		if b == ' ' || b == ',' || i == l-1 {
			if len(h) > 0 {
				// Flush the found header
				headers = append(headers, string(h))
				h = h[:0]
				upper = true
			}
		} else {
			upper = b == '-' || b == '_'
		}
	}
	return headers
}
<|endoftext|>