<commit_before>// Copyright © 2017 Sascha Andres <sascha.andres@outlook.com>
// 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 cmd

import (
	"io"
	"log"
	"os"
	"path"
	"strings"

	"github.com/chzyer/readline"
	"github.com/sascha-andres/devenv"
	"github.com/sascha-andres/devenv/helper"
	"github.com/sascha-andres/devenv/shell"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var ev devenv.EnvironmentConfiguration

var completer = readline.NewPrefixCompleter(
	readline.PcItem("repo",
		readline.PcItemDynamic(listRepositories(),
			readline.PcItem("branch"),
			readline.PcItem("commit"),
			readline.PcItem("log"),
			readline.PcItem("pull"),
			readline.PcItem("push"),
			readline.PcItem("status"),
		),
	),
	readline.PcItem("addrepo"),
	readline.PcItem("branch"),
	readline.PcItem("commit"),
	readline.PcItem("delrepo"),
	readline.PcItem("log"),
	readline.PcItem("pull"),
	readline.PcItem("push"),
	readline.PcItem("status"),
	readline.PcItem("quit"),
)

func filterInput(r rune) (rune, bool) {
	switch r {
	// block CtrlZ feature
	case readline.CharCtrlZ:
		return r, false
	}
	return r, true
}

// shellCmd represents the shell command
var shellCmd = &cobra.Command{
	Use:   "shell",
	Short: "Start devenv shell",
	Long:  `Devenv shell allows to work with all repositories at once.`,
	Run: func(cmd *cobra.Command, args []string) {
		projectName := strings.Join(args, " ")
		log.Printf("Called to start shell for '%s'\n", projectName)
		if "" == projectName || !devenv.ProjectIsCreated(projectName) {
			log.Fatalf("Project '%s' does not yet exist", projectName)
		}
		if ok, err := helper.Exists(path.Join(viper.GetString("configpath"), projectName+".yaml")); ok && err == nil {
			if err := ev.LoadFromFile(path.Join(viper.GetString("configpath"), projectName+".yaml")); err != nil {
				log.Fatalf("Error reading env config: '%s'", err.Error())
			}
		}

		interp := shell.NewInterpreter(path.Join(viper.GetString("basepath"), projectName), ev)
		l, err := readline.NewEx(&readline.Config{
			Prompt:          "\033[31m»\033[0m ",
			HistoryFile:     "/tmp/devenv-" + projectName + ".tmp",
			AutoComplete:    completer,
			InterruptPrompt: "^C",
			EOFPrompt:       "exit",

			HistorySearchFold:   true,
			FuncFilterInputRune: filterInput,
		})
		if err != nil {
			log.Fatalln(err)
		}
		defer l.Close()

		log.SetOutput(l.Stderr())

		for {
			line, err := l.Readline()
			if err == readline.ErrInterrupt {
				if len(line) == 0 {
					break
				} else {
					continue
				}
			} else if err == io.EOF {
				break
			}

			line = strings.TrimSpace(line)
			switch line {
			case "quit", "q":
				os.Exit(0)
				break
			default:
				interp.Execute(line)
				break
			}
		}
	},
}

func listRepositories() func(string) []string {
	return func(line string) []string {
		var repositories []string
		for _, val := range ev.Repositories {
			if !val.Disabled {
				repositories = append(repositories, val.Name)
			}
		}
		return repositories
	}
}

func init() {
	RootCmd.AddCommand(shellCmd)
}
<commit_msg>Printing out errors<commit_after>// Copyright © 2017 Sascha Andres <sascha.andres@outlook.com>
// 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 cmd

import (
	"io"
	"log"
	"os"
	"path"
	"strings"

	"github.com/chzyer/readline"
	"github.com/sascha-andres/devenv"
	"github.com/sascha-andres/devenv/helper"
	"github.com/sascha-andres/devenv/shell"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var ev devenv.EnvironmentConfiguration

var completer = readline.NewPrefixCompleter(
	readline.PcItem("repo",
		readline.PcItemDynamic(listRepositories(),
			readline.PcItem("branch"),
			readline.PcItem("commit"),
			readline.PcItem("log"),
			readline.PcItem("pull"),
			readline.PcItem("push"),
			readline.PcItem("status"),
		),
	),
	readline.PcItem("addrepo"),
	readline.PcItem("branch"),
	readline.PcItem("commit"),
	readline.PcItem("delrepo"),
	readline.PcItem("log"),
	readline.PcItem("pull"),
	readline.PcItem("push"),
	readline.PcItem("status"),
	readline.PcItem("quit"),
)

func filterInput(r rune) (rune, bool) {
	switch r {
	// block CtrlZ feature
	case readline.CharCtrlZ:
		return r, false
	}
	return r, true
}

// shellCmd represents the shell command
var shellCmd = &cobra.Command{
	Use:   "shell",
	Short: "Start devenv shell",
	Long:  `Devenv shell allows to work with all repositories at once.`,
	Run: func(cmd *cobra.Command, args []string) {
		projectName := strings.Join(args, " ")
		log.Printf("Called to start shell for '%s'\n", projectName)
		if "" == projectName || !devenv.ProjectIsCreated(projectName) {
			log.Fatalf("Project '%s' does not yet exist", projectName)
		}
		if ok, err := helper.Exists(path.Join(viper.GetString("configpath"), projectName+".yaml")); ok && err == nil {
			if err := ev.LoadFromFile(path.Join(viper.GetString("configpath"), projectName+".yaml")); err != nil {
				log.Fatalf("Error reading env config: '%s'", err.Error())
			}
		}

		interp := shell.NewInterpreter(path.Join(viper.GetString("basepath"), projectName), ev)
		l, err := readline.NewEx(&readline.Config{
			Prompt:          "\033[31m»\033[0m ",
			HistoryFile:     "/tmp/devenv-" + projectName + ".tmp",
			AutoComplete:    completer,
			InterruptPrompt: "^C",
			EOFPrompt:       "exit",

			HistorySearchFold:   true,
			FuncFilterInputRune: filterInput,
		})
		if err != nil {
			log.Fatalln(err)
		}
		defer l.Close()

		log.SetOutput(l.Stderr())

		for {
			line, err := l.Readline()
			if err == readline.ErrInterrupt {
				if len(line) == 0 {
					break
				} else {
					continue
				}
			} else if err == io.EOF {
				break
			}

			line = strings.TrimSpace(line)
			switch line {
			case "quit", "q":
				os.Exit(0)
				break
			default:
				err := interp.Execute(line)
				if err != nil {
					log.Printf("Error: %s", err.Error())
				}
				break
			}
		}
	},
}

func listRepositories() func(string) []string {
	return func(line string) []string {
		var repositories []string
		for _, val := range ev.Repositories {
			if !val.Disabled {
				repositories = append(repositories, val.Name)
			}
		}
		return repositories
	}
}

func init() {
	RootCmd.AddCommand(shellCmd)
}
<|endoftext|>


<commit_before>// Redwood is an internet content-filtering program.
// It is designed to replace and improve on DansGuardian
// as the core of the Security Appliance internet filter.
package main

import (
	"code.google.com/p/go-icap"
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	_ "net/http/pprof"
	"os"
	"runtime"
	"strings"
)

var testURL = flag.String("test", "", "URL to test instead of running ICAP server")
var pidfile = flag.String("pidfile", "", "path of file to store process ID")
var proxyAddresses = ListFlag("http-proxy", "address (host:port) to listen for proxy connections on")
var transparentAddresses = ListFlag("transparent-https", "address to listen for intercepted HTTPS connections on")
var icapAddresses = ListFlag("icap-server", "address to listen for ICAP connections on")

func main() {
	loadConfiguration()

	if *pidfile != "" {
		pid := os.Getpid()
		f, err := os.Create(*pidfile)
		if err == nil {
			fmt.Fprintln(f, pid)
			f.Close()
		} else {
			log.Println("could not create pidfile:", err)
		}
	}

	runtime.GOMAXPROCS(runtime.NumCPU())

	if *testURL != "" {
		runURLTest(*testURL)
		return
	}

	go accessLog()

	startWebServer()

	portsListening := 0

	if len(*proxyAddresses) > 0 {
		for _, addr := range *proxyAddresses {
			proxyListener, err := net.Listen("tcp", addr)
			if err != nil {
				log.Fatalf("error listening for connections on %s: %s", addr, err)
			}
			listenerChan <- proxyListener
			server := http.Server{Handler: proxyHandler{}}
			go func() {
				err = server.Serve(proxyListener)
				if err != nil && !strings.Contains(err.Error(), "use of closed") {
					log.Fatalln("Error running HTTP proxy:", err)
				}
			}()
			portsListening++
		}
	}

	if len(*transparentAddresses) > 0 {
		if !tlsReady {
			log.Fatal("Can't run a transparent HTTPS proxy without server certificates configured.")
		}
		for _, addr := range *transparentAddresses {
			go func() {
				err := runTransparentServer(addr)
				if err != nil && !strings.Contains(err.Error(), "use of closed") {
					log.Fatalln("Error running transparent HTTPS proxy:", err)
				}
			}()
			portsListening++
		}
	}

	if len(*icapAddresses) > 0 {
		icap.HandleFunc("/reqmod", handleRequest)
		icap.HandleFunc("/respmod", handleResponse)
		for _, addr := range *icapAddresses {
			icapListener, err := net.Listen("tcp", addr)
			if err != nil {
				log.Fatalf("error listening for connections on %s: %s", addr, err)
			}
			listenerChan <- icapListener
			go func() {
				err := new(icap.Server).Serve(icapListener)
				if err != nil && !strings.Contains(err.Error(), "use of closed") {
					log.Fatalln("Error running ICAP server:", err)
				}
			}()
			portsListening++
		}
		reloadSquid()
	}

	if portsListening > 0 {
		// Wait forever (or until somebody calls log.Fatal).
		select {}
	}
}
<commit_msg>Respect GOMAXPROCS environment variable.<commit_after>// Redwood is an internet content-filtering program.
// It is designed to replace and improve on DansGuardian
// as the core of the Security Appliance internet filter.
package main

import (
	"code.google.com/p/go-icap"
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	_ "net/http/pprof"
	"os"
	"strings"
)

var testURL = flag.String("test", "", "URL to test instead of running ICAP server")
var pidfile = flag.String("pidfile", "", "path of file to store process ID")
var proxyAddresses = ListFlag("http-proxy", "address (host:port) to listen for proxy connections on")
var transparentAddresses = ListFlag("transparent-https", "address to listen for intercepted HTTPS connections on")
var icapAddresses = ListFlag("icap-server", "address to listen for ICAP connections on")

func main() {
	loadConfiguration()

	if *pidfile != "" {
		pid := os.Getpid()
		f, err := os.Create(*pidfile)
		if err == nil {
			fmt.Fprintln(f, pid)
			f.Close()
		} else {
			log.Println("could not create pidfile:", err)
		}
	}

	if *testURL != "" {
		runURLTest(*testURL)
		return
	}

	go accessLog()

	startWebServer()

	portsListening := 0

	if len(*proxyAddresses) > 0 {
		for _, addr := range *proxyAddresses {
			proxyListener, err := net.Listen("tcp", addr)
			if err != nil {
				log.Fatalf("error listening for connections on %s: %s", addr, err)
			}
			listenerChan <- proxyListener
			server := http.Server{Handler: proxyHandler{}}
			go func() {
				err = server.Serve(proxyListener)
				if err != nil && !strings.Contains(err.Error(), "use of closed") {
					log.Fatalln("Error running HTTP proxy:", err)
				}
			}()
			portsListening++
		}
	}

	if len(*transparentAddresses) > 0 {
		if !tlsReady {
			log.Fatal("Can't run a transparent HTTPS proxy without server certificates configured.")
		}
		for _, addr := range *transparentAddresses {
			go func() {
				err := runTransparentServer(addr)
				if err != nil && !strings.Contains(err.Error(), "use of closed") {
					log.Fatalln("Error running transparent HTTPS proxy:", err)
				}
			}()
			portsListening++
		}
	}

	if len(*icapAddresses) > 0 {
		icap.HandleFunc("/reqmod", handleRequest)
		icap.HandleFunc("/respmod", handleResponse)
		for _, addr := range *icapAddresses {
			icapListener, err := net.Listen("tcp", addr)
			if err != nil {
				log.Fatalf("error listening for connections on %s: %s", addr, err)
			}
			listenerChan <- icapListener
			go func() {
				err := new(icap.Server).Serve(icapListener)
				if err != nil && !strings.Contains(err.Error(), "use of closed") {
					log.Fatalln("Error running ICAP server:", err)
				}
			}()
			portsListening++
		}
		reloadSquid()
	}

	if portsListening > 0 {
		// Wait forever (or until somebody calls log.Fatal).
		select {}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"net/http"
)

func commentApprove(commentHex string) error {
	if commentHex == "" {
		return errorMissingField
	}

	statement := `
		UPDATE comments
    SET state = 'approved'
		WHERE commentHex = $1;
	`

	_, err := db.Exec(statement, commentHex)
	if err != nil {
		logger.Errorf("cannot approve comment: %v", err)
		return errorInternal
	}

	return nil
}

func commentApproveHandler(w http.ResponseWriter, r *http.Request) {
	type request struct {
		Session    *string `json:"session"`
		CommentHex *string `json:"commentHex"`
	}

	var x request
	if err := unmarshalBody(r, &x); err != nil {
		writeBody(w, response{"success": false, "message": err.Error()})
		return
	}

	c, err := commenterGetBySession(*x.Session)
	if err != nil {
		writeBody(w, response{"success": false, "message": err.Error()})
		return
	}

	domain, err := commentDomainGet(*x.CommentHex)
	if err != nil {
		writeBody(w, response{"success": false, "message": err.Error()})
		return
	}

	isModerator, err := isDomainModerator(c.Email, domain)
	if err != nil {
		writeBody(w, response{"success": false, "message": err.Error()})
		return
	}

	if !isModerator {
		writeBody(w, response{"success": false, "message": errorNotModerator.Error()})
		return
	}

	if err = commentApprove(*x.CommentHex); err != nil {
		writeBody(w, response{"success": false, "message": err.Error()})
		return
	}

	writeBody(w, response{"success": true})
}
<commit_msg>comment_approve.go: fix isDomainModerator args<commit_after>package main

import (
	"net/http"
)

func commentApprove(commentHex string) error {
	if commentHex == "" {
		return errorMissingField
	}

	statement := `
		UPDATE comments
    SET state = 'approved'
		WHERE commentHex = $1;
	`

	_, err := db.Exec(statement, commentHex)
	if err != nil {
		logger.Errorf("cannot approve comment: %v", err)
		return errorInternal
	}

	return nil
}

func commentApproveHandler(w http.ResponseWriter, r *http.Request) {
	type request struct {
		Session    *string `json:"session"`
		CommentHex *string `json:"commentHex"`
	}

	var x request
	if err := unmarshalBody(r, &x); err != nil {
		writeBody(w, response{"success": false, "message": err.Error()})
		return
	}

	c, err := commenterGetBySession(*x.Session)
	if err != nil {
		writeBody(w, response{"success": false, "message": err.Error()})
		return
	}

	domain, err := commentDomainGet(*x.CommentHex)
	if err != nil {
		writeBody(w, response{"success": false, "message": err.Error()})
		return
	}

	isModerator, err := isDomainModerator(domain, c.Email)
	if err != nil {
		writeBody(w, response{"success": false, "message": err.Error()})
		return
	}

	if !isModerator {
		writeBody(w, response{"success": false, "message": errorNotModerator.Error()})
		return
	}

	if err = commentApprove(*x.CommentHex); err != nil {
		writeBody(w, response{"success": false, "message": err.Error()})
		return
	}

	writeBody(w, response{"success": true})
}
<|endoftext|>


<commit_before>package helpers

import (
	"encoding/json"
	log "github.com/Sirupsen/logrus"
	"github.com/ansible-semaphore/semaphore/db"
	"github.com/gorilla/context"
	"net/http"
	"runtime/debug"
	"strconv"
	"strings"

	"github.com/gorilla/mux"
)

func Store(r *http.Request) db.Store {
	return context.Get(r, "store").(db.Store)
}

func isXHR(w http.ResponseWriter, r *http.Request) bool {
	accept := r.Header.Get("Accept")
	return !strings.Contains(accept, "text/html")
}

// GetIntParam fetches a parameter from the route variables as an integer
// redirects to a 404 or writes bad request state depending on error state
func GetIntParam(name string, w http.ResponseWriter, r *http.Request) (int, error) {
	intParam, err := strconv.Atoi(mux.Vars(r)[name])

	if err != nil {
		if !isXHR(w, r) {
			http.Redirect(w, r, "/404", http.StatusFound)
		} else {
			w.WriteHeader(http.StatusBadRequest)
		}

		return 0, err
	}

	return intParam, nil
}

//H just a string-to-anything map
type H map[string]interface{}

//Bind decodes json into object
func Bind(w http.ResponseWriter, r *http.Request, out interface{}) bool {
	err := json.NewDecoder(r.Body).Decode(out)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
	}

	return err == nil
}

//WriteJSON writes object as JSON
func WriteJSON(w http.ResponseWriter, code int, out interface{}) {
	w.Header().Set("content-type", "application/json")
	w.WriteHeader(code)

	if err := json.NewEncoder(w).Encode(out); err != nil {
		panic(err)
	}
}

func WriteError(w http.ResponseWriter, err error) {
	if err == db.ErrNotFound {
		w.WriteHeader(http.StatusNotFound)
		return
	}

	log.Error(err)
	debug.PrintStack()
	w.WriteHeader(http.StatusInternalServerError)
}
<commit_msg>added GetMd5Hash func in helpers. Add import and refactor imports<commit_after>package helpers

import (
	"crypto/md5"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"runtime/debug"
	"strconv"
	"strings"

	log "github.com/Sirupsen/logrus"
	"github.com/gorilla/context"

	"github.com/ansible-semaphore/semaphore/db"

	"github.com/gorilla/mux"
)

func Store(r *http.Request) db.Store {
	return context.Get(r, "store").(db.Store)
}

func isXHR(w http.ResponseWriter, r *http.Request) bool {
	accept := r.Header.Get("Accept")
	return !strings.Contains(accept, "text/html")
}

// GetIntParam fetches a parameter from the route variables as an integer
// redirects to a 404 or writes bad request state depending on error state
func GetIntParam(name string, w http.ResponseWriter, r *http.Request) (int, error) {
	intParam, err := strconv.Atoi(mux.Vars(r)[name])

	if err != nil {
		if !isXHR(w, r) {
			http.Redirect(w, r, "/404", http.StatusFound)
		} else {
			w.WriteHeader(http.StatusBadRequest)
		}

		return 0, err
	}

	return intParam, nil
}

//H just a string-to-anything map
type H map[string]interface{}

//Bind decodes json into object
func Bind(w http.ResponseWriter, r *http.Request, out interface{}) bool {
	err := json.NewDecoder(r.Body).Decode(out)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
	}

	return err == nil
}

//WriteJSON writes object as JSON
func WriteJSON(w http.ResponseWriter, code int, out interface{}) {
	w.Header().Set("content-type", "application/json")
	w.WriteHeader(code)

	if err := json.NewEncoder(w).Encode(out); err != nil {
		panic(err)
	}
}

func WriteError(w http.ResponseWriter, err error) {
	if err == db.ErrNotFound {
		w.WriteHeader(http.StatusNotFound)
		return
	}

	log.Error(err)
	debug.PrintStack()
	w.WriteHeader(http.StatusInternalServerError)
}

func GetMD5Hash(filepath string) (string, error) {
	file, err := os.Open(filepath)
	if err != nil {
		return "", err
	}
	defer file.Close()

	hash := md5.New()
	if _, err := io.Copy(hash, file); err != nil {
		return "", err
	}
	return fmt.Sprintf("%x", hash.Sum(nil)), nil
}

<|endoftext|>


<commit_before>package main

// Imports
import (
	"os" // For quiting
	"fmt" // For printing of results/errors
	"net" // For talking to the who-is server
	"time" // For timeouts
	"regexp" // For matching whois results
	"io/ioutil" // For reading whois results
	"strings" // For cleaning up strings before printing
)

// Checks if a domain is actually a legal domain name
func validDomain(domain string) bool {

	// We have to have a tld, if not, bail
	if !strings.Contains(domain, ".") {
		return false
	}

	// Loop each character in the domain
	for _, c := range domain {

		// Check the character
		switch c {
			// Valid chars
			case 'a', 'b', 'c', 'd', 'e', 'f':
			case 'g', 'h', 'i', 'j', 'k', 'l':
			case 'm', 'n', 'o', 'p', 'q', 'r':
			case 's', 't', 'u', 'v', 'w', 'x':
			case 'y', 'z', '0', '1', '2', '3':
			case '4', '5', '6', '7', '8', '9':
			case '-', '.':
				continue
			// Invalid chars
			default:
				return false
		}

	}

	// Must be
	return true

}

// Global cache of domains to nameservers
var cache map[string][]string

// Checks the validity of a domain and prints the nameservers if possible
func lookupDomain(domain string) *[]string {

	// Split the domain by dots
	splitDomain := strings.Split(domain, ".")
	rootDomain := strings.Join(splitDomain[len(splitDomain)-2:], ".")

	// Check the cache for a existing lookup first
	result, exists := cache[rootDomain]
	if exists {
		return &result
	}

	// Connect to [tld].whois-server.net on port 43
	conn, err := net.DialTimeout(
		"tcp",
		net.JoinHostPort(splitDomain[len(splitDomain)-1] + ".whois-servers.net", "43"),
		time.Second * 10,
	)
	if err != nil {
		panic(err)
	}

	// Send a query for the root domain
	conn.Write([]byte("domain " + rootDomain + "\r\n"))
	var buffer []byte
	buffer, err = ioutil.ReadAll(conn)
	if err != nil {
		panic(err)
	}

	// Cleanup
	conn.Close()

	// Save the result in cache
	response := string(buffer[:])

	// Look for a "Status:" line
	statusRe := regexp.MustCompile(`Status:(.*)\n`)
	status := statusRe.FindStringSubmatch(response)

	// If no match, or status is "free", probably not registered
	if status == nil || strings.TrimSpace(status[1]) == "free" {
		return nil
	}

	// Else, grab the name servers
	nsRe := regexp.MustCompile(`(Name Server|Nserver|Nameserver):(.*)\n`)
	ns := nsRe.FindAllStringSubmatch(response, -1)

	// Extract the actual nameserver values
	servers := make([]string, len(ns))
	for i, server := range ns {

		// Cleanup the name and add it to the list
		servers[i] = strings.ToLower(strings.TrimSpace(server[2]))

	}

	// Save it in the cache for later
	cache[rootDomain] = servers

	// Return the list
	return &servers

}

// Entry point
func main() {

	// Verify we have the correct number of args
	if len(os.Args) != 2 {

		// Print usage and bail
		fmt.Fprintln(os.Stderr, "Usage: " + os.Args[0] + " [domain]")
		os.Exit(1)

	}

	// Grab the domain from args
	domain := os.Args[1]

	// Setup the worst-case size cache of nameservers for a given domain
	cache = make(map[string][]string, len(domain)*6)

	// Loop over each character in domain
	for i, c := range domain {

		// Loop each bit in character
		for j := 0; j < 8; j++ {

			// First bit it always 0 in ASCII and third bit is case which is irrelevant in DNS, skip them
			if j == 0 || j == 2 {
				continue
			}

			// Toggle the bit value
			c ^= 1 << uint(j);

			// Rebuild the flipped name for the domain from slices
			flipped := domain[:i] + string(c) + domain[i+1:]

			// If it's a valid domain
			if validDomain(flipped) {

				// Print the domain
				fmt.Print(flipped + "\t")

				// Lookup the nameservers for it
				servers := lookupDomain(flipped)

				// If we found some
				if servers == nil {
					fmt.Println("*")
				} else {
					fmt.Println(strings.Join(*servers, ","))
				}

			}

			// Toggle the bit value back before trying the next one
			c ^= 1 << uint(j);

		}

	}

}<commit_msg>Fix handling of invalid domain names<commit_after>package main

// Imports
import (
	"os" // For quiting
	"fmt" // For printing of results/errors
	"net" // For talking to the who-is server
	"time" // For timeouts
	"regexp" // For matching whois results
	"io/ioutil" // For reading whois results
	"strings" // For cleaning up strings before printing
)

// Checks if a domain is actually a legal domain name
func validDomain(domain string) bool {

	// We have to have a tld, if not, bail
	if !strings.Contains(domain, ".") {
		return false
	}

	// Loop each character in the domain
	for _, c := range domain {

		// Check the character
		switch c {
			// Valid chars
			case 'a', 'b', 'c', 'd', 'e', 'f':
			case 'g', 'h', 'i', 'j', 'k', 'l':
			case 'm', 'n', 'o', 'p', 'q', 'r':
			case 's', 't', 'u', 'v', 'w', 'x':
			case 'y', 'z', '0', '1', '2', '3':
			case '4', '5', '6', '7', '8', '9':
			case '-', '.':
				continue
			// Invalid chars
			default:
				return false
		}

	}

	// Must be
	return true

}

// Global cache of domains to nameservers
var cache map[string][]string

// Checks the validity of a domain and prints the nameservers if possible
func lookupDomain(domain string) *[]string {

	// Split the domain by dots
	splitDomain := strings.Split(domain, ".")
	rootDomain := strings.Join(splitDomain[len(splitDomain)-2:], ".")

	// Check the cache for a existing lookup first
	result, exists := cache[rootDomain]
	if exists {
		return &result
	}

	// Connect to [tld].whois-server.net on port 43
	conn, err := net.DialTimeout(
		"tcp",
		net.JoinHostPort(splitDomain[len(splitDomain)-1] + ".whois-servers.net", "43"),
		time.Second * 10,
	)
	if err != nil {
		return nil
	}

	// Send a query for the root domain
	conn.Write([]byte("domain " + rootDomain + "\r\n"))
	var buffer []byte
	buffer, err = ioutil.ReadAll(conn)
	if err != nil {
		panic(err)
	}

	// Cleanup
	conn.Close()

	// Save the result in cache
	response := string(buffer[:])

	// Look for a "Status:" line
	statusRe := regexp.MustCompile(`Status:(.*)\n`)
	status := statusRe.FindStringSubmatch(response)

	// If no match, or status is "free", probably not registered
	if status == nil || strings.TrimSpace(status[1]) == "free" {
		return nil
	}

	// Else, grab the name servers
	nsRe := regexp.MustCompile(`(Name Server|Nserver|Nameserver):(.*)\n`)
	ns := nsRe.FindAllStringSubmatch(response, -1)

	// Extract the actual nameserver values
	servers := make([]string, len(ns))
	for i, server := range ns {

		// Cleanup the name and add it to the list
		servers[i] = strings.ToLower(strings.TrimSpace(server[2]))

	}

	// Save it in the cache for later
	cache[rootDomain] = servers

	// Return the list
	return &servers

}

// Entry point
func main() {

	// Verify we have the correct number of args
	if len(os.Args) != 2 {

		// Print usage and bail
		fmt.Fprintln(os.Stderr, "Usage: " + os.Args[0] + " [domain]")
		os.Exit(1)

	}

	// Grab the domain from args
	domain := os.Args[1]

	// Setup the worst-case size cache of nameservers for a given domain
	cache = make(map[string][]string, len(domain)*6)

	// Loop over each character in domain
	for i, c := range domain {

		// Loop each bit in character
		for j := 0; j < 8; j++ {

			// First bit it always 0 in ASCII and third bit is case which is irrelevant in DNS, skip them
			if j == 0 || j == 2 {
				continue
			}

			// Toggle the bit value
			c ^= 1 << uint(j);

			// Rebuild the flipped name for the domain from slices
			flipped := domain[:i] + string(c) + domain[i+1:]

			// If it's a valid domain
			if validDomain(flipped) {

				// Print the domain
				fmt.Print(flipped + "\t")

				// Lookup the nameservers for it
				servers := lookupDomain(flipped)

				// If we found some
				if servers == nil {
					fmt.Println("*")
				} else {
					fmt.Println(strings.Join(*servers, ","))
				}

			}

			// Toggle the bit value back before trying the next one
			c ^= 1 << uint(j);

		}

	}

}
<|endoftext|>


<commit_before>package gitbase

import (
	"io"

	git "gopkg.in/src-d/go-git.v4"
	"gopkg.in/src-d/go-git.v4/config"
	"gopkg.in/src-d/go-mysql-server.v0/sql"
	"gopkg.in/src-d/go-mysql-server.v0/sql/expression"
	"gopkg.in/src-d/go-mysql-server.v0/sql/plan"
)

type remotesTable struct{}

// RemotesSchema is the schema for the remotes table.
var RemotesSchema = sql.Schema{
	{Name: "repository_id", Type: sql.Text, Nullable: false, Source: RemotesTableName},
	{Name: "remote_name", Type: sql.Text, Nullable: false, Source: RemotesTableName},
	{Name: "remote_push_url", Type: sql.Text, Nullable: false, Source: RemotesTableName},
	{Name: "remote_fetch_url", Type: sql.Text, Nullable: false, Source: RemotesTableName},
	{Name: "remote_push_refspec", Type: sql.Text, Nullable: false, Source: RemotesTableName},
	{Name: "remote_fetch_refspec", Type: sql.Text, Nullable: false, Source: RemotesTableName},
}

var _ sql.PushdownProjectionAndFiltersTable = (*remotesTable)(nil)

func newRemotesTable() Indexable {
	return new(remotesTable)
}

var _ Table = (*remotesTable)(nil)
var _ Squashable = (*remotesTable)(nil)

func (remotesTable) isSquashable()   {}
func (remotesTable) isGitbaseTable() {}

func (remotesTable) Resolved() bool {
	return true
}

func (remotesTable) Name() string {
	return RemotesTableName
}

func (remotesTable) Schema() sql.Schema {
	return RemotesSchema
}

func (r remotesTable) String() string {
	return printTable(RemotesTableName, RemotesSchema)
}

func (r *remotesTable) TransformUp(f sql.TransformNodeFunc) (sql.Node, error) {
	return f(r)
}

func (r *remotesTable) TransformExpressionsUp(f sql.TransformExprFunc) (sql.Node, error) {
	return r, nil
}

func (r remotesTable) RowIter(ctx *sql.Context) (sql.RowIter, error) {
	span, ctx := ctx.Span("gitbase.RemotesTable")
	iter := new(remotesIter)

	rowRepoIter, err := NewRowRepoIter(ctx, iter)
	if err != nil {
		span.Finish()
		return nil, err
	}

	return sql.NewSpanIter(span, rowRepoIter), nil
}

func (remotesTable) Children() []sql.Node {
	return nil
}

func (remotesTable) HandledFilters(filters []sql.Expression) []sql.Expression {
	return handledFilters(RemotesTableName, RemotesSchema, filters)
}

func (remotesTable) handledColumns() []string { return []string{} }

func (r *remotesTable) WithProjectAndFilters(
	ctx *sql.Context,
	_, filters []sql.Expression,
) (sql.RowIter, error) {
	span, ctx := ctx.Span("gitbase.RemotesTable")
	iter, err := rowIterWithSelectors(
		ctx, RemotesSchema, RemotesTableName,
		filters, nil,
		r.handledColumns(),
		remotesIterBuilder,
	)

	if err != nil {
		span.Finish()
		return nil, err
	}

	return sql.NewSpanIter(span, iter), nil
}

// IndexKeyValueIter implements the sql.Indexable interface.
func (*remotesTable) IndexKeyValueIter(
	ctx *sql.Context,
	colNames []string,
) (sql.IndexKeyValueIter, error) {
	s, ok := ctx.Session.(*Session)
	if !ok || s == nil {
		return nil, ErrInvalidGitbaseSession.New(ctx.Session)
	}

	iter, err := s.Pool.RepoIter()
	if err != nil {
		return nil, err
	}

	return &remotesKeyValueIter{repos: iter, columns: colNames}, nil
}

// WithProjectFiltersAndIndex implements sql.Indexable interface.
func (*remotesTable) WithProjectFiltersAndIndex(
	ctx *sql.Context,
	columns, filters []sql.Expression,
	index sql.IndexValueIter,
) (sql.RowIter, error) {
	span, ctx := ctx.Span("gitbase.ReferencesTable.WithProjectFiltersAndIndex")
	s, ok := ctx.Session.(*Session)
	if !ok || s == nil {
		span.Finish()
		return nil, ErrInvalidGitbaseSession.New(ctx.Session)
	}

	var iter sql.RowIter = &remotesIndexIter{index: index, pool: s.Pool}

	if len(filters) > 0 {
		iter = plan.NewFilterIter(ctx, expression.JoinAnd(filters...), iter)
	}

	return sql.NewSpanIter(span, iter), nil
}

func remotesIterBuilder(_ *sql.Context, _ selectors, _ []sql.Expression) (RowRepoIter, error) {
	// it's not worth to manually filter with the selectors
	return new(remotesIter), nil
}

type remotesIter struct {
	repositoryID string
	remotes      []*git.Remote
	remotePos    int
	urlPos       int
}

func (i *remotesIter) NewIterator(repo *Repository) (RowRepoIter, error) {
	remotes, err := repo.Repo.Remotes()
	if err != nil {
		return nil, err
	}

	return &remotesIter{
		repositoryID: repo.ID,
		remotes:      remotes,
		remotePos:    0,
		urlPos:       0}, nil
}

func (i *remotesIter) Next() (sql.Row, error) {
	if i.remotePos >= len(i.remotes) {
		return nil, io.EOF
	}

	remote := i.remotes[i.remotePos]
	config := remote.Config()

	if i.urlPos >= len(config.URLs) {
		i.remotePos++
		if i.remotePos >= len(i.remotes) {
			return nil, io.EOF
		}

		remote = i.remotes[i.remotePos]
		config = remote.Config()
		i.urlPos = 0
	}

	row := remoteToRow(i.repositoryID, config, i.urlPos)
	i.urlPos++

	return row, nil
}

func (i *remotesIter) Close() error {
	return nil
}

func remoteToRow(repoID string, config *config.RemoteConfig, pos int) sql.Row {
	return sql.NewRow(
		repoID,
		config.Name,
		config.URLs[pos],
		config.URLs[pos],
		config.Fetch[pos].String(),
		config.Fetch[pos].String(),
	)
}

type remoteIndexKey struct {
	Repository string
	Pos        int
	URLPos     int
}

type remotesKeyValueIter struct {
	repos   *RepositoryIter
	repo    *Repository
	columns []string
	remotes []*git.Remote
	pos     int
	urlPos  int
}

func (i *remotesKeyValueIter) Next() ([]interface{}, []byte, error) {
	for {
		if len(i.remotes) == 0 {
			var err error
			i.repo, err = i.repos.Next()
			if err != nil {
				return nil, nil, err
			}

			i.remotes, err = i.repo.Repo.Remotes()
			if err != nil {
				return nil, nil, err
			}

			i.pos = 0
			i.urlPos = 0
		}

		if i.pos >= len(i.remotes) {
			i.remotes = nil
			continue
		}

		cfg := i.remotes[i.pos].Config()
		if i.urlPos >= len(cfg.URLs) {
			i.pos++
			continue
		}

		i.urlPos++

		key, err := encodeIndexKey(remoteIndexKey{i.repo.ID, i.pos, i.urlPos - 1})
		if err != nil {
			return nil, nil, err
		}

		row := remoteToRow(i.repo.ID, cfg, i.urlPos-1)
		values, err := rowIndexValues(row, i.columns, RemotesSchema)
		if err != nil {
			return nil, nil, err
		}

		return values, key, nil
	}
}

func (i *remotesKeyValueIter) Close() error {
	return i.repos.Close()
}

type remotesIndexIter struct {
	index   sql.IndexValueIter
	pool    *RepositoryPool
	repo    *Repository
	remotes []*git.Remote
}

func (i *remotesIndexIter) Next() (sql.Row, error) {
	data, err := i.index.Next()
	if err != nil {
		return nil, err
	}

	var key remoteIndexKey
	if err := decodeIndexKey(data, &key); err != nil {
		return nil, err
	}

	if i.repo == nil || i.repo.ID != key.Repository {
		i.repo, err = i.pool.GetRepo(key.Repository)
		if err != nil {
			return nil, err
		}

		i.remotes, err = i.repo.Repo.Remotes()
		if err != nil {
			return nil, err
		}
	}

	config := i.remotes[key.Pos].Config()
	return remoteToRow(key.Repository, config, key.URLPos), nil
}

func (i *remotesIndexIter) Close() error { return i.index.Close() }
<commit_msg>gitbase: fix name of remotes table span<commit_after>package gitbase

import (
	"io"

	git "gopkg.in/src-d/go-git.v4"
	"gopkg.in/src-d/go-git.v4/config"
	"gopkg.in/src-d/go-mysql-server.v0/sql"
	"gopkg.in/src-d/go-mysql-server.v0/sql/expression"
	"gopkg.in/src-d/go-mysql-server.v0/sql/plan"
)

type remotesTable struct{}

// RemotesSchema is the schema for the remotes table.
var RemotesSchema = sql.Schema{
	{Name: "repository_id", Type: sql.Text, Nullable: false, Source: RemotesTableName},
	{Name: "remote_name", Type: sql.Text, Nullable: false, Source: RemotesTableName},
	{Name: "remote_push_url", Type: sql.Text, Nullable: false, Source: RemotesTableName},
	{Name: "remote_fetch_url", Type: sql.Text, Nullable: false, Source: RemotesTableName},
	{Name: "remote_push_refspec", Type: sql.Text, Nullable: false, Source: RemotesTableName},
	{Name: "remote_fetch_refspec", Type: sql.Text, Nullable: false, Source: RemotesTableName},
}

var _ sql.PushdownProjectionAndFiltersTable = (*remotesTable)(nil)

func newRemotesTable() Indexable {
	return new(remotesTable)
}

var _ Table = (*remotesTable)(nil)
var _ Squashable = (*remotesTable)(nil)

func (remotesTable) isSquashable()   {}
func (remotesTable) isGitbaseTable() {}

func (remotesTable) Resolved() bool {
	return true
}

func (remotesTable) Name() string {
	return RemotesTableName
}

func (remotesTable) Schema() sql.Schema {
	return RemotesSchema
}

func (r remotesTable) String() string {
	return printTable(RemotesTableName, RemotesSchema)
}

func (r *remotesTable) TransformUp(f sql.TransformNodeFunc) (sql.Node, error) {
	return f(r)
}

func (r *remotesTable) TransformExpressionsUp(f sql.TransformExprFunc) (sql.Node, error) {
	return r, nil
}

func (r remotesTable) RowIter(ctx *sql.Context) (sql.RowIter, error) {
	span, ctx := ctx.Span("gitbase.RemotesTable")
	iter := new(remotesIter)

	rowRepoIter, err := NewRowRepoIter(ctx, iter)
	if err != nil {
		span.Finish()
		return nil, err
	}

	return sql.NewSpanIter(span, rowRepoIter), nil
}

func (remotesTable) Children() []sql.Node {
	return nil
}

func (remotesTable) HandledFilters(filters []sql.Expression) []sql.Expression {
	return handledFilters(RemotesTableName, RemotesSchema, filters)
}

func (remotesTable) handledColumns() []string { return []string{} }

func (r *remotesTable) WithProjectAndFilters(
	ctx *sql.Context,
	_, filters []sql.Expression,
) (sql.RowIter, error) {
	span, ctx := ctx.Span("gitbase.RemotesTable")
	iter, err := rowIterWithSelectors(
		ctx, RemotesSchema, RemotesTableName,
		filters, nil,
		r.handledColumns(),
		remotesIterBuilder,
	)

	if err != nil {
		span.Finish()
		return nil, err
	}

	return sql.NewSpanIter(span, iter), nil
}

// IndexKeyValueIter implements the sql.Indexable interface.
func (*remotesTable) IndexKeyValueIter(
	ctx *sql.Context,
	colNames []string,
) (sql.IndexKeyValueIter, error) {
	s, ok := ctx.Session.(*Session)
	if !ok || s == nil {
		return nil, ErrInvalidGitbaseSession.New(ctx.Session)
	}

	iter, err := s.Pool.RepoIter()
	if err != nil {
		return nil, err
	}

	return &remotesKeyValueIter{repos: iter, columns: colNames}, nil
}

// WithProjectFiltersAndIndex implements sql.Indexable interface.
func (*remotesTable) WithProjectFiltersAndIndex(
	ctx *sql.Context,
	columns, filters []sql.Expression,
	index sql.IndexValueIter,
) (sql.RowIter, error) {
	span, ctx := ctx.Span("gitbase.RemotesTable.WithProjectFiltersAndIndex")
	s, ok := ctx.Session.(*Session)
	if !ok || s == nil {
		span.Finish()
		return nil, ErrInvalidGitbaseSession.New(ctx.Session)
	}

	var iter sql.RowIter = &remotesIndexIter{index: index, pool: s.Pool}

	if len(filters) > 0 {
		iter = plan.NewFilterIter(ctx, expression.JoinAnd(filters...), iter)
	}

	return sql.NewSpanIter(span, iter), nil
}

func remotesIterBuilder(_ *sql.Context, _ selectors, _ []sql.Expression) (RowRepoIter, error) {
	// it's not worth to manually filter with the selectors
	return new(remotesIter), nil
}

type remotesIter struct {
	repositoryID string
	remotes      []*git.Remote
	remotePos    int
	urlPos       int
}

func (i *remotesIter) NewIterator(repo *Repository) (RowRepoIter, error) {
	remotes, err := repo.Repo.Remotes()
	if err != nil {
		return nil, err
	}

	return &remotesIter{
		repositoryID: repo.ID,
		remotes:      remotes,
		remotePos:    0,
		urlPos:       0}, nil
}

func (i *remotesIter) Next() (sql.Row, error) {
	if i.remotePos >= len(i.remotes) {
		return nil, io.EOF
	}

	remote := i.remotes[i.remotePos]
	config := remote.Config()

	if i.urlPos >= len(config.URLs) {
		i.remotePos++
		if i.remotePos >= len(i.remotes) {
			return nil, io.EOF
		}

		remote = i.remotes[i.remotePos]
		config = remote.Config()
		i.urlPos = 0
	}

	row := remoteToRow(i.repositoryID, config, i.urlPos)
	i.urlPos++

	return row, nil
}

func (i *remotesIter) Close() error {
	return nil
}

func remoteToRow(repoID string, config *config.RemoteConfig, pos int) sql.Row {
	return sql.NewRow(
		repoID,
		config.Name,
		config.URLs[pos],
		config.URLs[pos],
		config.Fetch[pos].String(),
		config.Fetch[pos].String(),
	)
}

type remoteIndexKey struct {
	Repository string
	Pos        int
	URLPos     int
}

type remotesKeyValueIter struct {
	repos   *RepositoryIter
	repo    *Repository
	columns []string
	remotes []*git.Remote
	pos     int
	urlPos  int
}

func (i *remotesKeyValueIter) Next() ([]interface{}, []byte, error) {
	for {
		if len(i.remotes) == 0 {
			var err error
			i.repo, err = i.repos.Next()
			if err != nil {
				return nil, nil, err
			}

			i.remotes, err = i.repo.Repo.Remotes()
			if err != nil {
				return nil, nil, err
			}

			i.pos = 0
			i.urlPos = 0
		}

		if i.pos >= len(i.remotes) {
			i.remotes = nil
			continue
		}

		cfg := i.remotes[i.pos].Config()
		if i.urlPos >= len(cfg.URLs) {
			i.pos++
			continue
		}

		i.urlPos++

		key, err := encodeIndexKey(remoteIndexKey{i.repo.ID, i.pos, i.urlPos - 1})
		if err != nil {
			return nil, nil, err
		}

		row := remoteToRow(i.repo.ID, cfg, i.urlPos-1)
		values, err := rowIndexValues(row, i.columns, RemotesSchema)
		if err != nil {
			return nil, nil, err
		}

		return values, key, nil
	}
}

func (i *remotesKeyValueIter) Close() error {
	return i.repos.Close()
}

type remotesIndexIter struct {
	index   sql.IndexValueIter
	pool    *RepositoryPool
	repo    *Repository
	remotes []*git.Remote
}

func (i *remotesIndexIter) Next() (sql.Row, error) {
	data, err := i.index.Next()
	if err != nil {
		return nil, err
	}

	var key remoteIndexKey
	if err := decodeIndexKey(data, &key); err != nil {
		return nil, err
	}

	if i.repo == nil || i.repo.ID != key.Repository {
		i.repo, err = i.pool.GetRepo(key.Repository)
		if err != nil {
			return nil, err
		}

		i.remotes, err = i.repo.Repo.Remotes()
		if err != nil {
			return nil, err
		}
	}

	config := i.remotes[key.Pos].Config()
	return remoteToRow(key.Repository, config, key.URLPos), nil
}

func (i *remotesIndexIter) Close() error { return i.index.Close() }
<|endoftext|>


<commit_before>package api

import "time"

// StorageVolumeSnapshotsPost represents the fields available for a new LXD storage volume snapshot
//
// API extension: storage_api_volume_snapshots
type StorageVolumeSnapshotsPost struct {
	Name string `json:"name" yaml:"name"`

	// API extension: custom_volume_snapshot_expiry
	ExpiresAt *time.Time `json:"expires_at" yaml:"expires_at"`
}

// StorageVolumeSnapshotPost represents the fields required to rename/move a LXD storage volume snapshot
//
// API extension: storage_api_volume_snapshots
type StorageVolumeSnapshotPost struct {
	Name string `json:"name" yaml:"name"`
}

// StorageVolumeSnapshot represents a LXD storage volume snapshot
//
// API extension: storage_api_volume_snapshots
type StorageVolumeSnapshot struct {
	StorageVolumeSnapshotPut `json:",inline" yaml:",inline"`

	Name   string            `json:"name" yaml:"name"`
	Config map[string]string `json:"config" yaml:"config"`

	// API extension: custom_block_volumes
	ContentType string `json:"content_type" yaml:"content_type"`
}

// StorageVolumeSnapshotPut represents the modifiable fields of a LXD storage volume
//
// API extension: storage_api_volume_snapshots
type StorageVolumeSnapshotPut struct {
	Description string `json:"description" yaml:"description"`

	// API extension: custom_volume_snapshot_expiry
	ExpiresAt *time.Time `json:"expires_at" yaml:"expires_at"`
}
<commit_msg>shared/api: Add swagger metadata for storage volume snapshots<commit_after>package api

import "time"

// StorageVolumeSnapshotsPost represents the fields available for a new LXD storage volume snapshot
//
// swagger:model
//
// API extension: storage_api_volume_snapshots
type StorageVolumeSnapshotsPost struct {
	// Snapshot name
	// Example: snap0
	Name string `json:"name" yaml:"name"`

	// When the snapshot expires (gets auto-deleted)
	// Example: 2021-03-23T17:38:37.753398689-04:00
	//
	// API extension: custom_volume_snapshot_expiry
	ExpiresAt *time.Time `json:"expires_at" yaml:"expires_at"`
}

// StorageVolumeSnapshotPost represents the fields required to rename/move a LXD storage volume snapshot
//
// swagger:model
//
// API extension: storage_api_volume_snapshots
type StorageVolumeSnapshotPost struct {
	// New snapshot name
	// Example: snap1
	Name string `json:"name" yaml:"name"`
}

// StorageVolumeSnapshot represents a LXD storage volume snapshot
//
// swagger:model
//
// API extension: storage_api_volume_snapshots
type StorageVolumeSnapshot struct {
	StorageVolumeSnapshotPut `json:",inline" yaml:",inline"`

	// Snapshot name
	// Example: snap0
	Name string `json:"name" yaml:"name"`

	// Storage volume configuration map (refer to doc/storage.md)
	// Example: {"zfs.remove_snapshots": "true", "size": "50GiB"}
	Config map[string]string `json:"config" yaml:"config"`

	// The content type (filesystem or block)
	// Example: filesystem
	//
	// API extension: custom_block_volumes
	ContentType string `json:"content_type" yaml:"content_type"`
}

// StorageVolumeSnapshotPut represents the modifiable fields of a LXD storage volume
//
// swagger:model
//
// API extension: storage_api_volume_snapshots
type StorageVolumeSnapshotPut struct {
	// Description of the storage volume
	// Example: My custom volume
	Description string `json:"description" yaml:"description"`

	// When the snapshot expires (gets auto-deleted)
	// Example: 2021-03-23T17:38:37.753398689-04:00
	//
	// API extension: custom_volume_snapshot_expiry
	ExpiresAt *time.Time `json:"expires_at" yaml:"expires_at"`
}
<|endoftext|>


<commit_before>package service

import (
	"errors"
	"github.com/timeredbull/tsuru/api/auth"
	"github.com/timeredbull/tsuru/db"
	"github.com/timeredbull/tsuru/log"
	"labix.org/v2/mgo/bson"
	"strings"
)

const OnNewInstance = "on-new-instance"

type Service struct {
	Name       string `bson:"_id"`
	Endpoint   map[string]string
	Bootstrap  map[string]string
	OwnerTeams []string `bson:"owner_teams"`
	Teams      []string
	Status     string
}

func (s *Service) Log(out []byte) {
	log.Printf(string(out))
}

func (s *Service) Get() error {
	query := bson.M{"_id": s.Name, "status": bson.M{"$ne": "deleted"}}
	return db.Session.Services().Find(query).One(&s)
}

func (s *Service) Create() error {
	s.Status = "created"
	err := db.Session.Services().Insert(s)
	return err
}

func (s *Service) update() error {
	return db.Session.Services().Update(bson.M{"_id": s.Name}, s)
}

func (s *Service) Delete() error {
	s.Status = "deleted"
	return db.Session.Services().Update(bson.M{"_id": s.Name}, s)
}

func (s *Service) GetClient(endpoint string) (cli *Client, err error) {
	if e, ok := s.Endpoint[endpoint]; ok {
		if !strings.HasPrefix(e, "http://") {
			e = "http://" + e
		}
		cli = &Client{endpoint: e}
	} else {
		err = errors.New("Unknown endpoint: " + endpoint)
	}
	return
}

func (s *Service) findTeam(team *auth.Team) int {
	for i, t := range s.Teams {
		if team.Name == t {
			return i
		}
	}
	return -1
}

func (s *Service) hasTeam(team *auth.Team) bool {
	return s.findTeam(team) > -1
}

func (s *Service) GrantAccess(team *auth.Team) error {
	if s.hasTeam(team) {
		return errors.New("This team already has access to this service")
	}
	s.Teams = append(s.Teams, team.Name)
	return nil
}

func (s *Service) RevokeAccess(team *auth.Team) error {
	index := s.findTeam(team)
	if index < 0 {
		return errors.New("This team does not have access to this service")
	}
	last := len(s.Teams) - 1
	s.Teams[index] = s.Teams[last]
	s.Teams = s.Teams[:last]
	return nil
}

func GetServicesNames(services []Service) []string {
	sNames := make([]string, len(services))
	for i, s := range services {
		sNames[i] = s.Name
	}
	return sNames
}
<commit_msg>added Doc on Service struct<commit_after>package service

import (
	"errors"
	"github.com/timeredbull/tsuru/api/auth"
	"github.com/timeredbull/tsuru/db"
	"github.com/timeredbull/tsuru/log"
	"labix.org/v2/mgo/bson"
	"strings"
)

const OnNewInstance = "on-new-instance"

type Service struct {
	Name       string `bson:"_id"`
	Endpoint   map[string]string
	Bootstrap  map[string]string
	OwnerTeams []string `bson:"owner_teams"`
	Teams      []string
	Status     string
	Doc        string
}

func (s *Service) Log(out []byte) {
	log.Printf(string(out))
}

func (s *Service) Get() error {
	query := bson.M{"_id": s.Name, "status": bson.M{"$ne": "deleted"}}
	return db.Session.Services().Find(query).One(&s)
}

func (s *Service) Create() error {
	s.Status = "created"
	err := db.Session.Services().Insert(s)
	return err
}

func (s *Service) update() error {
	return db.Session.Services().Update(bson.M{"_id": s.Name}, s)
}

func (s *Service) Delete() error {
	s.Status = "deleted"
	return db.Session.Services().Update(bson.M{"_id": s.Name}, s)
}

func (s *Service) GetClient(endpoint string) (cli *Client, err error) {
	if e, ok := s.Endpoint[endpoint]; ok {
		if !strings.HasPrefix(e, "http://") {
			e = "http://" + e
		}
		cli = &Client{endpoint: e}
	} else {
		err = errors.New("Unknown endpoint: " + endpoint)
	}
	return
}

func (s *Service) findTeam(team *auth.Team) int {
	for i, t := range s.Teams {
		if team.Name == t {
			return i
		}
	}
	return -1
}

func (s *Service) hasTeam(team *auth.Team) bool {
	return s.findTeam(team) > -1
}

func (s *Service) GrantAccess(team *auth.Team) error {
	if s.hasTeam(team) {
		return errors.New("This team already has access to this service")
	}
	s.Teams = append(s.Teams, team.Name)
	return nil
}

func (s *Service) RevokeAccess(team *auth.Team) error {
	index := s.findTeam(team)
	if index < 0 {
		return errors.New("This team does not have access to this service")
	}
	last := len(s.Teams) - 1
	s.Teams[index] = s.Teams[last]
	s.Teams = s.Teams[:last]
	return nil
}

func GetServicesNames(services []Service) []string {
	sNames := make([]string, len(services))
	for i, s := range services {
		sNames[i] = s.Name
	}
	return sNames
}
<|endoftext|>


<commit_before>package version

// Version of Functions
var Version = "0.3.242"
<commit_msg>fnserver: 0.3.243 release [skip ci]<commit_after>package version

// Version of Functions
var Version = "0.3.243"
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes 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 apiserver

import (
	"fmt"

	"k8s.io/apimachinery/pkg/runtime/schema"
	utilerrors "k8s.io/apimachinery/pkg/util/errors"
	"k8s.io/kubernetes/cmd/libs/go2idl/client-gen/test_apis/testgroup/v1"
	testgroupetcd "k8s.io/kubernetes/examples/apiserver/rest"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/rest"
	"k8s.io/kubernetes/pkg/genericapiserver"
	"k8s.io/kubernetes/pkg/genericapiserver/authorizer"
	genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options"
	kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
	"k8s.io/kubernetes/pkg/registry/generic"
	"k8s.io/kubernetes/pkg/storage/storagebackend"

	// Install the testgroup API
	_ "k8s.io/kubernetes/cmd/libs/go2idl/client-gen/test_apis/testgroup/install"

	"github.com/golang/glog"
)

const (
	// Ports on which to run the server.
	// Explicitly setting these to a different value than the default values, to prevent this from clashing with a local cluster.
	InsecurePort = 8081
	SecurePort   = 6444
)

func newStorageFactory() genericapiserver.StorageFactory {
	config := storagebackend.Config{
		Prefix:     genericoptions.DefaultEtcdPathPrefix,
		ServerList: []string{"http://127.0.0.1:2379"},
	}
	storageFactory := genericapiserver.NewDefaultStorageFactory(config, "application/json", api.Codecs, genericapiserver.NewDefaultResourceEncodingConfig(), genericapiserver.NewResourceConfig())

	return storageFactory
}

type ServerRunOptions struct {
	GenericServerRunOptions *genericoptions.ServerRunOptions
	Etcd                    *genericoptions.EtcdOptions
	SecureServing           *genericoptions.SecureServingOptions
	InsecureServing         *genericoptions.ServingOptions
	Authentication          *kubeoptions.BuiltInAuthenticationOptions
	CloudProvider           *kubeoptions.CloudProviderOptions
}

func NewServerRunOptions() *ServerRunOptions {
	s := ServerRunOptions{
		GenericServerRunOptions: genericoptions.NewServerRunOptions(),
		Etcd:            genericoptions.NewEtcdOptions(),
		SecureServing:   genericoptions.NewSecureServingOptions(),
		InsecureServing: genericoptions.NewInsecureServingOptions(),
		Authentication:  kubeoptions.NewBuiltInAuthenticationOptions().WithAll(),
		CloudProvider:   kubeoptions.NewCloudProviderOptions(),
	}
	s.InsecureServing.BindPort = InsecurePort
	s.SecureServing.ServingOptions.BindPort = SecurePort

	return &s
}

func (serverOptions *ServerRunOptions) Run(stopCh <-chan struct{}) error {
	serverOptions.Etcd.StorageConfig.ServerList = []string{"http://127.0.0.1:2379"}

	// set defaults
	if err := serverOptions.CloudProvider.DefaultExternalHost(serverOptions.GenericServerRunOptions); err != nil {
		return err
	}
	if err := serverOptions.SecureServing.MaybeDefaultWithSelfSignedCerts(serverOptions.GenericServerRunOptions.AdvertiseAddress.String()); err != nil {
		glog.Fatalf("Error creating self-signed certificates: %v", err)
	}

	// validate options
	if errs := serverOptions.Etcd.Validate(); len(errs) > 0 {
		return utilerrors.NewAggregate(errs)
	}
	if errs := serverOptions.SecureServing.Validate(); len(errs) > 0 {
		return utilerrors.NewAggregate(errs)
	}
	if errs := serverOptions.InsecureServing.Validate("insecure-port"); len(errs) > 0 {
		return utilerrors.NewAggregate(errs)
	}

	// create config from options
	config := genericapiserver.NewConfig().
		ApplyOptions(serverOptions.GenericServerRunOptions).
		ApplyInsecureServingOptions(serverOptions.InsecureServing)

	if _, err := config.ApplySecureServingOptions(serverOptions.SecureServing); err != nil {
		return fmt.Errorf("failed to configure https: %s", err)
	}
	if err := serverOptions.Authentication.Apply(config); err != nil {
		return fmt.Errorf("failed to configure authentication: %s", err)
	}

	config.Authorizer = authorizer.NewAlwaysAllowAuthorizer()
	config.SwaggerConfig = genericapiserver.DefaultSwaggerConfig()

	s, err := config.Complete().New()
	if err != nil {
		return fmt.Errorf("Error in bringing up the server: %v", err)
	}

	groupVersion := v1.SchemeGroupVersion
	groupName := groupVersion.Group
	groupMeta, err := api.Registry.Group(groupName)
	if err != nil {
		return fmt.Errorf("%v", err)
	}
	storageFactory := newStorageFactory()
	storageConfig, err := storageFactory.NewConfig(schema.GroupResource{Group: groupName, Resource: "testtype"})
	if err != nil {
		return fmt.Errorf("Unable to get storage config: %v", err)
	}

	testTypeOpts := generic.RESTOptions{
		StorageConfig:           storageConfig,
		Decorator:               generic.UndecoratedStorage,
		ResourcePrefix:          "testtypes",
		DeleteCollectionWorkers: 1,
	}

	restStorageMap := map[string]rest.Storage{
		"testtypes": testgroupetcd.NewREST(testTypeOpts),
	}
	apiGroupInfo := genericapiserver.APIGroupInfo{
		GroupMeta: *groupMeta,
		VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
			groupVersion.Version: restStorageMap,
		},
		Scheme:               api.Scheme,
		NegotiatedSerializer: api.Codecs,
	}
	if err := s.InstallAPIGroup(&apiGroupInfo); err != nil {
		return fmt.Errorf("Error in installing API: %v", err)
	}
	s.PrepareRun().Run(stopCh)
	return nil
}
<commit_msg>Fix imports<commit_after>/*
Copyright 2016 The Kubernetes 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 apiserver

import (
	"fmt"

	"k8s.io/apimachinery/pkg/runtime/schema"
	utilerrors "k8s.io/apimachinery/pkg/util/errors"
	"k8s.io/kubernetes/cmd/libs/go2idl/client-gen/test_apis/testgroup/v1"
	testgroupetcd "k8s.io/kubernetes/examples/apiserver/rest"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/genericapiserver"
	"k8s.io/kubernetes/pkg/genericapiserver/api/rest"
	"k8s.io/kubernetes/pkg/genericapiserver/authorizer"
	genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options"
	kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
	"k8s.io/kubernetes/pkg/registry/generic"
	"k8s.io/kubernetes/pkg/storage/storagebackend"

	// Install the testgroup API
	_ "k8s.io/kubernetes/cmd/libs/go2idl/client-gen/test_apis/testgroup/install"

	"github.com/golang/glog"
)

const (
	// Ports on which to run the server.
	// Explicitly setting these to a different value than the default values, to prevent this from clashing with a local cluster.
	InsecurePort = 8081
	SecurePort   = 6444
)

func newStorageFactory() genericapiserver.StorageFactory {
	config := storagebackend.Config{
		Prefix:     genericoptions.DefaultEtcdPathPrefix,
		ServerList: []string{"http://127.0.0.1:2379"},
	}
	storageFactory := genericapiserver.NewDefaultStorageFactory(config, "application/json", api.Codecs, genericapiserver.NewDefaultResourceEncodingConfig(), genericapiserver.NewResourceConfig())

	return storageFactory
}

type ServerRunOptions struct {
	GenericServerRunOptions *genericoptions.ServerRunOptions
	Etcd                    *genericoptions.EtcdOptions
	SecureServing           *genericoptions.SecureServingOptions
	InsecureServing         *genericoptions.ServingOptions
	Authentication          *kubeoptions.BuiltInAuthenticationOptions
	CloudProvider           *kubeoptions.CloudProviderOptions
}

func NewServerRunOptions() *ServerRunOptions {
	s := ServerRunOptions{
		GenericServerRunOptions: genericoptions.NewServerRunOptions(),
		Etcd:            genericoptions.NewEtcdOptions(),
		SecureServing:   genericoptions.NewSecureServingOptions(),
		InsecureServing: genericoptions.NewInsecureServingOptions(),
		Authentication:  kubeoptions.NewBuiltInAuthenticationOptions().WithAll(),
		CloudProvider:   kubeoptions.NewCloudProviderOptions(),
	}
	s.InsecureServing.BindPort = InsecurePort
	s.SecureServing.ServingOptions.BindPort = SecurePort

	return &s
}

func (serverOptions *ServerRunOptions) Run(stopCh <-chan struct{}) error {
	serverOptions.Etcd.StorageConfig.ServerList = []string{"http://127.0.0.1:2379"}

	// set defaults
	if err := serverOptions.CloudProvider.DefaultExternalHost(serverOptions.GenericServerRunOptions); err != nil {
		return err
	}
	if err := serverOptions.SecureServing.MaybeDefaultWithSelfSignedCerts(serverOptions.GenericServerRunOptions.AdvertiseAddress.String()); err != nil {
		glog.Fatalf("Error creating self-signed certificates: %v", err)
	}

	// validate options
	if errs := serverOptions.Etcd.Validate(); len(errs) > 0 {
		return utilerrors.NewAggregate(errs)
	}
	if errs := serverOptions.SecureServing.Validate(); len(errs) > 0 {
		return utilerrors.NewAggregate(errs)
	}
	if errs := serverOptions.InsecureServing.Validate("insecure-port"); len(errs) > 0 {
		return utilerrors.NewAggregate(errs)
	}

	// create config from options
	config := genericapiserver.NewConfig().
		ApplyOptions(serverOptions.GenericServerRunOptions).
		ApplyInsecureServingOptions(serverOptions.InsecureServing)

	if _, err := config.ApplySecureServingOptions(serverOptions.SecureServing); err != nil {
		return fmt.Errorf("failed to configure https: %s", err)
	}
	if err := serverOptions.Authentication.Apply(config); err != nil {
		return fmt.Errorf("failed to configure authentication: %s", err)
	}

	config.Authorizer = authorizer.NewAlwaysAllowAuthorizer()
	config.SwaggerConfig = genericapiserver.DefaultSwaggerConfig()

	s, err := config.Complete().New()
	if err != nil {
		return fmt.Errorf("Error in bringing up the server: %v", err)
	}

	groupVersion := v1.SchemeGroupVersion
	groupName := groupVersion.Group
	groupMeta, err := api.Registry.Group(groupName)
	if err != nil {
		return fmt.Errorf("%v", err)
	}
	storageFactory := newStorageFactory()
	storageConfig, err := storageFactory.NewConfig(schema.GroupResource{Group: groupName, Resource: "testtype"})
	if err != nil {
		return fmt.Errorf("Unable to get storage config: %v", err)
	}

	testTypeOpts := generic.RESTOptions{
		StorageConfig:           storageConfig,
		Decorator:               generic.UndecoratedStorage,
		ResourcePrefix:          "testtypes",
		DeleteCollectionWorkers: 1,
	}

	restStorageMap := map[string]rest.Storage{
		"testtypes": testgroupetcd.NewREST(testTypeOpts),
	}
	apiGroupInfo := genericapiserver.APIGroupInfo{
		GroupMeta: *groupMeta,
		VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
			groupVersion.Version: restStorageMap,
		},
		Scheme:               api.Scheme,
		NegotiatedSerializer: api.Codecs,
	}
	if err := s.InstallAPIGroup(&apiGroupInfo); err != nil {
		return fmt.Errorf("Error in installing API: %v", err)
	}
	s.PrepareRun().Run(stopCh)
	return nil
}
<|endoftext|>


<commit_before>package quiclatest

type baseFlowController struct {
	bytesSent       uint64
	bytesReceived   uint64
	largestSent     uint64
	largestReceived uint64

	MaxDataLimit uint64
}

type StreamFlowController struct {
	IsStreamZero bool
	baseFlowController
	connFC *ConnectionFlowController
}

func (s *StreamFlowController) SendableBySize(largestOffset uint64) bool {
	return largestOffset <= s.MaxDataLimit
}

func (s *StreamFlowController) updateLargestReceived(offset uint64) {
	s.largestReceived = offset
	if !s.IsStreamZero {
		s.connFC.updateByteReceived(offset) // TODO: not correct
	}
}

func (s *StreamFlowController) updateLargestSent(offset uint64) {
	s.largestSent = offset
	if !s.IsStreamZero {
		s.connFC.updateByteSent(offset) // TODO: not correct
	}
}

type ConnectionFlowController struct {
	baseFlowController
}

func (c *ConnectionFlowController) updateByteSent(bytes uint64) {
	c.bytesSent += bytes
}
func (c *ConnectionFlowController) updateByteReceived(bytes uint64) {
	c.bytesReceived += bytes
}
<commit_msg>implement more presisely<commit_after>package quiclatest

import "github.com/ami-GS/gQUIC/latest/qtype"

type baseFlowController struct {
	bytesSent       uint64
	bytesReceived   uint64
	largestSent     uint64
	largestReceived uint64

	MaxDataLimit uint64
}

type StreamFlowController struct {
	IsStreamZero bool
	baseFlowController
	connFC *ConnectionFlowController
}

func (s *StreamFlowController) SendableByOffset(offset uint64, fin bool) bool {
	sendable := true
	if !s.IsStreamZero && fin {
		sendable = s.connFC.SendableByOffset(offset)
	}
	return sendable && offset <= s.MaxDataLimit
}

func (s *StreamFlowController) ReceivableByOffset(offset uint64, fin bool) error {
	if !s.IsStreamZero && fin {
		err := s.connFC.ReceivableByOffset(offset)
		if err != nil {
			return err
		}
	}

	if offset > s.MaxDataLimit {
		return qtype.FlowControlError
	}
	return nil
}

func (s *StreamFlowController) updateLargestReceived(offset uint64) {
	s.largestReceived = offset
}

func (s *StreamFlowController) updateLargestSent(offset uint64) {
	s.largestSent = offset
}

type ConnectionFlowController struct {
	baseFlowController
}

func (c *ConnectionFlowController) SendableByOffset(largestOffset uint64) bool {
	return c.bytesSent+largestOffset <= c.MaxDataLimit
}

func (c *ConnectionFlowController) ReceivableByOffset(largestOffset uint64) error {
	if c.bytesReceived+largestOffset > c.MaxDataLimit {
		return qtype.FlowControlReceivedTooMuchData
	}
	return nil
}

func (c *ConnectionFlowController) updateByteSent(largestOffset uint64) {
	c.bytesSent += largestOffset
}
func (c *ConnectionFlowController) updateByteReceived(largestOffset uint64) {
	c.bytesReceived += largestOffset
}
<|endoftext|>


<commit_before>// Copyright 2016 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package keybase

import (
	"fmt"
	"os/user"
	"path/filepath"
	"strings"
	"time"

	"github.com/kardianos/osext"
	"github.com/keybase/go-updater"
)

// destinationPath returns the app bundle path where this executable is located
func (c config) destinationPath() string {
	path, err := osext.Executable()
	if err != nil {
		c.log.Warningf("Error trying to determine our destination path: %s", err)
		return ""
	}
	return appBundleForPath(path)
}

func appBundleForPath(path string) string {
	if path == "" {
		return ""
	}
	paths := strings.SplitN(path, ".app", 2)
	// If no match, return ""
	if len(paths) <= 1 {
		return ""
	}
	return paths[0] + ".app"
}

// dir returns directory for configuration files on darwin
func (c config) dir() (string, error) {
	usr, err := user.Current()
	if err != nil {
		return "", err
	}
	if c.appName == "" {
		return "", fmt.Errorf("Unable to resolve config directory: No app name")
	}
	return filepath.Join(usr.HomeDir, "Library", "Application Support", c.appName), nil
}

func (c config) osVersion() string {
	out, err := updater.RunCommand("/usr/bin/sw_vers", []string{"-productVersion"}, 5*time.Second, c.log)
	if err != nil {
		c.log.Warningf("Error trying to determine OS version: %s (%s)", err, out)
		return ""
	}
	return strings.TrimSpace(out)
}

// UpdatePrompt is called when the user needs to accept an update
func (c context) UpdatePrompt(update updater.Update, options updater.UpdateOptions, promptOptions updater.UpdatePromptOptions) (*updater.UpdatePromptResponse, error) {
	destinationPath := c.config.destinationPath()
	if destinationPath == "" {
		return nil, fmt.Errorf("No destination path")
	}
	promptPath := filepath.Join(destinationPath, "Contents", "Resources", "Updater.app", "Contents", "MacOS", "Updater")
	return c.updatePrompt(promptPath, update, options, promptOptions)
}
<commit_msg>App name changed to include Keybase (for process list, dock icon name etc) (#38)<commit_after>// Copyright 2016 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package keybase

import (
	"fmt"
	"os/user"
	"path/filepath"
	"strings"
	"time"

	"github.com/kardianos/osext"
	"github.com/keybase/go-updater"
)

// destinationPath returns the app bundle path where this executable is located
func (c config) destinationPath() string {
	path, err := osext.Executable()
	if err != nil {
		c.log.Warningf("Error trying to determine our destination path: %s", err)
		return ""
	}
	return appBundleForPath(path)
}

func appBundleForPath(path string) string {
	if path == "" {
		return ""
	}
	paths := strings.SplitN(path, ".app", 2)
	// If no match, return ""
	if len(paths) <= 1 {
		return ""
	}
	return paths[0] + ".app"
}

// dir returns directory for configuration files on darwin
func (c config) dir() (string, error) {
	usr, err := user.Current()
	if err != nil {
		return "", err
	}
	if c.appName == "" {
		return "", fmt.Errorf("Unable to resolve config directory: No app name")
	}
	return filepath.Join(usr.HomeDir, "Library", "Application Support", c.appName), nil
}

func (c config) osVersion() string {
	out, err := updater.RunCommand("/usr/bin/sw_vers", []string{"-productVersion"}, 5*time.Second, c.log)
	if err != nil {
		c.log.Warningf("Error trying to determine OS version: %s (%s)", err, out)
		return ""
	}
	return strings.TrimSpace(out)
}

// UpdatePrompt is called when the user needs to accept an update
func (c context) UpdatePrompt(update updater.Update, options updater.UpdateOptions, promptOptions updater.UpdatePromptOptions) (*updater.UpdatePromptResponse, error) {
	destinationPath := c.config.destinationPath()
	if destinationPath == "" {
		return nil, fmt.Errorf("No destination path")
	}
	// For example, /Applications/Keybase.app/Contents/Resources/KeybaseUpdater.app/Contents/MacOS/Updater
	promptPath := filepath.Join(destinationPath, "Contents", "Resources", "KeybaseUpdater.app", "Contents", "MacOS", "Updater")
	return c.updatePrompt(promptPath, update, options, promptOptions)
}
<|endoftext|>


<commit_before>// Copyright 2013 Hui Chen
// Copyright 2016 ego 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 riot

import (
	// "fmt"
	"strings"

	"github.com/go-ego/gpy"
	"github.com/go-ego/riot/types"
)

// TMap defines the tokens map type map[string][]int
type TMap map[string][]int

type segmenterReq struct {
	docId uint64
	hash  uint32
	data  types.DocData
	// data        types.DocumentIndexData
	forceUpdate bool
}

// ForSplitData for split segment's data, segspl
func (engine *Engine) ForSplitData(splData []string, num int) (TMap, int) {
	var (
		numTokens int
		splitStr  string
	)
	tokensMap := make(map[string][]int)

	for i := 0; i < num; i++ {
		if splData[i] != "" {
			if !engine.stopTokens.IsStopToken(splData[i]) {
				numTokens++
				tokensMap[splData[i]] = append(tokensMap[splData[i]], numTokens)
			}

			splitStr += splData[i]
			if !engine.stopTokens.IsStopToken(splitStr) {
				numTokens++
				tokensMap[splitStr] = append(tokensMap[splitStr], numTokens)
			}

			if engine.initOptions.Using == 6 {
				// more combination
				var splitsStr string
				for s := i + 1; s < len(splData); s++ {
					splitsStr += splData[s]

					if !engine.stopTokens.IsStopToken(splitsStr) {
						numTokens++
						tokensMap[splitsStr] = append(tokensMap[splitsStr], numTokens)
					}
				}
			}

		}
	}

	return tokensMap, numTokens
}

func (engine *Engine) splitData(request segmenterReq) (TMap, int) {
	var (
		num       int
		numTokens int
	)
	tokensMap := make(map[string][]int)

	if request.data.Content != "" {
		request.data.Content = strings.ToLower(request.data.Content)
		if engine.initOptions.Using == 3 {
			// use segmenter
			segments := engine.segmenter.ModeSegment([]byte(request.data.Content),
				engine.initOptions.GseMode)

			for _, segment := range segments {
				token := segment.Token().Text()
				if !engine.stopTokens.IsStopToken(token) {
					tokensMap[token] = append(tokensMap[token], segment.Start())
				}
			}
			numTokens += len(segments)
		}

		if engine.initOptions.Using == 4 {
			// use segmenter
			splSpaData := strings.Split(request.data.Content, " ")
			num := len(splSpaData)
			if num == 1 {
				tokensMap[request.data.Content] = []int{1}
			}

			if num > 1 {
				tokenMap, numToken := engine.ForSplitData(splSpaData, num)
				numTokens += numToken

				for key, val := range tokenMap {
					tokensMap[key] = val
				}
			}
		}

		if engine.initOptions.Using != 4 {
			splData := strings.Split(request.data.Content, "")
			num = len(splData)
			tokenMap, numToken := engine.ForSplitData(splData, num)
			numTokens += numToken
			for key, val := range tokenMap {
				tokensMap[key] = val
			}
		}
	}

	for _, t := range request.data.Tokens {
		if !engine.stopTokens.IsStopToken(t.Text) {
			tokensMap[t.Text] = t.Locations
		}
	}

	numTokens += len(request.data.Tokens)

	return tokensMap, numTokens
}

func (engine *Engine) segmenterData(request segmenterReq) (TMap, int) {
	tokensMap := make(map[string][]int)
	numTokens := 0

	if engine.initOptions.Using == 0 && request.data.Content != "" {
		// Content 分词, 当文档正文不为空时，优先从内容分词中得到关键词
		segments := engine.segmenter.ModeSegment([]byte(request.data.Content),
			engine.initOptions.GseMode)

		for _, segment := range segments {
			token := segment.Token().Text()
			if !engine.stopTokens.IsStopToken(token) {
				tokensMap[token] = append(tokensMap[token], segment.Start())
			}
		}

		for _, t := range request.data.Tokens {
			if !engine.stopTokens.IsStopToken(t.Text) {
				tokensMap[t.Text] = t.Locations
			}
		}

		numTokens = len(segments) + len(request.data.Tokens)

		return tokensMap, numTokens
	}

	if engine.initOptions.Using == 1 && request.data.Content != "" {
		// Content 分词, 当文档正文不为空时，优先从内容分词中得到关键词
		segments := engine.segmenter.ModeSegment([]byte(request.data.Content),
			engine.initOptions.GseMode)

		for _, segment := range segments {
			token := segment.Token().Text()
			if !engine.stopTokens.IsStopToken(token) {
				tokensMap[token] = append(tokensMap[token], segment.Start())
			}
		}
		numTokens = len(segments)

		return tokensMap, numTokens
	}

	if engine.initOptions.Using == 2 ||
		((engine.initOptions.Using == 1 || engine.initOptions.Using == 3) &&
			request.data.Content == "") {
		for _, t := range request.data.Tokens {
			if !engine.stopTokens.IsStopToken(t.Text) {
				tokensMap[t.Text] = t.Locations
			}
		}

		numTokens = len(request.data.Tokens)

		return tokensMap, numTokens
	}

	tokenMap, lenSplitData := engine.splitData(request)

	return tokenMap, lenSplitData
}

func (engine *Engine) segmenterWorker() {
	for {
		request := <-engine.segmenterChan
		if request.docId == 0 {
			if request.forceUpdate {
				for i := 0; i < engine.initOptions.NumShards; i++ {
					engine.indexerAddDocChans[i] <- indexerAddDocReq{
						forceUpdate: true}
				}
			}
			continue
		}

		shard := engine.getShard(request.hash)
		tokensMap := make(map[string][]int)
		numTokens := 0
		if !engine.initOptions.NotUsingGse && engine.initOptions.Using != 0 {
			tokensMap, numTokens = engine.segmenterData(request)
		} else {
			if request.data.Content != "" {
				splSpaData := strings.Split(request.data.Content, " ")
				num := len(splSpaData)
				if num == 1 {
					tokensMap[request.data.Content] = []int{1}
				}

				if num > 1 {
					tokenMap, numToken := engine.ForSplitData(splSpaData, num)
					numTokens += numToken

					for key, val := range tokenMap {
						tokensMap[key] = val
					}
				}
			}

			for _, t := range request.data.Tokens {
				if !engine.stopTokens.IsStopToken(t.Text) {
					tokensMap[t.Text] = t.Locations
				}
			}

			numTokens = len(request.data.Tokens)
		}

		// 加入非分词的文档标签
		for _, label := range request.data.Labels {
			if !engine.initOptions.NotUsingGse {
				if !engine.stopTokens.IsStopToken(label) {
					// 当正文中已存在关键字时，若不判断，位置信息将会丢失
					if _, ok := tokensMap[label]; !ok {
						tokensMap[label] = []int{}
					}
				}
			} else {
				// 当正文中已存在关键字时，若不判断，位置信息将会丢失
				if _, ok := tokensMap[label]; !ok {
					tokensMap[label] = []int{}
				}
			}
		}

		indexerRequest := indexerAddDocReq{
			doc: &types.DocIndex{
				DocId:    request.docId,
				TokenLen: float32(numTokens),
				Keywords: make([]types.KeywordIndex, len(tokensMap)),
			},
			forceUpdate: request.forceUpdate,
		}
		iTokens := 0
		for k, v := range tokensMap {
			indexerRequest.doc.Keywords[iTokens] = types.KeywordIndex{
				Text: k,
				// 非分词标注的词频设置为0，不参与tf-idf计算
				Frequency: float32(len(v)),
				Starts:    v}
			iTokens++
		}

		engine.indexerAddDocChans[shard] <- indexerRequest
		if request.forceUpdate {
			for i := 0; i < engine.initOptions.NumShards; i++ {
				if i == shard {
					continue
				}
				engine.indexerAddDocChans[i] <- indexerAddDocReq{forceUpdate: true}
			}
		}
		rankerRequest := rankerAddDocReq{
			// docId: request.docId, fields: request.data.Fields}
			docId: request.docId, fields: request.data.Fields,
			content: request.data.Content, attri: request.data.Attri}
		engine.rankerAddDocChans[shard] <- rankerRequest
	}
}

// PinYin get the Chinese alphabet and abbreviation
func (engine *Engine) PinYin(hans string) []string {
	var (
		str      string
		pyStr    string
		strArr   []string
		splitStr string
		// splitArr []string
	)

	//
	splitHans := strings.Split(hans, "")
	for i := 0; i < len(splitHans); i++ {
		if splitHans[i] != "" {
			if !engine.stopTokens.IsStopToken(splitHans[i]) {
				strArr = append(strArr, splitHans[i])
			}
			splitStr += splitHans[i]
		}
		if !engine.stopTokens.IsStopToken(splitStr) {
			strArr = append(strArr, splitStr)
		}
	}

	// Segment 分词
	if !engine.initOptions.NotUsingGse {
		sehans := engine.Segment(hans)
		for h := 0; h < len(sehans); h++ {
			if !engine.stopTokens.IsStopToken(sehans[h]) {
				strArr = append(strArr, sehans[h])
			}
		}
	}
	//
	// py := pinyin.LazyConvert(sehans[h], nil)
	py := gpy.LazyConvert(hans, nil)

	// log.Println("py...", py)
	for i := 0; i < len(py); i++ {
		// log.Println("py[i]...", py[i])
		pyStr += py[i]
		if !engine.stopTokens.IsStopToken(pyStr) {
			strArr = append(strArr, pyStr)
		}

		if len(py[i]) > 0 {
			str += py[i][0:1]
			if !engine.stopTokens.IsStopToken(str) {
				strArr = append(strArr, str)
			}
		}
	}

	return strArr
}
<commit_msg>fix some logic error<commit_after>// Copyright 2013 Hui Chen
// Copyright 2016 ego 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 riot

import (
	// "fmt"
	"strings"

	"github.com/go-ego/gpy"
	"github.com/go-ego/riot/types"
)

// TMap defines the tokens map type map[string][]int
type TMap map[string][]int

type segmenterReq struct {
	docId uint64
	hash  uint32
	data  types.DocData
	// data        types.DocumentIndexData
	forceUpdate bool
}

// ForSplitData for split segment's data, segspl
func (engine *Engine) ForSplitData(splData []string, num int) (TMap, int) {
	var (
		numTokens int
		splitStr  string
	)
	tokensMap := make(map[string][]int)

	for i := 0; i < num; i++ {
		if splData[i] != "" {
			if !engine.stopTokens.IsStopToken(splData[i]) {
				numTokens++
				tokensMap[splData[i]] = append(tokensMap[splData[i]], numTokens)
			}

			splitStr += splData[i]
			if !engine.stopTokens.IsStopToken(splitStr) {
				numTokens++
				tokensMap[splitStr] = append(tokensMap[splitStr], numTokens)
			}

			if engine.initOptions.Using == 6 {
				// more combination
				var splitsStr string
				for s := i + 1; s < len(splData); s++ {
					splitsStr += splData[s]

					if !engine.stopTokens.IsStopToken(splitsStr) {
						numTokens++
						tokensMap[splitsStr] = append(tokensMap[splitsStr], numTokens)
					}
				}
			}

		}
	}

	return tokensMap, numTokens
}

func (engine *Engine) splitData(request segmenterReq) (TMap, int) {
	var (
		num       int
		numTokens int
	)
	tokensMap := make(map[string][]int)

	if request.data.Content != "" {
		request.data.Content = strings.ToLower(request.data.Content)
		if engine.initOptions.Using == 3 {
			// use segmenter
			segments := engine.segmenter.ModeSegment([]byte(request.data.Content),
				engine.initOptions.GseMode)

			for _, segment := range segments {
				token := segment.Token().Text()
				if !engine.stopTokens.IsStopToken(token) {
					tokensMap[token] = append(tokensMap[token], segment.Start())
				}
			}
			numTokens += len(segments)
		}

		if engine.initOptions.Using == 4 {
			// use segmenter
			splSpaData := strings.Split(request.data.Content, " ")
			num := len(splSpaData)
			// if num == 1 {
			// 	tokensMap[request.data.Content] = []int{1}
			// }

			if num > 0 {
				tokenMap, numToken := engine.ForSplitData(splSpaData, num)
				numTokens += numToken

				for key, val := range tokenMap {
					tokensMap[key] = val
				}
			}
		}

		if engine.initOptions.Using != 4 {
			splData := strings.Split(request.data.Content, "")
			num = len(splData)
			tokenMap, numToken := engine.ForSplitData(splData, num)
			numTokens += numToken
			for key, val := range tokenMap {
				tokensMap[key] = val
			}
		}
	}

	for _, t := range request.data.Tokens {
		if !engine.stopTokens.IsStopToken(t.Text) {
			tokensMap[t.Text] = t.Locations
		}
	}

	numTokens += len(request.data.Tokens)

	return tokensMap, numTokens
}

func (engine *Engine) segmenterData(request segmenterReq) (TMap, int) {
	tokensMap := make(map[string][]int)
	numTokens := 0

	if engine.initOptions.Using == 0 && request.data.Content != "" {
		// Content 分词, 当文档正文不为空时，优先从内容分词中得到关键词
		segments := engine.segmenter.ModeSegment([]byte(request.data.Content),
			engine.initOptions.GseMode)

		for _, segment := range segments {
			token := segment.Token().Text()
			if !engine.stopTokens.IsStopToken(token) {
				tokensMap[token] = append(tokensMap[token], segment.Start())
			}
		}

		for _, t := range request.data.Tokens {
			if !engine.stopTokens.IsStopToken(t.Text) {
				tokensMap[t.Text] = t.Locations
			}
		}

		numTokens = len(segments) + len(request.data.Tokens)

		return tokensMap, numTokens
	}

	if engine.initOptions.Using == 1 && request.data.Content != "" {
		// Content 分词, 当文档正文不为空时，优先从内容分词中得到关键词
		segments := engine.segmenter.ModeSegment([]byte(request.data.Content),
			engine.initOptions.GseMode)

		for _, segment := range segments {
			token := segment.Token().Text()
			if !engine.stopTokens.IsStopToken(token) {
				tokensMap[token] = append(tokensMap[token], segment.Start())
			}
		}
		numTokens = len(segments)

		return tokensMap, numTokens
	}

	if engine.initOptions.Using == 2 ||
		((engine.initOptions.Using == 1 || engine.initOptions.Using == 3) &&
			request.data.Content == "") {
		for _, t := range request.data.Tokens {
			if !engine.stopTokens.IsStopToken(t.Text) {
				tokensMap[t.Text] = t.Locations
			}
		}

		numTokens = len(request.data.Tokens)

		return tokensMap, numTokens
	}

	tokenMap, lenSplitData := engine.splitData(request)

	return tokenMap, lenSplitData
}

func (engine *Engine) segmenterWorker() {
	for {
		request := <-engine.segmenterChan
		if request.docId == 0 {
			if request.forceUpdate {
				for i := 0; i < engine.initOptions.NumShards; i++ {
					engine.indexerAddDocChans[i] <- indexerAddDocReq{
						forceUpdate: true}
				}
			}
			continue
		}

		shard := engine.getShard(request.hash)
		tokensMap := make(map[string][]int)
		numTokens := 0
		if !(engine.initOptions.NotUsingGse && engine.initOptions.Using == 0) {
			tokensMap, numTokens = engine.segmenterData(request)
		} else {
			if request.data.Content != "" {
				splSpaData := strings.Split(request.data.Content, " ")
				num := len(splSpaData)
				if num == 1 {
					tokensMap[request.data.Content] = []int{1}
				}

				if num > 1 {
					tokenMap, numToken := engine.ForSplitData(splSpaData, num)
					numTokens += numToken

					for key, val := range tokenMap {
						tokensMap[key] = val
					}
				}
			}

			for _, t := range request.data.Tokens {
				if !engine.stopTokens.IsStopToken(t.Text) {
					tokensMap[t.Text] = t.Locations
				}
			}

			numTokens = len(request.data.Tokens)
		}

		// 加入非分词的文档标签
		for _, label := range request.data.Labels {
			if !engine.initOptions.NotUsingGse {
				if !engine.stopTokens.IsStopToken(label) {
					// 当正文中已存在关键字时，若不判断，位置信息将会丢失
					if _, ok := tokensMap[label]; !ok {
						tokensMap[label] = []int{}
					}
				}
			} else {
				// 当正文中已存在关键字时，若不判断，位置信息将会丢失
				if _, ok := tokensMap[label]; !ok {
					tokensMap[label] = []int{}
				}
			}
		}

		indexerRequest := indexerAddDocReq{
			doc: &types.DocIndex{
				DocId:    request.docId,
				TokenLen: float32(numTokens),
				Keywords: make([]types.KeywordIndex, len(tokensMap)),
			},
			forceUpdate: request.forceUpdate,
		}
		iTokens := 0
		for k, v := range tokensMap {
			indexerRequest.doc.Keywords[iTokens] = types.KeywordIndex{
				Text: k,
				// 非分词标注的词频设置为0，不参与tf-idf计算
				Frequency: float32(len(v)),
				Starts:    v}
			iTokens++
		}

		engine.indexerAddDocChans[shard] <- indexerRequest
		if request.forceUpdate {
			for i := 0; i < engine.initOptions.NumShards; i++ {
				if i == shard {
					continue
				}
				engine.indexerAddDocChans[i] <- indexerAddDocReq{forceUpdate: true}
			}
		}
		rankerRequest := rankerAddDocReq{
			// docId: request.docId, fields: request.data.Fields}
			docId: request.docId, fields: request.data.Fields,
			content: request.data.Content, attri: request.data.Attri}
		engine.rankerAddDocChans[shard] <- rankerRequest
	}
}

// PinYin get the Chinese alphabet and abbreviation
func (engine *Engine) PinYin(hans string) []string {
	var (
		str      string
		pyStr    string
		strArr   []string
		splitStr string
		// splitArr []string
	)

	//
	splitHans := strings.Split(hans, "")
	for i := 0; i < len(splitHans); i++ {
		if splitHans[i] != "" {
			if !engine.stopTokens.IsStopToken(splitHans[i]) {
				strArr = append(strArr, splitHans[i])
			}
			splitStr += splitHans[i]
		}
		if !engine.stopTokens.IsStopToken(splitStr) {
			strArr = append(strArr, splitStr)
		}
	}

	// Segment 分词
	if !engine.initOptions.NotUsingGse {
		sehans := engine.Segment(hans)
		for h := 0; h < len(sehans); h++ {
			if !engine.stopTokens.IsStopToken(sehans[h]) {
				strArr = append(strArr, sehans[h])
			}
		}
	}
	//
	// py := pinyin.LazyConvert(sehans[h], nil)
	py := gpy.LazyConvert(hans, nil)

	// log.Println("py...", py)
	for i := 0; i < len(py); i++ {
		// log.Println("py[i]...", py[i])
		pyStr += py[i]
		if !engine.stopTokens.IsStopToken(pyStr) {
			strArr = append(strArr, pyStr)
		}

		if len(py[i]) > 0 {
			str += py[i][0:1]
			if !engine.stopTokens.IsStopToken(str) {
				strArr = append(strArr, str)
			}
		}
	}

	return strArr
}
<|endoftext|>