<commit_before>package main

import (
	// "bufio"
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/url"
	"os"
	"os/exec"
	"strings"
	"time"
)

// @author Robin Verlangen

type Cmd struct {
	Command              string   // Commands to execute
	Pending              bool     // Did we dispatch it to the client?
	Id                   string   // Unique ID for this command
	ClientId             string   // Client ID on which the command is executed
	TemplateId           string   // Reference to the template id
	ConsensusRequestId   string   // Reference to the request id
	Signature            string   // makes this only valid from the server to the client based on the preshared token and this is a signature with the command and id
	Timeout              int      // in seconds
	State                string   // Textual representation of the current state, e.g. finished, failed, etc.
	RequestUserId        string   // User ID of the user that initiated this command
	Created              int64    // Unix timestamp created
	ExecutionIterationId int      // In which iteration the command was started
	BufOutput            []string // Standard output
	BufOutputErr         []string // Error output
}

// Sign the command on the server
func (c *Cmd) Sign(client *RegisteredClient) {
	c.Signature = c.ComputeHmac(client.AuthToken)
}

// Set local state
func (c *Cmd) SetState(state string) {
	// Old state for change detection
	oldState := c.State

	// Update
	c.State = state

	// Debug logging
	if debug {
		log.Printf("Cmd %s went from state %s to %s", c.Id, oldState, c.State)
	}

	// Run validation
	if oldState == "finished_execution" && c.State == "flushed_logs" {
		c._validate()
	} else if oldState == "failed_execution" && c.State == "flushed_logs" {
		c.State = "failed"
	}
}

// Validate the execution of a command, only on the server
func (c *Cmd) _validate() {
	// Only on the server
	if conf.IsServer == false {
		return
	}

	// Get template
	template := server.templateStore.Get(c.TemplateId)
	if template == nil {
		log.Printf("Unable to find template %s for validation of cmd %s", c.TemplateId, c.Id)
		return
	}

	// Iterate and run on templates
	var failedValidation = false
	for _, v := range template.ValidationRules {
		// Select stream
		var stream []string
		if v.OutputStream == 1 {
			stream = c.BufOutput
		} else {
			stream = c.BufOutputErr
		}

		// Match on line
		var matched bool = false
		for _, line := range stream {
			if strings.Contains(line, v.Text) {
				matched = true
				break
			}
		}

		// Did we match?
		if v.MustContain == true && matched == false {
			// Should BE there, but is NOT
			c.SetState("failed_validation")
			failedValidation = true
			break
		} else if v.MustContain == false && matched == true {
			// Should NOT be there, but IS
			c.SetState("failed_validation")
			failedValidation = true
			break
		}
	}

	// Done and passed validation
	if failedValidation == false {
		if debug {
			log.Printf("Validation passed for %s", c.Id)
		}
		c.SetState("finished")

		// Start next iteration
		ece := server.executionCoordinator.Get(c.ConsensusRequestId)
		if ece != nil {
			go ece.Next()
		}
	}
}

// Notify state to server
func (c *Cmd) NotifyServer(state string) {
	// Update local client state
	c.SetState(state)

	// Update server state, only if this has a signature, else it is local
	if len(c.Signature) > 0 {
		client._req("PUT", fmt.Sprintf("client/%s/cmd/%s/state?state=%s", url.QueryEscape(client.Id), url.QueryEscape(c.Id), url.QueryEscape(state)), nil)
	}
}

// Should we flush the local buffer? After X milliseconds or Y lines
func (c *Cmd) _checkFlushLogs() {
	// At least 10 lines
	if len(c.BufOutput) > 10 || len(c.BufOutputErr) > 10 {
		c._flushLogs()
	}
}

// Write logs to server
func (c *Cmd) _flushLogs() {
	// Only if this has a signature, else it is local
	if len(c.Signature) < 1 {
		return
	}

	// To JSON
	m := make(map[string][]string)
	m["output"] = c.BufOutput
	m["error"] = c.BufOutputErr
	bytes, je := json.Marshal(m)
	if je != nil {
		log.Printf("Failed to convert logs to JSON: %s", je)
		return
	}

	// Post to server
	uri := fmt.Sprintf("client/%s/cmd/%s/logs", url.QueryEscape(client.Id), url.QueryEscape(c.Id))
	b, e := client._req("PUT", uri, bytes)
	if e != nil || len(b) < 1 {
		log.Printf("Failed log write: %s", e)
	}

	// Clear buffers
	c.BufOutput = make([]string, 0)
	c.BufOutputErr = make([]string, 0)
}

// Log output
func (c *Cmd) LogOutput(line string) {
	// No lock, only one routine can access this

	// Append
	c.BufOutput = append(c.BufOutput, line)

	// Check to flush?
	c._checkFlushLogs()
}

// Log error
func (c *Cmd) LogError(line string) {
	// No lock, only one routine can access this

	// Append
	c.BufOutputErr = append(c.BufOutputErr, line)

	// Check to flush?
	c._checkFlushLogs()
}

// Sign the command
func (c *Cmd) ComputeHmac(token string) string {
	bytes, be := base64.URLEncoding.DecodeString(token)
	if be != nil {
		return ""
	}
	mac := hmac.New(sha256.New, bytes)
	mac.Write([]byte(c.Command))
	mac.Write([]byte(c.Id))
	sum := mac.Sum(nil)
	return base64.URLEncoding.EncodeToString(sum)
}

// Execute command on the client
func (c *Cmd) Execute(client *Client) {
	log.Printf("Executing %s: %s", c.Id, c.Command)

	// Validate HMAC
	c.NotifyServer("validating")
	if client != nil {
		// Compute mac
		expectedMac := c.ComputeHmac(client.AuthToken)
		if expectedMac != c.Signature || len(c.Signature) < 1 {
			c.NotifyServer("invalid_signature")
			log.Printf("ERROR! Invalid command signature, communication between server and client might be tampered with")
			return
		}
	} else {
		log.Printf("Executing insecure command, unable to validate HMAC of %s", c.Id)
	}

	// Start
	c.NotifyServer("starting")

	// File contents
	var fileBytes bytes.Buffer
	fileBytes.WriteString("#!/bin/bash\n")
	fileBytes.WriteString(c.Command)

	// Write tmp file
	tmpFileName := fmt.Sprintf("/tmp/indispenso_%s", c.Id)
	ioutil.WriteFile(tmpFileName, fileBytes.Bytes(), 0644)

	// Remove file once done
	defer os.Remove(tmpFileName)

	// Run file
	cmd := exec.Command("bash", tmpFileName)
	var out bytes.Buffer
	var outerr bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &outerr

	// Consume streams
	// go func() {
	// 	p, pe := cmd.StdoutPipe()
	// 	if pe != nil {
	// 		log.Printf("Pipe error: %s", pe)
	// 		return
	// 	}
	// 	scanner := bufio.NewScanner(p)
	// 	for scanner.Scan() {
	// 		txt := scanner.Text()
	// 		c.LogOutput(txt)
	// 		if debug {
	// 			log.Println(scanner.Text())
	// 		}
	// 	}
	// 	if err := scanner.Err(); err != nil {
	// 		fmt.Fprintln(os.Stderr, "reading standard input:", err)
	// 	}
	// }()
	// go func() {
	// 	p, pe := cmd.StderrPipe()
	// 	if pe != nil {
	// 		log.Printf("Pipe error: %s", pe)
	// 		return
	// 	}
	// 	scanner := bufio.NewScanner(p)
	// 	for scanner.Scan() {
	// 		txt := scanner.Text()
	// 		c.LogError(txt)
	// 		if debug {
	// 			log.Println(scanner.Text())
	// 		}
	// 	}
	// 	if err := scanner.Err(); err != nil {
	// 		fmt.Fprintln(os.Stderr, "reading standard input:", err)
	// 	}
	// }()

	// Start
	err := cmd.Start()
	if err != nil {
		c.NotifyServer("failed_execution")
		log.Printf("Failed to start command: %s", err)
		return
	}
	c.NotifyServer("started_execution")

	// Timeout mechanism
	done := make(chan error, 1)
	go func() {
		done <- cmd.Wait()
	}()
	select {
	case <-time.After(time.Duration(c.Timeout) * time.Second):
		if err := cmd.Process.Kill(); err != nil {
			log.Printf("Failed to kill %s: %s", c.Id, err)
			return
		}
		<-done // allow goroutine to exit
		c.NotifyServer("killed_execution")
		log.Printf("Process %s killed", c.Id)
	case err := <-done:
		if err != nil {
			c.NotifyServer("failed_execution")
			c.LogError(fmt.Sprintf("%v", err))
			log.Printf("Process %s done with error = %v", c.Id, err)
		} else {
			c.NotifyServer("finished_execution")
			log.Printf("Finished %s", c.Id)
		}
	}

	// Logs
	for _, line := range strings.Split(out.String(), "\n") {
		c.LogOutput(line)
	}
	for _, line := range strings.Split(outerr.String(), "\n") {
		c.LogError(line)
	}
	// Final flush
	c._flushLogs()
	c.NotifyServer("flushed_logs")
}

func newCmd(command string, timeout int) *Cmd {
	// Default timeout if not valid
	if timeout < 1 {
		timeout = DEFAULT_COMMAND_TIMEOUT
	}

	// Create instance
	return &Cmd{
		Id:           uuidStr(),
		Command:      command,
		Pending:      true,
		Timeout:      timeout,
		State:        "pending",
		Created:      time.Now().Unix(),
		BufOutput:    make([]string, 0),
		BufOutputErr: make([]string, 0),
	}
}
<commit_msg>Re-auth with server after invalid token error<commit_after>package main

import (
	// "bufio"
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/url"
	"os"
	"os/exec"
	"strings"
	"time"
)

// @author Robin Verlangen

type Cmd struct {
	Command              string   // Commands to execute
	Pending              bool     // Did we dispatch it to the client?
	Id                   string   // Unique ID for this command
	ClientId             string   // Client ID on which the command is executed
	TemplateId           string   // Reference to the template id
	ConsensusRequestId   string   // Reference to the request id
	Signature            string   // makes this only valid from the server to the client based on the preshared token and this is a signature with the command and id
	Timeout              int      // in seconds
	State                string   // Textual representation of the current state, e.g. finished, failed, etc.
	RequestUserId        string   // User ID of the user that initiated this command
	Created              int64    // Unix timestamp created
	ExecutionIterationId int      // In which iteration the command was started
	BufOutput            []string // Standard output
	BufOutputErr         []string // Error output
}

// Sign the command on the server
func (c *Cmd) Sign(client *RegisteredClient) {
	c.Signature = c.ComputeHmac(client.AuthToken)
}

// Set local state
func (c *Cmd) SetState(state string) {
	// Old state for change detection
	oldState := c.State

	// Update
	c.State = state

	// Debug logging
	if debug {
		log.Printf("Cmd %s went from state %s to %s", c.Id, oldState, c.State)
	}

	// Run validation
	if oldState == "finished_execution" && c.State == "flushed_logs" {
		c._validate()
	} else if oldState == "failed_execution" && c.State == "flushed_logs" {
		c.State = "failed"
	}
}

// Validate the execution of a command, only on the server
func (c *Cmd) _validate() {
	// Only on the server
	if conf.IsServer == false {
		return
	}

	// Get template
	template := server.templateStore.Get(c.TemplateId)
	if template == nil {
		log.Printf("Unable to find template %s for validation of cmd %s", c.TemplateId, c.Id)
		return
	}

	// Iterate and run on templates
	var failedValidation = false
	for _, v := range template.ValidationRules {
		// Select stream
		var stream []string
		if v.OutputStream == 1 {
			stream = c.BufOutput
		} else {
			stream = c.BufOutputErr
		}

		// Match on line
		var matched bool = false
		for _, line := range stream {
			if strings.Contains(line, v.Text) {
				matched = true
				break
			}
		}

		// Did we match?
		if v.MustContain == true && matched == false {
			// Should BE there, but is NOT
			c.SetState("failed_validation")
			failedValidation = true
			break
		} else if v.MustContain == false && matched == true {
			// Should NOT be there, but IS
			c.SetState("failed_validation")
			failedValidation = true
			break
		}
	}

	// Done and passed validation
	if failedValidation == false {
		if debug {
			log.Printf("Validation passed for %s", c.Id)
		}
		c.SetState("finished")

		// Start next iteration
		ece := server.executionCoordinator.Get(c.ConsensusRequestId)
		if ece != nil {
			go ece.Next()
		}
	}
}

// Notify state to server
func (c *Cmd) NotifyServer(state string) {
	// Update local client state
	c.SetState(state)

	// Update server state, only if this has a signature, else it is local
	if len(c.Signature) > 0 {
		client._req("PUT", fmt.Sprintf("client/%s/cmd/%s/state?state=%s", url.QueryEscape(client.Id), url.QueryEscape(c.Id), url.QueryEscape(state)), nil)
	}
}

// Should we flush the local buffer? After X milliseconds or Y lines
func (c *Cmd) _checkFlushLogs() {
	// At least 10 lines
	if len(c.BufOutput) > 10 || len(c.BufOutputErr) > 10 {
		c._flushLogs()
	}
}

// Write logs to server
func (c *Cmd) _flushLogs() {
	// Only if this has a signature, else it is local
	if len(c.Signature) < 1 {
		return
	}

	// To JSON
	m := make(map[string][]string)
	m["output"] = c.BufOutput
	m["error"] = c.BufOutputErr
	bytes, je := json.Marshal(m)
	if je != nil {
		log.Printf("Failed to convert logs to JSON: %s", je)
		return
	}

	// Post to server
	uri := fmt.Sprintf("client/%s/cmd/%s/logs", url.QueryEscape(client.Id), url.QueryEscape(c.Id))
	b, e := client._req("PUT", uri, bytes)
	if e != nil || len(b) < 1 {
		log.Printf("Failed log write: %s", e)
	}

	// Clear buffers
	c.BufOutput = make([]string, 0)
	c.BufOutputErr = make([]string, 0)
}

// Log output
func (c *Cmd) LogOutput(line string) {
	// No lock, only one routine can access this

	// Append
	c.BufOutput = append(c.BufOutput, line)

	// Check to flush?
	c._checkFlushLogs()
}

// Log error
func (c *Cmd) LogError(line string) {
	// No lock, only one routine can access this

	// Append
	c.BufOutputErr = append(c.BufOutputErr, line)

	// Check to flush?
	c._checkFlushLogs()
}

// Sign the command
func (c *Cmd) ComputeHmac(token string) string {
	bytes, be := base64.URLEncoding.DecodeString(token)
	if be != nil {
		return ""
	}
	mac := hmac.New(sha256.New, bytes)
	mac.Write([]byte(c.Command))
	mac.Write([]byte(c.Id))
	sum := mac.Sum(nil)
	return base64.URLEncoding.EncodeToString(sum)
}

// Execute command on the client
func (c *Cmd) Execute(client *Client) {
	log.Printf("Executing %s: %s", c.Id, c.Command)

	// Validate HMAC
	c.NotifyServer("validating")
	if client != nil {
		// Compute mac
		expectedMac := c.ComputeHmac(client.AuthToken)

		// Valid?
		if expectedMac != c.Signature || len(c.Signature) < 1 {
			// No, let's abort

			// Notify server
			c.NotifyServer("invalid_signature")

			// Log
			log.Printf("ERROR! Invalid command signature, communication between server and client might be tampered with")

			// Re-authenticate with server in order to establish a new token
			client.AuthServer()

			// Abort execution
			return
		}
	} else {
		log.Printf("Executing insecure command, unable to validate HMAC of %s", c.Id)
	}

	// Start
	c.NotifyServer("starting")

	// File contents
	var fileBytes bytes.Buffer
	fileBytes.WriteString("#!/bin/bash\n")
	fileBytes.WriteString(c.Command)

	// Write tmp file
	tmpFileName := fmt.Sprintf("/tmp/indispenso_%s", c.Id)
	ioutil.WriteFile(tmpFileName, fileBytes.Bytes(), 0644)

	// Remove file once done
	defer os.Remove(tmpFileName)

	// Run file
	cmd := exec.Command("bash", tmpFileName)
	var out bytes.Buffer
	var outerr bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &outerr

	// Consume streams
	// go func() {
	// 	p, pe := cmd.StdoutPipe()
	// 	if pe != nil {
	// 		log.Printf("Pipe error: %s", pe)
	// 		return
	// 	}
	// 	scanner := bufio.NewScanner(p)
	// 	for scanner.Scan() {
	// 		txt := scanner.Text()
	// 		c.LogOutput(txt)
	// 		if debug {
	// 			log.Println(scanner.Text())
	// 		}
	// 	}
	// 	if err := scanner.Err(); err != nil {
	// 		fmt.Fprintln(os.Stderr, "reading standard input:", err)
	// 	}
	// }()
	// go func() {
	// 	p, pe := cmd.StderrPipe()
	// 	if pe != nil {
	// 		log.Printf("Pipe error: %s", pe)
	// 		return
	// 	}
	// 	scanner := bufio.NewScanner(p)
	// 	for scanner.Scan() {
	// 		txt := scanner.Text()
	// 		c.LogError(txt)
	// 		if debug {
	// 			log.Println(scanner.Text())
	// 		}
	// 	}
	// 	if err := scanner.Err(); err != nil {
	// 		fmt.Fprintln(os.Stderr, "reading standard input:", err)
	// 	}
	// }()

	// Start
	err := cmd.Start()
	if err != nil {
		c.NotifyServer("failed_execution")
		log.Printf("Failed to start command: %s", err)
		return
	}
	c.NotifyServer("started_execution")

	// Timeout mechanism
	done := make(chan error, 1)
	go func() {
		done <- cmd.Wait()
	}()
	select {
	case <-time.After(time.Duration(c.Timeout) * time.Second):
		if err := cmd.Process.Kill(); err != nil {
			log.Printf("Failed to kill %s: %s", c.Id, err)
			return
		}
		<-done // allow goroutine to exit
		c.NotifyServer("killed_execution")
		log.Printf("Process %s killed", c.Id)
	case err := <-done:
		if err != nil {
			c.NotifyServer("failed_execution")
			c.LogError(fmt.Sprintf("%v", err))
			log.Printf("Process %s done with error = %v", c.Id, err)
		} else {
			c.NotifyServer("finished_execution")
			log.Printf("Finished %s", c.Id)
		}
	}

	// Logs
	for _, line := range strings.Split(out.String(), "\n") {
		c.LogOutput(line)
	}
	for _, line := range strings.Split(outerr.String(), "\n") {
		c.LogError(line)
	}
	// Final flush
	c._flushLogs()
	c.NotifyServer("flushed_logs")
}

func newCmd(command string, timeout int) *Cmd {
	// Default timeout if not valid
	if timeout < 1 {
		timeout = DEFAULT_COMMAND_TIMEOUT
	}

	// Create instance
	return &Cmd{
		Id:           uuidStr(),
		Command:      command,
		Pending:      true,
		Timeout:      timeout,
		State:        "pending",
		Created:      time.Now().Unix(),
		BufOutput:    make([]string, 0),
		BufOutputErr: make([]string, 0),
	}
}
<|endoftext|>


<commit_before>package flash

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"strconv"
	"strings"
)

// Req public interface for Ctx
type Req interface {
	QueryParam(string) string
	SetVar(string, interface{})
	Var(string) interface{}
	Param(string) string
	Header(string) string
	RenderJSON(code int, s JSON)
	RenderJSONError(code int, s string)
}

// Ctx contains request information
type Ctx struct {
	Req *http.Request
	W   http.ResponseWriter

	vars   map[string]interface{}
	params map[string]string
}

// initCtx initializing Ctx structure
func (c *Ctx) initCtx(w http.ResponseWriter, req *http.Request, params map[string]string) {
	c.W = w
	c.Req = req
	c.params = params
	c.vars = make(map[string]interface{})
}

// LoadJSONRequest extracting JSON request by key
// from request body into interface
func (c *Ctx) LoadJSONRequest(root string, v interface{}) {
	defer c.Req.Body.Close()

	if root == "" {
		extractJSONPayload(c.Req.Body, &v)
		return
	}

	var s []byte
	var body JSON
	extractJSONPayload(c.Req.Body, &body)
	s, _ = json.Marshal(body[root])
	json.Unmarshal(s, &v)
}

// QueryParam returns URL query param
func (c *Ctx) QueryParam(s string) string {
	return c.Req.URL.Query().Get(s)
}

// Param get URL param
func (c *Ctx) Param(k string) string {
	return c.params[k]
}

// Params returns all URL params
func (c *Ctx) Params() map[string]string {
	return c.params
}

// SetVar set session variable
func (c *Ctx) SetVar(k string, v interface{}) {
	c.vars[k] = v
}

// Var returns session variable
func (c *Ctx) Var(k string) interface{} {
	return c.vars[k]
}

// Header returns request header
func (c *Ctx) Header(s string) string {
	return c.Req.Header.Get(s)
}

// Cookie returns request header
func (c *Ctx) Cookie(s string) string {
	if cookie, err := c.Req.Cookie(s); err == nil {
		return cookie.Value
	}
	return ""
}

// RenderJSON rendering JSON to client
func (c *Ctx) RenderJSON(code int, s JSON) {
	if strings.Contains(c.Req.Header.Get("Accept-Encoding"), "gzip") {
		RenderJSONgzip(c.W, code, s)
		return
	}
	RenderJSON(c.W, code, s)
}

// RenderJSONError rendering error to client in JSON format
func (c *Ctx) RenderJSONError(code int, s string) {
	c.RenderJSON(code, JSON{"errors": JSON{"message": []string{s}}})
}

// RenderString rendering string to client
func (c *Ctx) RenderString(code int, s string) {
	c.W.WriteHeader(code)
	c.W.Write([]byte(s))
}

// Render rendering []byte to client
func (c *Ctx) Render(code int, b []byte) {
	c.W.WriteHeader(code)
	c.W.Write(b)
}

// RenderError rendering error to client
func (c *Ctx) RenderError(code int, s string) {
	http.Error(c.W, s, code)
}

// LoadFile handling file uploads
func (c *Ctx) LoadFile(field, dir string) (string, error) {
	c.Req.ParseMultipartForm(32 << 20)
	file, handler, err := c.Req.FormFile(field)
	if err != nil {
		return "", err
	}
	defer file.Close()
	fmt.Fprintf(c.W, "%v", handler.Header)
	f, err := os.OpenFile(dir+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		return "", err
	}
	defer f.Close()
	io.Copy(f, file)
	return handler.Filename, nil
}

// ID64 returns ID as int64
func (c *Ctx) ID64() int64 {
	i, _ := strconv.ParseInt(c.params["id"], 10, 64)
	return i
}
<commit_msg>adding Cookie method to Req interface<commit_after>package flash

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"strconv"
	"strings"
)

// Req public interface for Ctx
type Req interface {
	QueryParam(string) string
	SetVar(string, interface{})
	Var(string) interface{}
	Param(string) string
	Header(string) string
	Cookie(string) string
	RenderJSON(code int, s JSON)
	RenderJSONError(code int, s string)
}

// Ctx contains request information
type Ctx struct {
	Req *http.Request
	W   http.ResponseWriter

	vars   map[string]interface{}
	params map[string]string
}

// initCtx initializing Ctx structure
func (c *Ctx) initCtx(w http.ResponseWriter, req *http.Request, params map[string]string) {
	c.W = w
	c.Req = req
	c.params = params
	c.vars = make(map[string]interface{})
}

// LoadJSONRequest extracting JSON request by key
// from request body into interface
func (c *Ctx) LoadJSONRequest(root string, v interface{}) {
	defer c.Req.Body.Close()

	if root == "" {
		extractJSONPayload(c.Req.Body, &v)
		return
	}

	var s []byte
	var body JSON
	extractJSONPayload(c.Req.Body, &body)
	s, _ = json.Marshal(body[root])
	json.Unmarshal(s, &v)
}

// QueryParam returns URL query param
func (c *Ctx) QueryParam(s string) string {
	return c.Req.URL.Query().Get(s)
}

// Param get URL param
func (c *Ctx) Param(k string) string {
	return c.params[k]
}

// Params returns all URL params
func (c *Ctx) Params() map[string]string {
	return c.params
}

// SetVar set session variable
func (c *Ctx) SetVar(k string, v interface{}) {
	c.vars[k] = v
}

// Var returns session variable
func (c *Ctx) Var(k string) interface{} {
	return c.vars[k]
}

// Header returns request header
func (c *Ctx) Header(s string) string {
	return c.Req.Header.Get(s)
}

// Cookie returns request header
func (c *Ctx) Cookie(s string) string {
	if cookie, err := c.Req.Cookie(s); err == nil {
		return cookie.Value
	}
	return ""
}

// RenderJSON rendering JSON to client
func (c *Ctx) RenderJSON(code int, s JSON) {
	if strings.Contains(c.Req.Header.Get("Accept-Encoding"), "gzip") {
		RenderJSONgzip(c.W, code, s)
		return
	}
	RenderJSON(c.W, code, s)
}

// RenderJSONError rendering error to client in JSON format
func (c *Ctx) RenderJSONError(code int, s string) {
	c.RenderJSON(code, JSON{"errors": JSON{"message": []string{s}}})
}

// RenderString rendering string to client
func (c *Ctx) RenderString(code int, s string) {
	c.W.WriteHeader(code)
	c.W.Write([]byte(s))
}

// Render rendering []byte to client
func (c *Ctx) Render(code int, b []byte) {
	c.W.WriteHeader(code)
	c.W.Write(b)
}

// RenderError rendering error to client
func (c *Ctx) RenderError(code int, s string) {
	http.Error(c.W, s, code)
}

// LoadFile handling file uploads
func (c *Ctx) LoadFile(field, dir string) (string, error) {
	c.Req.ParseMultipartForm(32 << 20)
	file, handler, err := c.Req.FormFile(field)
	if err != nil {
		return "", err
	}
	defer file.Close()
	fmt.Fprintf(c.W, "%v", handler.Header)
	f, err := os.OpenFile(dir+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		return "", err
	}
	defer f.Close()
	io.Copy(f, file)
	return handler.Filename, nil
}

// ID64 returns ID as int64
func (c *Ctx) ID64() int64 {
	i, _ := strconv.ParseInt(c.params["id"], 10, 64)
	return i
}
<|endoftext|>


<commit_before>package peco

import (
	"io"
	"sync"
	"time"
)

func (c *Ctx) CaretPos() int {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	return c.caretPosition
}

func (c *Ctx) SetCaretPos(where int) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.caretPosition = where
}

func (c *Ctx) MoveCaretPos(offset int) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.caretPosition = c.caretPosition + offset
}

func (q FilterQuery) Query() []rune {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	return q.query[:]
}

func (q FilterQuery) SavedQuery() []rune {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	return q.savedQuery[:]
}

func (q FilterQuery) QueryString() string {
	qbytes := q.Query()
	return string(qbytes)
}

func (q FilterQuery) QueryLen() int {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	return len(q.query)
}

func (q *FilterQuery) AppendQuery(r rune) {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	q.query = append(q.query, r)
}

func (q *FilterQuery) InsertQueryAt(ch rune, where int) {
	q.mutex.Lock()
	defer q.mutex.Unlock()

	sq := q.query
	buf := make([]rune, len(sq)+1)
	copy(buf, sq[:where])
	buf[where] = ch
	copy(buf[where+1:], sq[where:])
	q.query = buf
}

func NewCtx(o CtxOptions) *Ctx {
	return newCtx(o, 5)
}

func newCtx(o CtxOptions, hubBufferSize int) *Ctx {
	c := &Ctx{
		Hub:                 NewHub(hubBufferSize),
		FilterQuery:         &FilterQuery{[]rune{}, []rune{}, newMutex()},
		filters:             FilterSet{},
		caretPosition:       0,
		resultCh:            nil,
		mutex:               newMutex(),
		currentCol:          0,
		currentPage:         &PageInfo{},
		selection:           NewSelection(),
		activeLineBuffer:    nil,
		rawLineBuffer:       NewRawLineBuffer(),
		lines:               []Line{},
		linesMutex:          newMutex(),
		current:             nil,
		currentMutex:        newMutex(),
		config:              NewConfig(),
		selectionRangeStart: invalidSelectionRange,
		wait:                &sync.WaitGroup{},
		layoutType:          "top-down",
		singleKeyJumpMode:   false,
	}

	if o != nil {
		// XXX Pray this is really nil :)
		c.enableSep = o.EnableNullSep()
		c.currentLine = o.InitialIndex()

		c.rawLineBuffer.SetCapacity(o.BufferSize())

		if v := o.LayoutType(); v != "" {
			c.layoutType = v
		}
	}

	c.filters.Add(NewIgnoreCaseFilter())
	c.filters.Add(NewCaseSensitiveFilter())
	c.filters.Add(NewSmartCaseFilter())
	c.filters.Add(NewRegexpFilter())

	return c
}

const invalidSelectionRange = -1

func (c *Ctx) ReadConfig(file string) error {
	if err := c.config.ReadFilename(file); err != nil {
		return err
	}

	if err := c.LoadCustomFilter(); err != nil {
		return err
	}

	c.SetCurrentFilterByName(c.config.InitialFilter)

	if c.layoutType == "" { // Not set yet
		if c.config.Layout != "" {
			c.layoutType = c.config.Layout
		}
	}

	if len(c.config.SingleKeyJumpMap) == 0 {
		c.config.SingleKeyJumpMap = make(map[rune]uint)
		chrs := "asdfghjklzxcvbnmqwertyuiop"
		for i := 0; i < len(chrs); i++ {
			c.config.SingleKeyJumpMap[rune(chrs[i])] = uint(i)
		}
	}
	c.config.SingleKeyJumpList = make([]rune, len(c.config.SingleKeyJumpMap))
	for k, v := range c.config.SingleKeyJumpMap {
		c.config.SingleKeyJumpList[v] = k
	}

	return nil
}

func (c *Ctx) IsRangeMode() bool {
	return c.selectionRangeStart != invalidSelectionRange
}

func (c *Ctx) SelectionLen() int {
	return c.selection.Len()
}

func (c *Ctx) SelectionAdd(x int) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	if l, err := c.GetCurrentLineBuffer().LineAt(x); err == nil {
		c.selection.Add(l)
	}
}

func (c *Ctx) SelectionRemove(x int) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	if l, err := c.GetCurrentLineBuffer().LineAt(x); err == nil {
		c.selection.Delete(l)
	}
}

func (c *Ctx) SelectionClear() {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.selection = NewSelection()
}

func (c *Ctx) SelectionContains(n int) bool {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	if l, err := c.GetCurrentLineBuffer().LineAt(n); err == nil {
		return c.selection.Has(l)
	}
	return false
}

func (c *Ctx) ResultCh() <-chan Line {
	return c.resultCh
}

func (c *Ctx) AddWaitGroup(v int) {
	c.wait.Add(v)
}

func (c *Ctx) ReleaseWaitGroup() {
	c.wait.Done()
}

func (c *Ctx) WaitDone() {
	c.wait.Wait()
}

var execQueryLock = newMutex()
var execQueryTimer *time.Timer

func (c *Ctx) ExecQuery() bool {
	trace("Ctx.ExecQuery: START")
	defer trace("Ctx.ExecQuery: END")

	if c.QueryLen() <= 0 {
		if c.activeLineBuffer != nil {
			c.ResetActiveLineBuffer()
			return true
		}
		return false
	}

	delay := c.config.QueryExecutionDelay

	if delay <= 0 {
		c.SendQuery(c.QueryString())
		return true
	}

	go func() {
		// Wait $delay millisecs before sending the query
		// if a new input comes in, batch them up
		execQueryLock.Lock()
		defer execQueryLock.Unlock()
		if execQueryTimer != nil {
			return
		}
		execQueryTimer = time.AfterFunc(time.Duration(delay)*time.Millisecond, func() {
			trace("Ctx.ExecQuery: Sending Query!")
			c.SendQuery(c.QueryString())

			execQueryLock.Lock()
			defer execQueryLock.Unlock()
			execQueryTimer = nil
		})
	}()
	return true
}

func (c *Ctx) DrawPrompt() {
	c.SendDrawPrompt()
}

func (c *Ctx) NewBufferReader(r io.ReadCloser) *BufferReader {
	return &BufferReader{c, r, make(chan struct{}, 1)}
}

func (c *Ctx) NewView() *View {
	var layout Layout
	switch c.layoutType {
	case "bottom-up":
		layout = NewBottomUpLayout(c)
	default:
		layout = NewDefaultLayout(c)
	}
	return &View{c, newMutex(), layout}
}

func (c *Ctx) NewFilter() *Filter {
	return &Filter{c}
}

func (c *Ctx) NewInput() *Input {
	// Create a new keymap object
	k := NewKeymap(c.config.Keymap, c.config.Action)
	k.ApplyKeybinding()
	return &Input{c, newMutex(), nil, k, []string{}}
}

func (c *Ctx) SetSavedQuery(q []rune) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.FilterQuery.savedQuery = q
}

func (c *Ctx) SetQuery(q []rune) {
	trace("Ctx.SetQuery: START")
	defer trace("Ctx.SetQuery: END")
	c.mutex.Lock()
	trace("Ctx.SetQuery: setting query to '%s'", string(q))
	c.FilterQuery.query = q
	c.mutex.Unlock()
	c.SetCaretPos(c.QueryLen())
}

func (c *Ctx) Filter() QueryFilterer {
	return c.filters.GetCurrent()
}

func (c *Ctx) LoadCustomFilter() error {
	if len(c.config.CustomFilter) == 0 {
		return nil
	}

	for name, cfg := range c.config.CustomFilter {
		f := NewExternalCmdFilter(name, cfg.Cmd, cfg.Args, cfg.BufferThreshold, c.enableSep)
		if err := c.filters.Add(f); err != nil {
			return err
		}
	}
	return nil
}

func (c *Ctx) Error() error {
	return c.err
}

func (c *Ctx) ExitWith(err error) {
	c.err = err
	c.Stop()
}

func (c *Ctx) SetPrompt(p string) {
	c.config.Prompt = p
}

func (c *Ctx) AddRawLine(l *RawLine) {
	c.rawLineBuffer.AppendLine(l)
}

func (c Ctx) GetRawLineBufferSize() int {
	return c.rawLineBuffer.Size()
}

func (c *Ctx) ResetActiveLineBuffer() {
	c.rawLineBuffer.Replay()
	c.SetActiveLineBuffer(c.rawLineBuffer, false)
}

func (c *Ctx) SetActiveLineBuffer(l *RawLineBuffer, runningQuery bool) {
	c.activeLineBuffer = l

	go func(l *RawLineBuffer) {
		prev := time.Time{}
		for _ = range l.OutputCh() {
			if time.Since(prev) > time.Millisecond {
				c.SendDraw(runningQuery)
				prev = time.Now()
			}
		}
		c.SendDraw(runningQuery)
	}(l)
}

func (c Ctx) GetCurrentLineBuffer() LineBuffer {
	if b := c.activeLineBuffer; b != nil {
		return b
	}
	return c.rawLineBuffer
}

func (c *Ctx) RotateFilter() {
	c.filters.Rotate()
}

func (c *Ctx) ResetSelectedFilter() {
	c.filters.Reset()
}

func (c *Ctx) SetCurrentFilterByName(name string) error {
	return c.filters.SetCurrentByName(name)
}

func (c *Ctx) startInput() {
	c.AddWaitGroup(1)
	go c.NewInput().Loop()
}

func (c *Ctx) ToggleSingleKeyJumpMode() {
	c.singleKeyJumpMode = !c.singleKeyJumpMode
	c.SendPurgeDisplayCache()
	c.SendDraw(false)
}

func (c *Ctx) IsSingleKeyJumpMode() bool {
	return c.singleKeyJumpMode
}
<commit_msg>Apply https://github.com/peco/peco/pull/266#issuecomment-143934464<commit_after>package peco

import (
	"io"
	"sync"
	"time"
)

func (c *Ctx) CaretPos() int {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	return c.caretPosition
}

func (c *Ctx) SetCaretPos(where int) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.caretPosition = where
}

func (c *Ctx) MoveCaretPos(offset int) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.caretPosition = c.caretPosition + offset
}

func (q FilterQuery) Query() []rune {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	return q.query[:]
}

func (q FilterQuery) SavedQuery() []rune {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	return q.savedQuery[:]
}

func (q FilterQuery) QueryString() string {
	qbytes := q.Query()
	return string(qbytes)
}

func (q FilterQuery) QueryLen() int {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	return len(q.query)
}

func (q *FilterQuery) AppendQuery(r rune) {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	q.query = append(q.query, r)
}

func (q *FilterQuery) InsertQueryAt(ch rune, where int) {
	q.mutex.Lock()
	defer q.mutex.Unlock()

	sq := q.query
	buf := make([]rune, len(sq)+1)
	copy(buf, sq[:where])
	buf[where] = ch
	copy(buf[where+1:], sq[where:])
	q.query = buf
}

func NewCtx(o CtxOptions) *Ctx {
	return newCtx(o, 5)
}

func newCtx(o CtxOptions, hubBufferSize int) *Ctx {
	c := &Ctx{
		Hub:                 NewHub(hubBufferSize),
		FilterQuery:         &FilterQuery{[]rune{}, []rune{}, newMutex()},
		filters:             FilterSet{},
		caretPosition:       0,
		resultCh:            nil,
		mutex:               newMutex(),
		currentCol:          0,
		currentPage:         &PageInfo{},
		selection:           NewSelection(),
		activeLineBuffer:    nil,
		rawLineBuffer:       NewRawLineBuffer(),
		lines:               []Line{},
		linesMutex:          newMutex(),
		current:             nil,
		currentMutex:        newMutex(),
		config:              NewConfig(),
		selectionRangeStart: invalidSelectionRange,
		wait:                &sync.WaitGroup{},
		layoutType:          "top-down",
		singleKeyJumpMode:   false,
	}

	if o != nil {
		// XXX Pray this is really nil :)
		c.enableSep = o.EnableNullSep()
		c.currentLine = o.InitialIndex()

		c.rawLineBuffer.SetCapacity(o.BufferSize())

		if v := o.LayoutType(); v != "" {
			c.layoutType = v
		}
	}

	c.filters.Add(NewIgnoreCaseFilter())
	c.filters.Add(NewCaseSensitiveFilter())
	c.filters.Add(NewSmartCaseFilter())
	c.filters.Add(NewRegexpFilter())

	return c
}

const invalidSelectionRange = -1

func (c *Ctx) ReadConfig(file string) error {
	if err := c.config.ReadFilename(file); err != nil {
		return err
	}

	if err := c.LoadCustomFilter(); err != nil {
		return err
	}

	c.SetCurrentFilterByName(c.config.InitialFilter)

	if c.layoutType == "" { // Not set yet
		if c.config.Layout != "" {
			c.layoutType = c.config.Layout
		}
	}

	c.config.SingleKeyJumpMap = make(map[rune]uint)
	chrs := "asdfghjklzxcvbnmqwertyuiop"
	for i := 0; i < len(chrs); i++ {
		c.config.SingleKeyJumpMap[rune(chrs[i])] = uint(i)
	}
	c.config.SingleKeyJumpList = make([]rune, len(c.config.SingleKeyJumpMap))
	for k, v := range c.config.SingleKeyJumpMap {
		c.config.SingleKeyJumpList[v] = k
	}

	return nil
}

func (c *Ctx) IsRangeMode() bool {
	return c.selectionRangeStart != invalidSelectionRange
}

func (c *Ctx) SelectionLen() int {
	return c.selection.Len()
}

func (c *Ctx) SelectionAdd(x int) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	if l, err := c.GetCurrentLineBuffer().LineAt(x); err == nil {
		c.selection.Add(l)
	}
}

func (c *Ctx) SelectionRemove(x int) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	if l, err := c.GetCurrentLineBuffer().LineAt(x); err == nil {
		c.selection.Delete(l)
	}
}

func (c *Ctx) SelectionClear() {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.selection = NewSelection()
}

func (c *Ctx) SelectionContains(n int) bool {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	if l, err := c.GetCurrentLineBuffer().LineAt(n); err == nil {
		return c.selection.Has(l)
	}
	return false
}

func (c *Ctx) ResultCh() <-chan Line {
	return c.resultCh
}

func (c *Ctx) AddWaitGroup(v int) {
	c.wait.Add(v)
}

func (c *Ctx) ReleaseWaitGroup() {
	c.wait.Done()
}

func (c *Ctx) WaitDone() {
	c.wait.Wait()
}

var execQueryLock = newMutex()
var execQueryTimer *time.Timer

func (c *Ctx) ExecQuery() bool {
	trace("Ctx.ExecQuery: START")
	defer trace("Ctx.ExecQuery: END")

	if c.QueryLen() <= 0 {
		if c.activeLineBuffer != nil {
			c.ResetActiveLineBuffer()
			return true
		}
		return false
	}

	delay := c.config.QueryExecutionDelay

	if delay <= 0 {
		c.SendQuery(c.QueryString())
		return true
	}

	go func() {
		// Wait $delay millisecs before sending the query
		// if a new input comes in, batch them up
		execQueryLock.Lock()
		defer execQueryLock.Unlock()
		if execQueryTimer != nil {
			return
		}
		execQueryTimer = time.AfterFunc(time.Duration(delay)*time.Millisecond, func() {
			trace("Ctx.ExecQuery: Sending Query!")
			c.SendQuery(c.QueryString())

			execQueryLock.Lock()
			defer execQueryLock.Unlock()
			execQueryTimer = nil
		})
	}()
	return true
}

func (c *Ctx) DrawPrompt() {
	c.SendDrawPrompt()
}

func (c *Ctx) NewBufferReader(r io.ReadCloser) *BufferReader {
	return &BufferReader{c, r, make(chan struct{}, 1)}
}

func (c *Ctx) NewView() *View {
	var layout Layout
	switch c.layoutType {
	case "bottom-up":
		layout = NewBottomUpLayout(c)
	default:
		layout = NewDefaultLayout(c)
	}
	return &View{c, newMutex(), layout}
}

func (c *Ctx) NewFilter() *Filter {
	return &Filter{c}
}

func (c *Ctx) NewInput() *Input {
	// Create a new keymap object
	k := NewKeymap(c.config.Keymap, c.config.Action)
	k.ApplyKeybinding()
	return &Input{c, newMutex(), nil, k, []string{}}
}

func (c *Ctx) SetSavedQuery(q []rune) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.FilterQuery.savedQuery = q
}

func (c *Ctx) SetQuery(q []rune) {
	trace("Ctx.SetQuery: START")
	defer trace("Ctx.SetQuery: END")
	c.mutex.Lock()
	trace("Ctx.SetQuery: setting query to '%s'", string(q))
	c.FilterQuery.query = q
	c.mutex.Unlock()
	c.SetCaretPos(c.QueryLen())
}

func (c *Ctx) Filter() QueryFilterer {
	return c.filters.GetCurrent()
}

func (c *Ctx) LoadCustomFilter() error {
	if len(c.config.CustomFilter) == 0 {
		return nil
	}

	for name, cfg := range c.config.CustomFilter {
		f := NewExternalCmdFilter(name, cfg.Cmd, cfg.Args, cfg.BufferThreshold, c.enableSep)
		if err := c.filters.Add(f); err != nil {
			return err
		}
	}
	return nil
}

func (c *Ctx) Error() error {
	return c.err
}

func (c *Ctx) ExitWith(err error) {
	c.err = err
	c.Stop()
}

func (c *Ctx) SetPrompt(p string) {
	c.config.Prompt = p
}

func (c *Ctx) AddRawLine(l *RawLine) {
	c.rawLineBuffer.AppendLine(l)
}

func (c Ctx) GetRawLineBufferSize() int {
	return c.rawLineBuffer.Size()
}

func (c *Ctx) ResetActiveLineBuffer() {
	c.rawLineBuffer.Replay()
	c.SetActiveLineBuffer(c.rawLineBuffer, false)
}

func (c *Ctx) SetActiveLineBuffer(l *RawLineBuffer, runningQuery bool) {
	c.activeLineBuffer = l

	go func(l *RawLineBuffer) {
		prev := time.Time{}
		for _ = range l.OutputCh() {
			if time.Since(prev) > time.Millisecond {
				c.SendDraw(runningQuery)
				prev = time.Now()
			}
		}
		c.SendDraw(runningQuery)
	}(l)
}

func (c Ctx) GetCurrentLineBuffer() LineBuffer {
	if b := c.activeLineBuffer; b != nil {
		return b
	}
	return c.rawLineBuffer
}

func (c *Ctx) RotateFilter() {
	c.filters.Rotate()
}

func (c *Ctx) ResetSelectedFilter() {
	c.filters.Reset()
}

func (c *Ctx) SetCurrentFilterByName(name string) error {
	return c.filters.SetCurrentByName(name)
}

func (c *Ctx) startInput() {
	c.AddWaitGroup(1)
	go c.NewInput().Loop()
}

func (c *Ctx) ToggleSingleKeyJumpMode() {
	c.singleKeyJumpMode = !c.singleKeyJumpMode
	c.SendPurgeDisplayCache()
	c.SendDraw(false)
}

func (c *Ctx) IsSingleKeyJumpMode() bool {
	return c.singleKeyJumpMode
}
<|endoftext|>


<commit_before>// Copyright 2013 com authors
//
// 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 com

import (
	"errors"
	"os"
	"path"
	"strings"
)

// IsDir checks whether the path is a directory.
// It returns false when it's a file or does not exist.
func IsDir(dir string) bool {
	f, e := os.Stat(dir)
	if e != nil {
		return false
	}
	return f.IsDir()
}

func statDir(dirPath, recPath string, includeDir bool) ([]string, error) {
	dir, err := os.Open(dirPath)
	if err != nil {
		return nil, err
	}
	defer dir.Close()

	fis, err := dir.Readdir(0)
	if err != nil {
		return nil, err
	}

	statList := make([]string, 0)
	for _, fi := range fis {
		relPath := strings.TrimPrefix(path.Join(recPath, fi.Name()), "/")
		curPath := strings.TrimPrefix(path.Join(dirPath, fi.Name()), "/")
		if fi.IsDir() {
			if includeDir {
				statList = append(statList, relPath+"/")
			}
			s, err := statDir(curPath, relPath, includeDir)
			if err != nil {
				return nil, err
			}
			statList = append(statList, s...)
		} else {
			statList = append(statList, relPath)
		}
	}
	return statList, nil
}

// StatDir gathers information of given directory by depth-first.
// It returns slice of file list and includes subdirectories if enabled;
// it returns error and nil slice when error occurs in underlying functions,
// or given path is not a directory or does not exist.
//
// Slice does not include given path itself.
// If subdirectories is enabled, they will have suffix '/'.
func StatDir(dirPath string, includeDir ...bool) ([]string, error) {
	if !IsDir(dirPath) {
		return nil, errors.New("not a directory or does not exist: " + dirPath)
	}

	isIncludeDir := false
	if len(includeDir) >= 1 {
		isIncludeDir = includeDir[0]
	}

	return statDir(dirPath, "", isIncludeDir)
}

// CopyDir copy files recursively from source to target directory.
// It returns error when error occurs in underlying functions.
func CopyDir(srcPath, destPath string) error {
	// Check if target directory exists.
	if IsExist(destPath) {
		return errors.New("file or directory alreay exists: " + destPath)
	}

	err := os.Mkdir(destPath, os.ModePerm)
	if err != nil {
		return err
	}

	// Gather directory info.
	infos, err := StatDir(srcPath, true)
	if err != nil {
		return err
	}

	for _, info := range infos {
		curPath := path.Join(destPath, info)
		if strings.HasSuffix(info, "/") {
			err = os.Mkdir(curPath, os.ModePerm)
		} else {
			_, err = Copy(path.Join(srcPath, info), curPath)
		}
		if err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>bug fixed<commit_after>// Copyright 2013 com authors
//
// 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 com

import (
	"errors"
	"os"
	"path"
	"strings"
)

// IsDir checks whether the path is a directory.
// It returns false when it's a file or does not exist.
func IsDir(dir string) bool {
	f, e := os.Stat(dir)
	if e != nil {
		return false
	}
	return f.IsDir()
}

func statDir(dirPath, recPath string, includeDir bool) ([]string, error) {
	dir, err := os.Open(dirPath)
	if err != nil {
		return nil, err
	}
	defer dir.Close()

	fis, err := dir.Readdir(0)
	if err != nil {
		return nil, err
	}

	statList := make([]string, 0)
	for _, fi := range fis {
		relPath := path.Join(recPath, fi.Name())
		curPath := path.Join(dirPath, fi.Name())
		if fi.IsDir() {
			if includeDir {
				statList = append(statList, relPath+"/")
			}
			s, err := statDir(curPath, relPath, includeDir)
			if err != nil {
				return nil, err
			}
			statList = append(statList, s...)
		} else {
			statList = append(statList, relPath)
		}
	}
	return statList, nil
}

// StatDir gathers information of given directory by depth-first.
// It returns slice of file list and includes subdirectories if enabled;
// it returns error and nil slice when error occurs in underlying functions,
// or given path is not a directory or does not exist.
//
// Slice does not include given path itself.
// If subdirectories is enabled, they will have suffix '/'.
func StatDir(dirPath string, includeDir ...bool) ([]string, error) {
	if !IsDir(dirPath) {
		return nil, errors.New("not a directory or does not exist: " + dirPath)
	}

	isIncludeDir := false
	if len(includeDir) >= 1 {
		isIncludeDir = includeDir[0]
	}

	return statDir(dirPath, "", isIncludeDir)
}

// CopyDir copy files recursively from source to target directory.
// It returns error when error occurs in underlying functions.
func CopyDir(srcPath, destPath string) error {
	// Check if target directory exists.
	if IsExist(destPath) {
		return errors.New("file or directory alreay exists: " + destPath)
	}

	err := os.Mkdir(destPath, os.ModePerm)
	if err != nil {
		return err
	}

	// Gather directory info.
	infos, err := StatDir(srcPath, true)
	if err != nil {
		return err
	}

	for _, info := range infos {
		curPath := path.Join(destPath, info)
		if strings.HasSuffix(info, "/") {
			err = os.Mkdir(curPath, os.ModePerm)
		} else {
			_, err = Copy(path.Join(srcPath, info), curPath)
		}
		if err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>// A Redis storage backend for osin.

// Installation:

// 	go get github.com/ShaleApps/osinredis

// Usage:

// 	import (
// 	    "github.com/RangelReale/osin"
// 	    "github.com/ShaleApps/osinredis"
// 			"github.com/garyburd/redigo/redis"
// 	)

// 	func main() {
// 		pool = &redis.Pool{
// 			Dial: func() (redis.Conn, error) {
// 				conn, err := redis.Dial("tcp", ":6379")
// 				if err != nil {
// 					return nil, err
// 				}
// 				return conn, nil
// 			},
// 		}

// 		storage := osinredis.New(pool, "prefix")
// 		server := osin.NewServer(osin.NewServerConfig(), storage)
// 	}
package osinredis
<commit_msg>Fix doc.go<commit_after>/*
A Redis storage backend for osin.

Installation:

	go get github.com/ShaleApps/osinredis

Usage:

	import (
	    "github.com/RangelReale/osin"
	    "github.com/ShaleApps/osinredis"
			"github.com/garyburd/redigo/redis"
	)

	func main() {
		pool = &redis.Pool{
			Dial: func() (redis.Conn, error) {
				conn, err := redis.Dial("tcp", ":6379")
				if err != nil {
					return nil, err
				}
				return conn, nil
			},
		}

		storage := osinredis.New(pool, "prefix")
		server := osin.NewServer(osin.NewServerConfig(), storage)
	}

*/
package osinredis
<|endoftext|>


<commit_before>// Copyright 2018 The go-xdgbasedir Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package xdgbasedir implements a freedesktop.org XDG Base Directory Specification.
//  https://specifications.freedesktop.org/basedir-spec/latest/
//
// The XDG Base Directory Specification is based on the following concepts:
//
// - There is a single base directory relative to which user-specific data files should be written. This directory is defined by the environment variable $XDG_DATA_HOME.
//
// - There is a single base directory relative to which user-specific configuration files should be written. This directory is defined by the environment variable $XDG_CONFIG_HOME.
//
// - There is a set of preference ordered base directories relative to which data files should be searched. This set of directories is defined by the environment variable $XDG_DATA_DIRS.
//
// - There is a set of preference ordered base directories relative to which configuration files should be searched. This set of directories is defined by the environment variable $XDG_CONFIG_DIRS.
//
// - There is a single base directory relative to which user-specific non-essential (cached) data should be written. This directory is defined by the environment variable $XDG_CACHE_HOME.
package xdgbasedir
<commit_msg>all: add canonical import path comment<commit_after>// Copyright 2018 The go-xdgbasedir Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package xdgbasedir implements a freedesktop.org XDG Base Directory Specification.
//  https://specifications.freedesktop.org/basedir-spec/latest/
//
// The XDG Base Directory Specification is based on the following concepts:
//
// - There is a single base directory relative to which user-specific data files should be written. This directory is defined by the environment variable $XDG_DATA_HOME.
//
// - There is a single base directory relative to which user-specific configuration files should be written. This directory is defined by the environment variable $XDG_CONFIG_HOME.
//
// - There is a set of preference ordered base directories relative to which data files should be searched. This set of directories is defined by the environment variable $XDG_DATA_DIRS.
//
// - There is a set of preference ordered base directories relative to which configuration files should be searched. This set of directories is defined by the environment variable $XDG_CONFIG_DIRS.
//
// - There is a single base directory relative to which user-specific non-essential (cached) data should be written. This directory is defined by the environment variable $XDG_CACHE_HOME.
package xdgbasedir // import "github.com/zchee/go-xdgbasedir"
<|endoftext|>


<commit_before>/* Package rat, rest api testing in Go

This package provides a few simple helper types and functions to create
functional tests that call a running REST based WebService.
A test uses a rat Client that encapsulates a standard http.Client and the base url.
This can be created inside a function, as part of TestMain or as package variable.
Using the Client, you can send http requests and call expectation functions with the response.

Example

	// setup a shared client to your API
	var chatter = rat.NewClient("http://api.chatter.com", new(http.Client))

	func TestGetMessages(t *testing.T) {
		r := chatter.GET(t, rat.NewConfig("/v1/messages?user=zeus"))
		ExpectStatus(t,r,200)
		ExpectJSONArray(t,r,func(messages []interface{}){

			// in the callback you can validate the response structure
			if len(messages) == 0 {
				t.Error("expected messages, got none")
			}
		})
	}

If needed, implement the standard TestMain to do global setup and teardown.

	func TestMain(m *testing.M) {
		// there is no *testing.T available, use an stdout implementation
		t := rat.TestingT

		// setup
		chatter.PUT(t, rat.NewConfig("/v1/messages/1").Body("<payload>"))
		ExpectStatus(t,r,204)

		exitCode := m.Run()

		// teardown
		chatter.DELETE(t, rat.NewConfig("/v1/messages/1"))
		ExpectStatus(t,r,204)

		os.Exit(exitCode)
	}

(c) 2015, http://ernestmicklei.com. MIT License
*/
package rat
<commit_msg>another lint rule satisfied<commit_after>/*
Package rat, rest api testing in Go

This package provides a few simple helper types and functions to create
functional tests that call a running REST based WebService.
A test uses a rat Client that encapsulates a standard http.Client and the base url.
This can be created inside a function, as part of TestMain or as package variable.
Using the Client, you can send http requests and call expectation functions with the response.

Example

	// setup a shared client to your API
	var chatter = rat.NewClient("http://api.chatter.com", new(http.Client))

	func TestGetMessages(t *testing.T) {
		r := chatter.GET(t, rat.NewConfig("/v1/messages?user=zeus"))
		ExpectStatus(t,r,200)
		ExpectJSONArray(t,r,func(messages []interface{}){

			// in the callback you can validate the response structure
			if len(messages) == 0 {
				t.Error("expected messages, got none")
			}
		})
	}

If needed, implement the standard TestMain to do global setup and teardown.

	func TestMain(m *testing.M) {
		// there is no *testing.T available, use an stdout implementation
		t := rat.TestingT

		// setup
		chatter.PUT(t, rat.NewConfig("/v1/messages/1").Body("<payload>"))
		ExpectStatus(t,r,204)

		exitCode := m.Run()

		// teardown
		chatter.DELETE(t, rat.NewConfig("/v1/messages/1"))
		ExpectStatus(t,r,204)

		os.Exit(exitCode)
	}

(c) 2015, http://ernestmicklei.com. MIT License
*/
package rat
<|endoftext|>


<commit_before>/*
Package junos allows you to run commands on and configure Junos devices.

Establishing a session
	jnpr := junos.NewSession(host, user, password)

Lock config
	err := jnpr.Lock()
	if err != nil {
		log.Fatal(err)
	}

Unlock config
	err = jnpr.Unlock()
	if err != nil {
		log.Fatal(err)
	}

Compare the current configuration to a rollback config.
	diff, err := jnpr.RollbackDiff(3)
	if err != nil {
		fmt.Printf("Error: %s", err)
	}
	fmt.Println(diff)

The output will be exactly as it is running the "| compare" command on the CLI:

    [edit forwarding-options helpers bootp server 192.168.10.2]
    -     routing-instance srx-vr;
    [edit forwarding-options helpers bootp server 192.168.10.3]
    -     routing-instance srx-vr;
    [edit security address-book global]
         address server1 { ... }
    +    address dc-console 192.168.20.15/32;
    +    address dc-laptop 192.168.22.7/32;
    [edit security zones security-zone vendors interfaces]
          reth0.1000 { ... }
    +     reth0.520 {
    +         host-inbound-traffic {
    +             system-services {
    +                 dhcp;
    +                 ping;
    +             }
    +         }
    +     }

Rollback to an older configuration.
	err := jnpr.RollbackConfig(2)
	if err != nil {
		fmt.Printf("Error: %s", err)
	}

Run operational mode commands, such as "show."
	output, err := jnpr.Command("show version", "text")
	if err != nil {
		fmt.Printf("Error: %s", err)
	}
	fmt.Println(output)

When you specify "text," the output will be just like it is on the CLI:

    node0:
    --------------------------------------------------------------------------
    Hostname: firewall-1
    Model: srx240h2
    JUNOS Software Release [12.1X47-D10.4]

    node1:
    --------------------------------------------------------------------------
    Hostname: firewall-2
    Model: srx240h2
    JUNOS Software Release [12.1X47-D10.4]

*/
package junos<commit_msg>Updated documentation<commit_after>/*
Package junos allows you to run commands on and configure Junos devices.

Establishing a session
	jnpr := junos.NewSession(host, user, password)

Locking the configuration
	err := jnpr.Lock()
	if err != nil {
		log.Fatal(err)
	}

Commiting the configuration
	err = jnpr.Commit()
	if err != nil {
		log.Fatal(err)
	}

Unlocking the configuration
	err = jnpr.Unlock()
	if err != nil {
		log.Fatal(err)
	}

Compare the current configuration to a rollback config.
	diff, err := jnpr.RollbackDiff(3)
	if err != nil {
		fmt.Printf("Error: %s", err)
	}
	fmt.Println(diff)

The output will be exactly as it is running the "| compare" command on the CLI:

    [edit forwarding-options helpers bootp server 192.168.10.2]
    -     routing-instance srx-vr;
    [edit forwarding-options helpers bootp server 192.168.10.3]
    -     routing-instance srx-vr;
    [edit security address-book global]
         address server1 { ... }
    +    address dc-console 192.168.20.15/32;
    +    address dc-laptop 192.168.22.7/32;
    [edit security zones security-zone vendors interfaces]
          reth0.1000 { ... }
    +     reth0.520 {
    +         host-inbound-traffic {
    +             system-services {
    +                 dhcp;
    +                 ping;
    +             }
    +         }
    +     }

Rollback to an older configuration.
	err := jnpr.RollbackConfig(2)
	if err != nil {
		fmt.Printf("Error: %s", err)
	}

Run operational mode commands, such as "show."
	output, err := jnpr.Command("show version", "text")
	if err != nil {
		fmt.Printf("Error: %s", err)
	}
	fmt.Println(output)

When you specify "text," the output will be just like it is on the CLI:

    node0:
    --------------------------------------------------------------------------
    Hostname: firewall-1
    Model: srx240h2
    JUNOS Software Release [12.1X47-D10.4]

    node1:
    --------------------------------------------------------------------------
    Hostname: firewall-2
    Model: srx240h2
    JUNOS Software Release [12.1X47-D10.4]

*/
package junos<|endoftext|>


<commit_before>// EME (ECB-Mix-ECB) is a wide-block encryption mode presented in the 2003 paper
// "A Parallelizable Enciphering Mode" by Halevi and Rogaway.
// This is an implementation of EME in Go.
package eme

import (
	"crypto/cipher"
	"log"
)

const (
	DirectionEncrypt = true
	DirectionDecrypt = false
)

// multByTwo - GF multiplication as specified in the EME-32 draft
func multByTwo(out []byte, in []byte) {
	if len(in) != 16 {
		panic("len must be 16")
	}
	tmp := make([]byte, 16)

	tmp[0] = 2 * in[0]
	if in[15] >= 128 {
		tmp[0] = tmp[0] ^ 135
	}
	for j := 1; j < 16; j++ {
		tmp[j] = 2 * in[j]
		if in[j-1] >= 128 {
			tmp[j] += 1
		}
	}
	copy(out, tmp)
}

func xorBlocks(out []byte, in1 []byte, in2 []byte) {
	if len(in1) != len(in2) {
		log.Panicf("len(in1)=%d is not equal to len(in2)=%d", len(in1), len(in2))
	}

	for i := range in1 {
		out[i] = in1[i] ^ in2[i]
	}
}

// aesTransform - encrypt or decrypt (according to "direction") using block
// cipher "bc" (typically AES)
func aesTransform(dst []byte, src []byte, direction bool, bc cipher.Block) {
	if direction == DirectionEncrypt {
		bc.Encrypt(dst, src)
		return
	} else if direction == DirectionDecrypt {
		bc.Decrypt(dst, src)
		return
	} else {
		log.Panicf("unknown direction %d", direction)
	}
}

// tabulateL - calculate L_i for messages up to a length of m cipher blocks
func tabulateL(bc cipher.Block, m int) [][]byte {
	/* set L0 = 2*AESenc(K; 0) */
	eZero := make([]byte, 16)
	Li := make([]byte, 16)
	bc.Encrypt(Li, eZero)

	LTable := make([][]byte, m)
	// Allocate pool once and slice into m pieces in the loop
	pool := make([]byte, m*16)
	for i := 0; i < m; i++ {
		multByTwo(Li, Li)
		LTable[i] = pool[i*16 : (i+1)*16]
		copy(LTable[i], Li)
	}
	return LTable
}

type lCacheContainer struct {
	LTable  [][]byte
	enabled bool
}

// precompute LTable for maximum length
// Note that LTable depends on the AES key, so you must run precompute or clear
// when the key changes.
func (lc *lCacheContainer) precompute(bc cipher.Block) {
	lc.LTable = tabulateL(bc, 16*8) // 16*8 = maximum length
	lc.enabled = true
}

// clear LTable cache
func (lc *lCacheContainer) clear() {
	lc.enabled = false
}

var lTableCache lCacheContainer

// Transform - EME-encrypt or EME-decrypt, according to "direction"
// (defined in the constants directionEncrypt and directionDecrypt).
// The data in "P" is en- or decrypted with the block ciper "bc" under tweak "T".
// The result is returned in a freshly allocated slice.
func Transform(bc cipher.Block, T []byte, P []byte, direction bool) (C []byte) {
	if bc.BlockSize() != 16 {
		log.Panicf("Using a block size other than 16 is not implemented")
	}
	if len(T) != 16 {
		log.Panicf("Tweak must be 16 bytes long, is %d", len(T))
	}
	if len(P)%16 != 0 {
		log.Panicf("Data length %d is not a multiple of 16", len(P))
	}
	m := len(P) / 16
	if m == 0 || m > 16*8 {
		log.Panicf("EME operates on 1-%d block-cipher blocks", 16*8)
	}

	C = make([]byte, len(P))

	var LTable [][]byte
	if lTableCache.enabled {
		LTable = lTableCache.LTable
	} else {
		LTable = tabulateL(bc, m)
	}

	PPj := make([]byte, 16)
	for j := 0; j < m; j++ {
		Pj := P[j*16 : (j+1)*16]
		/* PPj = 2**(j-1)*L xor Pj */
		xorBlocks(PPj, Pj, LTable[j])
		/* PPPj = AESenc(K; PPj) */
		aesTransform(C[j*16:(j+1)*16], PPj, direction, bc)
	}

	/* MP =(xorSum PPPj) xor T */
	MP := make([]byte, 16)
	xorBlocks(MP, C[0:16], T)
	for j := 1; j < m; j++ {
		xorBlocks(MP, MP, C[j*16:(j+1)*16])
	}

	/* MC = AESenc(K; MP) */
	MC := make([]byte, 16)
	aesTransform(MC, MP, direction, bc)

	/* M = MP xor MC */
	M := make([]byte, 16)
	xorBlocks(M, MP, MC)
	CCCj := make([]byte, 16)
	for j := 1; j < m; j++ {
		multByTwo(M, M)
		/* CCCj = 2**(j-1)*M xor PPPj */
		xorBlocks(CCCj, C[j*16:(j+1)*16], M)
		copy(C[j*16:(j+1)*16], CCCj)
	}

	/* CCC1 = (xorSum CCCj) xor T xor MC */
	CCC1 := make([]byte, 16)
	xorBlocks(CCC1, MC, T)
	for j := 1; j < m; j++ {
		xorBlocks(CCC1, CCC1, C[j*16:(j+1)*16])
	}
	copy(C[0:16], CCC1)

	for j := 0; j < m; j++ {
		/* CCj = AES-enc(K; CCCj) */
		aesTransform(C[j*16:(j+1)*16], C[j*16:(j+1)*16], direction, bc)
		/* Cj = 2**(j-1)*L xor CCj */
		xorBlocks(C[j*16:(j+1)*16], C[j*16:(j+1)*16], LTable[j])
	}

	return C
}
<commit_msg>Improve panic messages a bit<commit_after>// EME (ECB-Mix-ECB) is a wide-block encryption mode presented in the 2003 paper
// "A Parallelizable Enciphering Mode" by Halevi and Rogaway.
// This is an implementation of EME in Go.
package eme

import (
	"crypto/cipher"
	"log"
)

const (
	DirectionEncrypt = true
	DirectionDecrypt = false
)

// multByTwo - GF multiplication as specified in the EME-32 draft
func multByTwo(out []byte, in []byte) {
	if len(in) != 16 {
		panic("len must be 16")
	}
	tmp := make([]byte, 16)

	tmp[0] = 2 * in[0]
	if in[15] >= 128 {
		tmp[0] = tmp[0] ^ 135
	}
	for j := 1; j < 16; j++ {
		tmp[j] = 2 * in[j]
		if in[j-1] >= 128 {
			tmp[j] += 1
		}
	}
	copy(out, tmp)
}

func xorBlocks(out []byte, in1 []byte, in2 []byte) {
	if len(in1) != len(in2) {
		log.Panicf("len(in1)=%d is not equal to len(in2)=%d", len(in1), len(in2))
	}

	for i := range in1 {
		out[i] = in1[i] ^ in2[i]
	}
}

// aesTransform - encrypt or decrypt (according to "direction") using block
// cipher "bc" (typically AES)
func aesTransform(dst []byte, src []byte, direction bool, bc cipher.Block) {
	if direction == DirectionEncrypt {
		bc.Encrypt(dst, src)
		return
	} else if direction == DirectionDecrypt {
		bc.Decrypt(dst, src)
		return
	} else {
		log.Panicf("unknown direction %d", direction)
	}
}

// tabulateL - calculate L_i for messages up to a length of m cipher blocks
func tabulateL(bc cipher.Block, m int) [][]byte {
	/* set L0 = 2*AESenc(K; 0) */
	eZero := make([]byte, 16)
	Li := make([]byte, 16)
	bc.Encrypt(Li, eZero)

	LTable := make([][]byte, m)
	// Allocate pool once and slice into m pieces in the loop
	pool := make([]byte, m*16)
	for i := 0; i < m; i++ {
		multByTwo(Li, Li)
		LTable[i] = pool[i*16 : (i+1)*16]
		copy(LTable[i], Li)
	}
	return LTable
}

type lCacheContainer struct {
	LTable  [][]byte
	enabled bool
}

// precompute LTable for maximum length
// Note that LTable depends on the AES key, so you must run precompute or clear
// when the key changes.
func (lc *lCacheContainer) precompute(bc cipher.Block) {
	lc.LTable = tabulateL(bc, 16*8) // 16*8 = maximum length
	lc.enabled = true
}

// clear LTable cache
func (lc *lCacheContainer) clear() {
	lc.enabled = false
}

var lTableCache lCacheContainer

// Transform - EME-encrypt or EME-decrypt, according to "direction"
// (defined in the constants directionEncrypt and directionDecrypt).
// The data in "P" is en- or decrypted with the block ciper "bc" under tweak "T".
// The result is returned in a freshly allocated slice.
func Transform(bc cipher.Block, T []byte, P []byte, direction bool) (C []byte) {
	if bc.BlockSize() != 16 {
		log.Panicf("Using a block size other than 16 is not implemented")
	}
	if len(T) != 16 {
		log.Panicf("Tweak must be 16 bytes long, is %d", len(T))
	}
	if len(P)%16 != 0 {
		log.Panicf("Data P must be a multiple of 16 long, is %d", len(P))
	}
	m := len(P) / 16
	if m == 0 || m > 16*8 {
		log.Panicf("EME operates on 1 to %d block-cipher blocks, you passed %d", 16*8, m)
	}

	C = make([]byte, len(P))

	var LTable [][]byte
	if lTableCache.enabled {
		LTable = lTableCache.LTable
	} else {
		LTable = tabulateL(bc, m)
	}

	PPj := make([]byte, 16)
	for j := 0; j < m; j++ {
		Pj := P[j*16 : (j+1)*16]
		/* PPj = 2**(j-1)*L xor Pj */
		xorBlocks(PPj, Pj, LTable[j])
		/* PPPj = AESenc(K; PPj) */
		aesTransform(C[j*16:(j+1)*16], PPj, direction, bc)
	}

	/* MP =(xorSum PPPj) xor T */
	MP := make([]byte, 16)
	xorBlocks(MP, C[0:16], T)
	for j := 1; j < m; j++ {
		xorBlocks(MP, MP, C[j*16:(j+1)*16])
	}

	/* MC = AESenc(K; MP) */
	MC := make([]byte, 16)
	aesTransform(MC, MP, direction, bc)

	/* M = MP xor MC */
	M := make([]byte, 16)
	xorBlocks(M, MP, MC)
	CCCj := make([]byte, 16)
	for j := 1; j < m; j++ {
		multByTwo(M, M)
		/* CCCj = 2**(j-1)*M xor PPPj */
		xorBlocks(CCCj, C[j*16:(j+1)*16], M)
		copy(C[j*16:(j+1)*16], CCCj)
	}

	/* CCC1 = (xorSum CCCj) xor T xor MC */
	CCC1 := make([]byte, 16)
	xorBlocks(CCC1, MC, T)
	for j := 1; j < m; j++ {
		xorBlocks(CCC1, CCC1, C[j*16:(j+1)*16])
	}
	copy(C[0:16], CCC1)

	for j := 0; j < m; j++ {
		/* CCj = AES-enc(K; CCCj) */
		aesTransform(C[j*16:(j+1)*16], C[j*16:(j+1)*16], direction, bc)
		/* Cj = 2**(j-1)*L xor CCj */
		xorBlocks(C[j*16:(j+1)*16], C[j*16:(j+1)*16], LTable[j])
	}

	return C
}
<|endoftext|>


<commit_before>package fap

/*
#cgo LDFLAGS: -lfap
#include <stdlib.h>
#include <string.h>
#include <fap.h>

char* str_at(char **lst, int idx) {
    return lst[idx];
}
char* new_c_str(uint size) {
    return (char*) malloc( size*sizeof(char) );
}
fap_packet_type_t* packet_type(fap_packet_t *p) {
    return p->type;
}
*/
import "C"

import (
	"errors"
	"log"
	"time"
	"unsafe"
)

type fap_packet_t C.fap_packet_t

func init() {
	C.fap_init()
}

// Cleanup should be called when done using this package.
func Cleanup() {
	C.fap_cleanup()
}

// ParseAprs is the main parser method. Parses content of input
// string. Setting isAX25 to true source callsign and path
// elements are checked to be strictly compatible with AX.25
// specs so that theycan be sent into AX.25 network. Destination
// callsign is always checked this way.
func ParseAprs(input string, isAX25 bool) (*Packet, error) {
	c_input := C.CString(input)
	defer C.free(unsafe.Pointer(c_input))

	c_len := C.uint(C.strlen(c_input))

	var c_isAX25 C.short
	if isAX25 {
		c_isAX25 = 1
	}

	c_packet := C.fap_parseaprs(c_input, c_len, c_isAX25)
	defer C.fap_free(c_packet)

	if c_packet == nil {
		log.Fatal("fap_parseaprs returned nil. Is libfap initialized?")
	}

	packet, err := (*fap_packet_t)(c_packet).goPacket()

	return packet, err
}

// Calculates distance between given locations,
// returning the the distance in kilometers.
func Distance(lon0, lat0, lon1, lat1 float64) float64 {
	c_dist := C.fap_distance(
		C.double(lon0), C.double(lat0),
		C.double(lon1), C.double(lat1),
	)

	return float64(c_dist)
}

// Calculates direction from first to second location.
func Direction(lon0, lat0, lon1, lat1 float64) float64 {
	c_dir := C.fap_direction(
		C.double(lon0), C.double(lat0),
		C.double(lon1), C.double(lat1),
	)

	return float64(c_dir)
}

// MicEMbitsToMessage converts mic-e message bits (three numbers 0-2)
// to a textual message.
func MicEMbitsToMessage(mbits string) string {
	if mbits == "" {
		log.Fatal("MicEMbitsToMessage() called with empty string")
	}

	buffer := C.new_c_str(60)
	defer C.free(unsafe.Pointer(buffer))

	C.fap_mice_mbits_to_message(C.CString(mbits), buffer)

	return C.GoString(buffer)
}

func (c *fap_packet_t) goPacket() (*Packet, error) {
	err := c.error()

	packet := Packet{
		// error_code (removed)
		Type: UNKNOWN, // set below

		OrigPacket: goString(c.orig_packet),
		// orig_packet_len (removed)

		Header: goString(c.header),
		Body:   goString(c.body),
		// body_len (removed)

		SrcCallsign: goString(c.src_callsign),
		DstCallsign: goString(c.dst_callsign),
		// path (set below)
		// path_len (removed)

		Latitude:      goFloat64(c.latitude),
		Longitude:     goFloat64(c.longitude),
		PosResolution: goFloat64(c.pos_resolution),
		PosAmbiguity:  goUnsignedInt(c.pos_ambiguity),
		PosFormat: POS_UNKNOWN, // set below
		DaoDatumByte:  byte(c.dao_datum_byte), // 0x00 = undef
		Altitude:      goFloat64(c.altitude),
		Course:        goUnsignedInt(c.course),
		Speed:         goFloat64(c.speed),

		SymbolTable: byte(c.symbol_table), // 0x00 = undef
		SymbolCode:  byte(c.symbol_code),  // 0x00 = undef

		Messaging:   goBool(c.messaging),
		Destination: goString(c.destination),
		Message:     goString(c.message),
		MessageAck:  goString(c.message_ack),
		MessageNack: goString(c.message_nack),
		MessageId:   goString(c.message_id),

		// comment (set below)
		// comment_len (removed)

		ObjectOrItemName: goString(c.object_or_item_name),
		Alive:            goBool(c.alive),
		GpsFixStatus:     goBool(c.gps_fix_status),
		RadioRange:       goUnsignedInt(c.radio_range),
		Phg:              goString(c.phg),

		// timestamp (set below)
		NmeaChecksumOk: goBool(c.nmea_checksum_ok),

		// wx_report (TODO)
		// telemetry (TODO)

		Messagebits: goString(c.messagebits),

		// status (set below)

		// capabilities (TODO)
		// capabilities_len (removed)
	}

	if t := C.packet_type((*C.fap_packet_t)(c)); t != nil {
		packet.Type = PacketType(*t)
	}
	if c.format != nil {
		packet.PosFormat = PositionFormat(*c.format)
	}
	if c.status != nil {
		packet.Status = C.GoStringN(c.status, C.int(c.status_len))
	}
	if c.comment != nil {
		packet.Comment = C.GoStringN(c.comment, C.int(c.comment_len))
	}
	if c.timestamp != nil {
		packet.Timestamp = time.Unix(int64(*c.timestamp), 0)
	}

	// Get path
	packet.Path = make([]string, int(c.path_len))
	for i := 0; i < int(c.path_len); i++ {
		packet.Path[i] = goString(C.str_at(c.path, C.int(i)))
	}

	return &packet, err
}

func (c *fap_packet_t) error() error {
	if c.error_code == nil {
		return nil
	}

	buffer := C.new_c_str(64)
	defer C.free(unsafe.Pointer(buffer))

	C.fap_explain_error(*c.error_code, buffer)

	return errors.New(C.GoString(buffer))
}
<commit_msg>use unsigned int instead of uint for cross-platform compatibility<commit_after>package fap

/*
#cgo LDFLAGS: -lfap
#include <stdlib.h>
#include <string.h>
#include <fap.h>

char* str_at(char **lst, int idx) {
    return lst[idx];
}
char* new_c_str(unsigned int size) {
    return (char*) malloc( size*sizeof(char) );
}
fap_packet_type_t* packet_type(fap_packet_t *p) {
    return p->type;
}
*/
import "C"

import (
	"errors"
	"log"
	"time"
	"unsafe"
)

type fap_packet_t C.fap_packet_t

func init() {
	C.fap_init()
}

// Cleanup should be called when done using this package.
func Cleanup() {
	C.fap_cleanup()
}

// ParseAprs is the main parser method. Parses content of input
// string. Setting isAX25 to true source callsign and path
// elements are checked to be strictly compatible with AX.25
// specs so that theycan be sent into AX.25 network. Destination
// callsign is always checked this way.
func ParseAprs(input string, isAX25 bool) (*Packet, error) {
	c_input := C.CString(input)
	defer C.free(unsafe.Pointer(c_input))

	c_len := C.uint(C.strlen(c_input))

	var c_isAX25 C.short
	if isAX25 {
		c_isAX25 = 1
	}

	c_packet := C.fap_parseaprs(c_input, c_len, c_isAX25)
	defer C.fap_free(c_packet)

	if c_packet == nil {
		log.Fatal("fap_parseaprs returned nil. Is libfap initialized?")
	}

	packet, err := (*fap_packet_t)(c_packet).goPacket()

	return packet, err
}

// Calculates distance between given locations,
// returning the the distance in kilometers.
func Distance(lon0, lat0, lon1, lat1 float64) float64 {
	c_dist := C.fap_distance(
		C.double(lon0), C.double(lat0),
		C.double(lon1), C.double(lat1),
	)

	return float64(c_dist)
}

// Calculates direction from first to second location.
func Direction(lon0, lat0, lon1, lat1 float64) float64 {
	c_dir := C.fap_direction(
		C.double(lon0), C.double(lat0),
		C.double(lon1), C.double(lat1),
	)

	return float64(c_dir)
}

// MicEMbitsToMessage converts mic-e message bits (three numbers 0-2)
// to a textual message.
func MicEMbitsToMessage(mbits string) string {
	if mbits == "" {
		log.Fatal("MicEMbitsToMessage() called with empty string")
	}

	buffer := C.new_c_str(60)
	defer C.free(unsafe.Pointer(buffer))

	C.fap_mice_mbits_to_message(C.CString(mbits), buffer)

	return C.GoString(buffer)
}

func (c *fap_packet_t) goPacket() (*Packet, error) {
	err := c.error()

	packet := Packet{
		// error_code (removed)
		Type: UNKNOWN, // set below

		OrigPacket: goString(c.orig_packet),
		// orig_packet_len (removed)

		Header: goString(c.header),
		Body:   goString(c.body),
		// body_len (removed)

		SrcCallsign: goString(c.src_callsign),
		DstCallsign: goString(c.dst_callsign),
		// path (set below)
		// path_len (removed)

		Latitude:      goFloat64(c.latitude),
		Longitude:     goFloat64(c.longitude),
		PosResolution: goFloat64(c.pos_resolution),
		PosAmbiguity:  goUnsignedInt(c.pos_ambiguity),
		PosFormat: POS_UNKNOWN, // set below
		DaoDatumByte:  byte(c.dao_datum_byte), // 0x00 = undef
		Altitude:      goFloat64(c.altitude),
		Course:        goUnsignedInt(c.course),
		Speed:         goFloat64(c.speed),

		SymbolTable: byte(c.symbol_table), // 0x00 = undef
		SymbolCode:  byte(c.symbol_code),  // 0x00 = undef

		Messaging:   goBool(c.messaging),
		Destination: goString(c.destination),
		Message:     goString(c.message),
		MessageAck:  goString(c.message_ack),
		MessageNack: goString(c.message_nack),
		MessageId:   goString(c.message_id),

		// comment (set below)
		// comment_len (removed)

		ObjectOrItemName: goString(c.object_or_item_name),
		Alive:            goBool(c.alive),
		GpsFixStatus:     goBool(c.gps_fix_status),
		RadioRange:       goUnsignedInt(c.radio_range),
		Phg:              goString(c.phg),

		// timestamp (set below)
		NmeaChecksumOk: goBool(c.nmea_checksum_ok),

		// wx_report (TODO)
		// telemetry (TODO)

		Messagebits: goString(c.messagebits),

		// status (set below)

		// capabilities (TODO)
		// capabilities_len (removed)
	}

	if t := C.packet_type((*C.fap_packet_t)(c)); t != nil {
		packet.Type = PacketType(*t)
	}
	if c.format != nil {
		packet.PosFormat = PositionFormat(*c.format)
	}
	if c.status != nil {
		packet.Status = C.GoStringN(c.status, C.int(c.status_len))
	}
	if c.comment != nil {
		packet.Comment = C.GoStringN(c.comment, C.int(c.comment_len))
	}
	if c.timestamp != nil {
		packet.Timestamp = time.Unix(int64(*c.timestamp), 0)
	}

	// Get path
	packet.Path = make([]string, int(c.path_len))
	for i := 0; i < int(c.path_len); i++ {
		packet.Path[i] = goString(C.str_at(c.path, C.int(i)))
	}

	return &packet, err
}

func (c *fap_packet_t) error() error {
	if c.error_code == nil {
		return nil
	}

	buffer := C.new_c_str(64)
	defer C.free(unsafe.Pointer(buffer))

	C.fap_explain_error(*c.error_code, buffer)

	return errors.New(C.GoString(buffer))
}
<|endoftext|>


<commit_before>package raft

// FSM provides an interface that can be implemented by
// clients to make use of the replicated log
type FSM interface {
	// Apply log is invoked once a log entry is commited
	ApplyLog([]byte)
}
<commit_msg>Change FSM method to just Apply<commit_after>package raft

// FSM provides an interface that can be implemented by
// clients to make use of the replicated log
type FSM interface {
	// Apply log is invoked once a log entry is commited
	Apply([]byte)
}
<|endoftext|>


<commit_before>// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build ignore

// gen runs go generate on Unicode- and CLDR-related package in the text
// repositories, taking into account dependencies and versions.
package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/build"
	"go/format"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"regexp"
	"runtime"
	"strings"
	"sync"
	"unicode"

	"golang.org/x/text/collate"
	"golang.org/x/text/internal/gen"
	"golang.org/x/text/language"
)

var (
	verbose     = flag.Bool("v", false, "verbose output")
	force       = flag.Bool("force", false, "ignore failing dependencies")
	doCore      = flag.Bool("core", false, "force an update to core")
	excludeList = flag.String("exclude", "",
		"comma-separated list of packages to exclude")

	// The user can specify a selection of packages to build on the command line.
	args []string
)

func exclude(pkg string) bool {
	if len(args) > 0 {
		return !contains(args, pkg)
	}
	return contains(strings.Split(*excludeList, ","), pkg)
}

// TODO:
// - Better version handling.
// - Generate tables for the core unicode package?
// - Add generation for encodings. This requires some retooling here and there.
// - Running repo-wide "long" tests.

var vprintf = fmt.Printf

func main() {
	gen.Init()
	args = flag.Args()
	if !*verbose {
		// Set vprintf to a no-op.
		vprintf = func(string, ...interface{}) (int, error) { return 0, nil }
	}

	// TODO: create temporary cache directory to load files and create and set
	// a "cache" option if the user did not specify the UNICODE_DIR environment
	// variable. This will prevent duplicate downloads and also will enable long
	// tests, which really need to be run after each generated package.

	updateCore := *doCore
	if gen.UnicodeVersion() != unicode.Version {
		fmt.Printf("Requested Unicode version %s; core unicode version is %s.\n",
			gen.UnicodeVersion(),
			unicode.Version)
		c := collate.New(language.Und, collate.Numeric)
		if c.CompareString(gen.UnicodeVersion(), unicode.Version) < 0 && !*force {
			os.Exit(2)
		}
		updateCore = true
		goroot := os.Getenv("GOROOT")
		appendToFile(
			filepath.Join(goroot, "api", "except.txt"),
			fmt.Sprintf("pkg unicode, const Version = %q\n", unicode.Version),
		)
		const lines = `pkg unicode, const Version = %q
// TODO: add a new line of the following form for each new script and property.
pkg unicode, var <new script or property> *RangeTable
`
		appendToFile(
			filepath.Join(goroot, "api", "next.txt"),
			fmt.Sprintf(lines, gen.UnicodeVersion()),
		)
	}

	var unicode = &dependency{}
	if updateCore {
		fmt.Printf("Updating core to version %s...\n", gen.UnicodeVersion())
		unicode = generate("unicode")

		// Test some users of the unicode packages, especially the ones that
		// keep a mirrored table. These may need to be corrected by hand.
		generate("regexp", unicode)
		generate("strconv", unicode) // mimics Unicode table
		generate("strings", unicode)
		generate("testing", unicode) // mimics Unicode table
	}

	var (
		cldr       = generate("./unicode/cldr", unicode)
		compact    = generate("./internal/language/compact", cldr)
		language   = generate("./language", cldr, compact)
		internal   = generate("./internal", unicode, language)
		norm       = generate("./unicode/norm", unicode)
		rangetable = generate("./unicode/rangetable", unicode)
		cases      = generate("./cases", unicode, norm, language, rangetable)
		width      = generate("./width", unicode)
		bidi       = generate("./unicode/bidi", unicode, norm, rangetable)
		mib        = generate("./encoding/internal/identifier", unicode)
		number     = generate("./internal/number", unicode, cldr, language, internal)
		cldrtree   = generate("./internal/cldrtree", language, internal)
		_          = generate("./unicode/runenames", unicode)
		_          = generate("./encoding/htmlindex", unicode, language, mib)
		_          = generate("./encoding/ianaindex", unicode, language, mib)
		_          = generate("./secure/precis", unicode, norm, rangetable, cases, width, bidi)
		_          = generate("./currency", unicode, cldr, language, internal, number)
		_          = generate("./feature/plural", unicode, cldr, language, internal, number)
		_          = generate("./internal/export/idna", unicode, bidi, norm)
		_          = generate("./language/display", unicode, cldr, language, internal, number)
		_          = generate("./collate", unicode, norm, cldr, language, rangetable)
		_          = generate("./search", unicode, norm, cldr, language, rangetable)
		_          = generate("./date", cldr, language, cldrtree)
	)
	all.Wait()

	// Copy exported packages to the destination golang.org repo.
	copyExported("golang.org/x/net/idna")

	if updateCore {
		copyVendored()
	}

	if hasErrors {
		fmt.Println("FAIL")
		os.Exit(1)
	}
	vprintf("SUCCESS\n")
}

func appendToFile(file, text string) {
	fmt.Println("Augmenting", file)
	w, err := os.OpenFile(file, os.O_APPEND|os.O_WRONLY, 0600)
	if err != nil {
		fmt.Println("Failed to open file:", err)
		os.Exit(1)
	}
	defer w.Close()
	if _, err := w.WriteString(text); err != nil {
		fmt.Println("Failed to write to file:", err)
		os.Exit(1)
	}
}

var (
	all       sync.WaitGroup
	hasErrors bool
)

type dependency struct {
	sync.WaitGroup
	hasErrors bool
}

func generate(pkg string, deps ...*dependency) *dependency {
	var wg dependency
	if exclude(pkg) {
		return &wg
	}
	wg.Add(1)
	all.Add(1)
	go func() {
		defer wg.Done()
		defer all.Done()
		// Wait for dependencies to finish.
		for _, d := range deps {
			d.Wait()
			if d.hasErrors && !*force {
				fmt.Printf("--- ABORT: %s\n", pkg)
				wg.hasErrors = true
				return
			}
		}
		vprintf("=== GENERATE %s\n", pkg)
		args := []string{"generate"}
		if *verbose {
			args = append(args, "-v")
		}
		args = append(args, pkg)
		cmd := exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), args...)
		w := &bytes.Buffer{}
		cmd.Stderr = w
		cmd.Stdout = w
		if err := cmd.Run(); err != nil {
			fmt.Printf("--- FAIL: %s:\n\t%v\n\tError: %v\n", pkg, indent(w), err)
			hasErrors = true
			wg.hasErrors = true
			return
		}

		vprintf("=== TEST %s\n", pkg)
		args[0] = "test"
		cmd = exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), args...)
		wt := &bytes.Buffer{}
		cmd.Stderr = wt
		cmd.Stdout = wt
		if err := cmd.Run(); err != nil {
			fmt.Printf("--- FAIL: %s:\n\t%v\n\tError: %v\n", pkg, indent(wt), err)
			hasErrors = true
			wg.hasErrors = true
			return
		}
		vprintf("--- SUCCESS: %s\n\t%v\n", pkg, indent(w))
		fmt.Print(wt.String())
	}()
	return &wg
}

// copyExported copies a package in x/text/internal/export to the
// destination repository.
func copyExported(p string) {
	copyPackage(
		filepath.Join("internal", "export", path.Base(p)),
		filepath.Join("..", filepath.FromSlash(p[len("golang.org/x"):])),
		"golang.org/x/text/internal/export/"+path.Base(p),
		p)
}

// copyVendored copies packages used by Go core into the vendored directory.
func copyVendored() {
	root := filepath.Join(build.Default.GOROOT, filepath.FromSlash("src/vendor/golang_org/x"))

	err := filepath.Walk(root, func(dir string, info os.FileInfo, err error) error {
		if err != nil || !info.IsDir() || root == dir {
			return err
		}
		src := dir[len(root)+1:]
		const slash = string(filepath.Separator)
		if c := strings.Split(src, slash); c[0] == "text" {
			// Copy a text repo package from its normal location.
			src = strings.Join(c[1:], slash)
		} else {
			// Copy the vendored package if it exists in the export directory.
			src = filepath.Join("internal", "export", filepath.Base(src))
		}
		copyPackage(src, dir, "golang.org", "golang_org")
		return nil
	})
	if err != nil {
		fmt.Printf("Seeding directory %s has failed %v:", root, err)
		os.Exit(1)
	}
}

// goGenRE is used to remove go:generate lines.
var goGenRE = regexp.MustCompile("//go:generate[^\n]*\n")

// copyPackage copies relevant files from a directory in x/text to the
// destination package directory. The destination package is assumed to have
// the same name. For each copied file go:generate lines are removed and
// package comments are rewritten to the new path.
func copyPackage(dirSrc, dirDst, search, replace string) {
	err := filepath.Walk(dirSrc, func(file string, info os.FileInfo, err error) error {
		base := filepath.Base(file)
		if err != nil || info.IsDir() ||
			!strings.HasSuffix(base, ".go") ||
			strings.HasSuffix(base, "_test.go") ||
			// Don't process subdirectories.
			filepath.Dir(file) != dirSrc {
			return nil
		}
		b, err := ioutil.ReadFile(file)
		if err != nil || bytes.Contains(b, []byte("\n// +build ignore")) {
			return err
		}
		// Fix paths.
		b = bytes.Replace(b, []byte(search), []byte(replace), -1)
		// Remove go:generate lines.
		b = goGenRE.ReplaceAllLiteral(b, nil)
		comment := "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n"
		if *doCore {
			comment = "// Code generated by running \"go run gen.go -core\" in golang.org/x/text. DO NOT EDIT.\n\n"
		}
		if !bytes.HasPrefix(b, []byte(comment)) {
			b = append([]byte(comment), b...)
		}
		if b, err = format.Source(b); err != nil {
			fmt.Println("Failed to format file:", err)
			os.Exit(1)
		}
		file = filepath.Join(dirDst, base)
		vprintf("=== COPY %s\n", file)
		return ioutil.WriteFile(file, b, 0666)
	})
	if err != nil {
		fmt.Println("Copying exported files failed:", err)
		os.Exit(1)
	}
}

func contains(a []string, s string) bool {
	for _, e := range a {
		if s == e {
			return true
		}
	}
	return false
}

func indent(b *bytes.Buffer) string {
	return strings.Replace(strings.TrimSpace(b.String()), "\n", "\n\t", -1)
}
<commit_msg>gen.go: fix breakage due to changes in core<commit_after>// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build ignore

// gen runs go generate on Unicode- and CLDR-related package in the text
// repositories, taking into account dependencies and versions.
package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/build"
	"go/format"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"regexp"
	"runtime"
	"strings"
	"sync"
	"unicode"

	"golang.org/x/text/collate"
	"golang.org/x/text/internal/gen"
	"golang.org/x/text/language"
)

var (
	verbose     = flag.Bool("v", false, "verbose output")
	force       = flag.Bool("force", false, "ignore failing dependencies")
	doCore      = flag.Bool("core", false, "force an update to core")
	excludeList = flag.String("exclude", "",
		"comma-separated list of packages to exclude")

	// The user can specify a selection of packages to build on the command line.
	args []string
)

func exclude(pkg string) bool {
	if len(args) > 0 {
		return !contains(args, pkg)
	}
	return contains(strings.Split(*excludeList, ","), pkg)
}

// TODO:
// - Better version handling.
// - Generate tables for the core unicode package?
// - Add generation for encodings. This requires some retooling here and there.
// - Running repo-wide "long" tests.

var vprintf = fmt.Printf

func main() {
	gen.Init()
	args = flag.Args()
	if !*verbose {
		// Set vprintf to a no-op.
		vprintf = func(string, ...interface{}) (int, error) { return 0, nil }
	}

	// TODO: create temporary cache directory to load files and create and set
	// a "cache" option if the user did not specify the UNICODE_DIR environment
	// variable. This will prevent duplicate downloads and also will enable long
	// tests, which really need to be run after each generated package.

	updateCore := *doCore
	if gen.UnicodeVersion() != unicode.Version {
		fmt.Printf("Requested Unicode version %s; core unicode version is %s.\n",
			gen.UnicodeVersion(),
			unicode.Version)
		c := collate.New(language.Und, collate.Numeric)
		if c.CompareString(gen.UnicodeVersion(), unicode.Version) < 0 && !*force {
			os.Exit(2)
		}
		updateCore = true
		goroot := os.Getenv("GOROOT")
		appendToFile(
			filepath.Join(goroot, "api", "except.txt"),
			fmt.Sprintf("pkg unicode, const Version = %q\n", unicode.Version),
		)
		const lines = `pkg unicode, const Version = %q
// TODO: add a new line of the following form for each new script and property.
pkg unicode, var <new script or property> *RangeTable
`
		appendToFile(
			filepath.Join(goroot, "api", "next.txt"),
			fmt.Sprintf(lines, gen.UnicodeVersion()),
		)
	}

	var unicode = &dependency{}
	if updateCore {
		fmt.Printf("Updating core to version %s...\n", gen.UnicodeVersion())
		unicode = generate("unicode")

		// Test some users of the unicode packages, especially the ones that
		// keep a mirrored table. These may need to be corrected by hand.
		generate("regexp", unicode)
		generate("strconv", unicode) // mimics Unicode table
		generate("strings", unicode)
		generate("testing", unicode) // mimics Unicode table
	}

	var (
		cldr       = generate("./unicode/cldr", unicode)
		compact    = generate("./internal/language/compact", cldr)
		language   = generate("./language", cldr, compact)
		internal   = generate("./internal", unicode, language)
		norm       = generate("./unicode/norm", unicode)
		rangetable = generate("./unicode/rangetable", unicode)
		cases      = generate("./cases", unicode, norm, language, rangetable)
		width      = generate("./width", unicode)
		bidi       = generate("./unicode/bidi", unicode, norm, rangetable)
		mib        = generate("./encoding/internal/identifier", unicode)
		number     = generate("./internal/number", unicode, cldr, language, internal)
		cldrtree   = generate("./internal/cldrtree", language, internal)
		_          = generate("./unicode/runenames", unicode)
		_          = generate("./encoding/htmlindex", unicode, language, mib)
		_          = generate("./encoding/ianaindex", unicode, language, mib)
		_          = generate("./secure/precis", unicode, norm, rangetable, cases, width, bidi)
		_          = generate("./currency", unicode, cldr, language, internal, number)
		_          = generate("./feature/plural", unicode, cldr, language, internal, number)
		_          = generate("./internal/export/idna", unicode, bidi, norm)
		_          = generate("./language/display", unicode, cldr, language, internal, number)
		_          = generate("./collate", unicode, norm, cldr, language, rangetable)
		_          = generate("./search", unicode, norm, cldr, language, rangetable)
		_          = generate("./date", cldr, language, cldrtree)
	)
	all.Wait()

	// Copy exported packages to the destination golang.org repo.
	copyExported("golang.org/x/net/idna")

	if updateCore {
		copyInternal()
	}

	if hasErrors {
		fmt.Println("FAIL")
		os.Exit(1)
	}
	vprintf("SUCCESS\n")
}

func appendToFile(file, text string) {
	fmt.Println("Augmenting", file)
	w, err := os.OpenFile(file, os.O_APPEND|os.O_WRONLY, 0600)
	if err != nil {
		fmt.Println("Failed to open file:", err)
		os.Exit(1)
	}
	defer w.Close()
	if _, err := w.WriteString(text); err != nil {
		fmt.Println("Failed to write to file:", err)
		os.Exit(1)
	}
}

var (
	all       sync.WaitGroup
	hasErrors bool
)

type dependency struct {
	sync.WaitGroup
	hasErrors bool
}

func generate(pkg string, deps ...*dependency) *dependency {
	var wg dependency
	if exclude(pkg) {
		return &wg
	}
	wg.Add(1)
	all.Add(1)
	go func() {
		defer wg.Done()
		defer all.Done()
		// Wait for dependencies to finish.
		for _, d := range deps {
			d.Wait()
			if d.hasErrors && !*force {
				fmt.Printf("--- ABORT: %s\n", pkg)
				wg.hasErrors = true
				return
			}
		}
		vprintf("=== GENERATE %s\n", pkg)
		args := []string{"generate"}
		if *verbose {
			args = append(args, "-v")
		}
		args = append(args, pkg)
		cmd := exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), args...)
		w := &bytes.Buffer{}
		cmd.Stderr = w
		cmd.Stdout = w
		if err := cmd.Run(); err != nil {
			fmt.Printf("--- FAIL: %s:\n\t%v\n\tError: %v\n", pkg, indent(w), err)
			hasErrors = true
			wg.hasErrors = true
			return
		}

		vprintf("=== TEST %s\n", pkg)
		args[0] = "test"
		cmd = exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), args...)
		wt := &bytes.Buffer{}
		cmd.Stderr = wt
		cmd.Stdout = wt
		if err := cmd.Run(); err != nil {
			fmt.Printf("--- FAIL: %s:\n\t%v\n\tError: %v\n", pkg, indent(wt), err)
			hasErrors = true
			wg.hasErrors = true
			return
		}
		vprintf("--- SUCCESS: %s\n\t%v\n", pkg, indent(w))
		fmt.Print(wt.String())
	}()
	return &wg
}

// copyExported copies a package in x/text/internal/export to the
// destination repository.
func copyExported(p string) {
	copyPackage(
		filepath.Join("internal", "export", path.Base(p)),
		filepath.Join("..", filepath.FromSlash(p[len("golang.org/x"):])),
		"golang.org/x/text/internal/export/"+path.Base(p),
		p)
}

// copyInternal copies packages used by Go core into the internal directory.
func copyInternal() {
	root := filepath.Join(build.Default.GOROOT, filepath.FromSlash("src/internal/x"))

	err := filepath.Walk(root, func(dir string, info os.FileInfo, err error) error {
		if err != nil || !info.IsDir() || root == dir {
			return err
		}
		src := dir[len(root)+1:]
		const slash = string(filepath.Separator)
		if c := strings.Split(src, slash); c[0] == "text" {
			// Copy a text repo package from its normal location.
			src = strings.Join(c[1:], slash)
		} else {
			// Copy the vendored package if it exists in the export directory.
			src = filepath.Join("internal", "export", filepath.Base(src))
		}
		copyPackage(src, dir, "golang.org", "internal")
		return nil
	})
	if err != nil {
		fmt.Printf("Seeding directory %s has failed %v:", root, err)
		os.Exit(1)
	}
}

// goGenRE is used to remove go:generate lines.
var goGenRE = regexp.MustCompile("//go:generate[^\n]*\n")

// copyPackage copies relevant files from a directory in x/text to the
// destination package directory. The destination package is assumed to have
// the same name. For each copied file go:generate lines are removed and
// package comments are rewritten to the new path.
func copyPackage(dirSrc, dirDst, search, replace string) {
	err := filepath.Walk(dirSrc, func(file string, info os.FileInfo, err error) error {
		base := filepath.Base(file)
		if err != nil || info.IsDir() ||
			!strings.HasSuffix(base, ".go") ||
			strings.HasSuffix(base, "_test.go") ||
			// Don't process subdirectories.
			filepath.Dir(file) != dirSrc {
			return nil
		}
		if strings.HasPrefix(base, "tables") {
			if !strings.HasSuffix(base, gen.UnicodeVersion()+".go") {
				return nil
			}
			base = "tables.go"
		}
		b, err := ioutil.ReadFile(file)
		if err != nil || bytes.Contains(b, []byte("\n// +build ignore")) {
			return err
		}
		// Fix paths.
		b = bytes.Replace(b, []byte(search), []byte(replace), -1)
		b = bytes.Replace(b, []byte("internal/export"), []byte(""), -1)
		// Remove go:generate lines.
		b = goGenRE.ReplaceAllLiteral(b, nil)
		comment := "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n"
		if !bytes.HasPrefix(b, []byte(comment)) {
			b = append([]byte(comment), b...)
		}
		if b, err = format.Source(b); err != nil {
			fmt.Println("Failed to format file:", err)
			os.Exit(1)
		}
		file = filepath.Join(dirDst, base)
		vprintf("=== COPY %s\n", file)
		return ioutil.WriteFile(file, b, 0666)
	})
	if err != nil {
		fmt.Println("Copying exported files failed:", err)
		os.Exit(1)
	}
}

func contains(a []string, s string) bool {
	for _, e := range a {
		if s == e {
			return true
		}
	}
	return false
}

func indent(b *bytes.Buffer) string {
	return strings.Replace(strings.TrimSpace(b.String()), "\n", "\n\t", -1)
}
<|endoftext|>


<commit_before>package main

import (
	_ "errors"
	"flag"
	_ "fmt"
	_ "gmq/queue"
	"os"
)

var configfile string

func main() {

	flag.StringVar(&configfile, "f", "gmq.conf", "Configuration file")
	flag.Parse()

	//	if err := parseConfigFile(configfile); err != nil {
	//		panic(errors.New("Unable to parse configuration file %s"))
	//	}
}

func parseConfigFile(f string) error {
	//TODO
	_, err := os.Open(f)
	return err
}
<commit_msg>Adapting to configuration<commit_after>package main

import (
	"flag"
)

var configfile string

func main() {

	flag.StringVar(&configfile, "f", "/etc/gmq/gmq.json", "Configuration file")
	flag.Parse()

	//	if err := parseConfigFile(configfile); err != nil {
	//		panic(errors.New("Unable to parse configuration file %s"))
	//	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"path/filepath"
)

var programName string

func init() {
	programName = filepath.Base(os.Args[0])
}

func main() {
	commands := map[string]command{
		"ruler": makeRulerCommand(),
	}

	flag.Usage = func() {
		fmt.Printf("%s is a Twitter command-line interface.\n\n", programName)
		var maxCommandLen int
		for name := range commands {
			if len := len(name); len > maxCommandLen {
				maxCommandLen = len
			}
		}
		for name, subcommand := range commands {
			formatString := fmt.Sprintf("%%%ds: %%s\n", maxCommandLen)
			fmt.Printf(formatString, name, subcommand.desc)
		}
	}

	flag.Parse()

	args := flag.Args()

	if len(args) <= 0 {
		flag.Usage()
		os.Exit(2)
	}
	cmd, ok := commands[args[0]]
	if !ok {
		printError("%q is not a valid subcommand\n", args[0])
		os.Exit(1)
	}
	if err := cmd.fn(args[1:]); err != nil {
		printError("error running %q: %s", args[0], err)
		os.Exit(1)
	}
}

type command struct {
	fs   *flag.FlagSet
	desc string
	fn   func([]string) error
}

func makeRulerCommand() command {
	fs := flag.NewFlagSet("ruler", flag.ExitOnError)
	spacesToIndent := fs.Int("indent", 0, "the number of spaces to print before the ruler")
	fn := func(args []string) error {
		fs.Parse(args)
		_, err := fmt.Println(ruler(*spacesToIndent))
		return err
	}
	return command{
		fs:   fs,
		desc: "prints a 140-character ruler",
		fn:   fn,
	}
}

func ruler(spacesToIndent int) string {
	var ruler string
	for i := 0; i < spacesToIndent; i++ {
		ruler += " "
	}
	for i := 1; i <= 140; i++ {
		if i%5 == 0 {
			ruler += "|"
		} else {
			ruler += "-"
		}
	}
	return ruler
}

func printError(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, programName+": "+format, args...)
}
<commit_msg>Add help subcommand that outputs usage information<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"path/filepath"
)

var programName string

func init() {
	programName = filepath.Base(os.Args[0])
}

func main() {
	commands := map[string]command{
		"ruler": makeRulerCommand(),
	}

	flag.Usage = func() {
		fmt.Printf("%s is a command-line interface to Twitter.\n\n", programName)
		var maxCommandLen int
		for name := range commands {
			if len := len(name); len > maxCommandLen {
				maxCommandLen = len
			}
		}
		for name, subcommand := range commands {
			formatString := fmt.Sprintf("%%%ds: %%s\n", maxCommandLen)
			fmt.Printf(formatString, name, subcommand.desc)
		}
	}

	flag.Parse()

	args := flag.Args()

	if len(args) <= 0 || args[0] == "help" {
		flag.Usage()
		os.Exit(2)
	}
	cmd, ok := commands[args[0]]
	if !ok {
		printError("unknown subcommand %q\nRun '%s help' for usage.\n", args[0], programName)
		os.Exit(1)
	}
	if err := cmd.fn(args[1:]); err != nil {
		printError("error running %q: %s", args[0], err)
		os.Exit(1)
	}
}

type command struct {
	fs   *flag.FlagSet
	desc string
	fn   func([]string) error
}

func makeRulerCommand() command {
	fs := flag.NewFlagSet("ruler", flag.ExitOnError)
	spacesToIndent := fs.Int("indent", 0, "the number of spaces to print before the ruler")
	fn := func(args []string) error {
		fs.Parse(args)
		_, err := fmt.Println(ruler(*spacesToIndent))
		return err
	}
	return command{
		fs:   fs,
		desc: "prints a 140-character ruler",
		fn:   fn,
	}
}

func ruler(spacesToIndent int) string {
	var ruler string
	for i := 0; i < spacesToIndent; i++ {
		ruler += " "
	}
	for i := 1; i <= 140; i++ {
		if i%5 == 0 {
			ruler += "|"
		} else {
			ruler += "-"
		}
	}
	return ruler
}

func printError(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, programName+": "+format, args...)
}
<|endoftext|>