<commit_before>package main

import (
	"log"
	"os"
	"path/filepath"
	"sync"

	"github.com/ernado/selectel/storage"
	config "github.com/tj/go-config"
)

type Options struct {
	User      string `help:"selectel user name"`
	Password  string `help:"selectel password"`
	Container string `help:"name of bucket"`
	Dir       string `help:"directory which will be uploaded"`
}

func main() {
	var options Options
	config.MustResolve(&options)

	api, err := storage.New(options.User, options.Password)
	if err != nil {
		log.Fatal(err)
	}
	api.ContainerInfo(options.Container)

	upload := make(chan string, 1048576)
	var wg sync.WaitGroup

	go func() {
		wg.Add(1)
		for file := range upload {
			wg.Add(1)
			go func(filename string) {
				defer wg.Done()

				file, err := os.Open(filename)
				if err != nil {
					log.Printf("Can't open file %s: %v", filename, err)
					return
				}
				defer file.Close()

				err = api.Upload(file, options.Container, filepath.ToSlash(filename), "")
				if err != nil {
					log.Printf("Can't upload file %s: %v", filename, err)
					return
				}

				log.Printf("File %s uploaded", filename)

			}(file)

		}
		wg.Done()
	}()

	err = filepath.Walk(options.Dir, func(path string, info os.FileInfo, err error) error {
		if !info.IsDir() && path[0] != '.' {
			upload <- path
		}

		return nil
	})

	//upload <- filepath.Join(options.Dir, "README.md")
	close(upload)

	if err != nil {
		log.Printf("Error: %v", err)
		return
	}

	wg.Wait()

	log.Println("Well done!")

}
<commit_msg>Added clering of bucket<commit_after>package main

import (
	"log"
	"os"
	"path/filepath"
	"sync"

	"github.com/ernado/selectel/storage"
	config "github.com/tj/go-config"
)

type Options struct {
	User      string `help:"selectel user name"`
	Password  string `help:"selectel password"`
	Container string `help:"name of bucket"`
	Dir       string `help:"directory which will be uploaded"`
}

func main() {
	var options Options
	config.MustResolve(&options)

	api, err := storage.New(options.User, options.Password)
	if err != nil {
		log.Fatal(err)
	}

	objects, err := api.Container(options.Container).Objects()
	if err != nil {
		log.Fatal(err)
	}
	for _, obj := range objects {
		err = obj.Remove()
		if err != nil {
			log.Printf("Can't remove file: %v", err)
			continue
		}
	}

	var wg sync.WaitGroup
	upload := make(chan string, 1048576)

	go func() {
		wg.Add(1)
		for file := range upload {
			wg.Add(1)
			go func(filename string) {
				defer wg.Done()

				file, err := os.Open(filename)
				if err != nil {
					log.Printf("Can't open file %s: %v", filename, err)
					return
				}
				defer file.Close()

				err = api.Upload(file, options.Container, filepath.ToSlash(filename), "")
				if err != nil {
					log.Printf("Can't upload file %s: %v", filename, err)
					return
				}

				log.Printf("File %s uploaded", filename)

			}(file)

		}
		wg.Done()
	}()

	err = filepath.Walk(options.Dir, func(path string, info os.FileInfo, err error) error {
		if !info.IsDir() && path[0] != '.' {
			upload <- path
		}

		return nil
	})

	//upload <- filepath.Join(options.Dir, "README.md")
	close(upload)

	if err != nil {
		log.Printf("Error: %v", err)
		return
	}

	wg.Wait()

	log.Println("Well done!")

}
<|endoftext|>


<commit_before>package main

import (
	"flag"

	"github.com/vdesjardins/cert-monitor/controller"
)

var (
	configPath = flag.String("config", "/etc/certmon.yml", "path to main configuration file")
	oneTime    = flag.Bool("onetime", false, "refresh certificates without entering the endless loop")
	noReload   = flag.Bool("noreload", false, "do not reload services associated with each certificate")
)

func main() {
	flag.Parse()

	if *oneTime == true {
		controller.ExecOnce(*configPath, *noReload)
	} else {
		controller.ExecLoop(*configPath, *noReload)
	}
}
<commit_msg>rename default config file name to cert-monitor<commit_after>package main

import (
	"flag"

	"github.com/vdesjardins/cert-monitor/controller"
)

var (
	configPath = flag.String("config", "/etc/cert-monitor.yml", "path to main configuration file")
	oneTime    = flag.Bool("onetime", false, "refresh certificates without entering the endless loop")
	noReload   = flag.Bool("noreload", false, "do not reload services associated with each certificate")
)

func main() {
	flag.Parse()

	if *oneTime == true {
		controller.ExecOnce(*configPath, *noReload)
	} else {
		controller.ExecLoop(*configPath, *noReload)
	}
}
<|endoftext|>


<commit_before>// Copyright 2018 Google LLC
//
// 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 main

import (
	"context"
	"crypto/tls"
	"crypto/x509"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/signal"
	"time"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/credentials"
	healthpb "google.golang.org/grpc/health/grpc_health_v1"
	"google.golang.org/grpc/status"
)

var (
	flAddr          string
	flService       string
	flUserAgent     string
	flConnTimeout   time.Duration
	flRPCTimeout    time.Duration
	flTLS           bool
	flTLSNoVerify   bool
	flTLSCACert     string
	flTLSClientCert string
	flTLSClientKey  string
	flTLSServerName string
	flVerbose       bool
)

const (
	// StatusInvalidArguments indicates specified invalid arguments.
	StatusInvalidArguments = 1
	// StatusConnectionFailure indicates connection failed.
	StatusConnectionFailure = 2
	// StatusRPCFailure indicates rpc failed.
	StatusRPCFailure = 3
	// StatusUnhealthy indicates rpc succeeded but indicates unhealthy service.
	StatusUnhealthy = 4
)

func init() {
	log.SetFlags(0)
	flag.StringVar(&flAddr, "addr", "", "(required) tcp host:port to connect")
	flag.StringVar(&flService, "service", "", "service name to check (default: \"\")")
	flag.StringVar(&flUserAgent, "user-agent", "grpc_health_probe", "user-agent header value of health check requests")
	// timeouts
	flag.DurationVar(&flConnTimeout, "connect-timeout", time.Second, "timeout for establishing connection")
	flag.DurationVar(&flRPCTimeout, "rpc-timeout", time.Second, "timeout for health check rpc")
	// tls settings
	flag.BoolVar(&flTLS, "tls", false, "use TLS (default: false, INSECURE plaintext transport)")
	flag.BoolVar(&flTLSNoVerify, "tls-no-verify", false, "(with -tls) don't verify the certificate (INSECURE) presented by the server (default: false)")
	flag.StringVar(&flTLSCACert, "tls-ca-cert", "", "(with -tls, optional) file containing trusted certificates for verifying server")
	flag.StringVar(&flTLSClientCert, "tls-client-cert", "", "(with -tls, optional) client certificate for authenticating to the server (requires -tls-client-key)")
	flag.StringVar(&flTLSClientKey, "tls-client-key", "", "(with -tls) client private key for authenticating to the server (requires -tls-client-cert)")
	flag.StringVar(&flTLSServerName, "tls-server-name", "", "(with -tls) override the hostname used to verify the server certificate")
	flag.BoolVar(&flVerbose, "v", false, "verbose logs")

	flag.Parse()

	argError := func(s string, v ...interface{}) {
		log.Printf("error: "+s, v...)
		os.Exit(StatusInvalidArguments)
	}

	if flAddr == "" {
		argError("-addr not specified")
	}
	if flConnTimeout <= 0 {
		argError("-connect-timeout must be greater than zero (specified: %v)", flConnTimeout)
	}
	if flRPCTimeout <= 0 {
		argError("-rpc-timeout must be greater than zero (specified: %v)", flRPCTimeout)
	}
	if !flTLS && flTLSNoVerify {
		argError("specified -tls-no-verify without specifying -tls")
	}
	if !flTLS && flTLSCACert != "" {
		argError("specified -tls-ca-cert without specifying -tls")
	}
	if !flTLS && flTLSClientCert != "" {
		argError("specified -tls-client-cert without specifying -tls")
	}
	if !flTLS && flTLSServerName != "" {
		argError("specified -tls-server-name without specifying -tls")
	}
	if flTLSClientCert != "" && flTLSClientKey == "" {
		argError("specified -tls-client-cert without specifying -tls-client-key")
	}
	if flTLSClientCert == "" && flTLSClientKey != "" {
		argError("specified -tls-client-key without specifying -tls-client-cert")
	}
	if flTLSNoVerify && flTLSCACert != "" {
		argError("cannot specify -tls-ca-cert with -tls-no-verify (CA cert would not be used)")
	}
	if flTLSNoVerify && flTLSServerName != "" {
		argError("cannot specify -tls-server-name with -tls-no-verify (server name would not be used)")
	}

	if flVerbose {
		log.Printf("parsed options:")
		log.Printf("> addr=%s conn_timeout=%v rpc_timeout=%v", flAddr, flConnTimeout, flRPCTimeout)
		log.Printf("> tls=%v", flTLS)
		if flTLS {
			log.Printf("  > no-verify=%v ", flTLSNoVerify)
			log.Printf("  > ca-cert=%s", flTLSCACert)
			log.Printf("  > client-cert=%s", flTLSClientCert)
			log.Printf("  > client-key=%s", flTLSClientKey)
			log.Printf("  > server-name=%s", flTLSServerName)
		}
	}
}

func buildCredentials(skipVerify bool, caCerts, clientCert, clientKey, serverName string) (credentials.TransportCredentials, error) {
	var cfg tls.Config

	if clientCert != "" && clientKey != "" {
		keyPair, err := tls.LoadX509KeyPair(clientCert, clientKey)
		if err != nil {
			return nil, fmt.Errorf("failed to load tls client cert/key pair. error=%v", err)
		}
		cfg.Certificates = []tls.Certificate{keyPair}
	}

	if skipVerify {
		cfg.InsecureSkipVerify = true
	} else if caCerts != "" {
		// override system roots
		rootCAs := x509.NewCertPool()
		pem, err := ioutil.ReadFile(caCerts)
		if err != nil {
			return nil, fmt.Errorf("failed to load root CA certificates from file (%s) error=%v", caCerts, err)
		}
		if !rootCAs.AppendCertsFromPEM(pem) {
			return nil, fmt.Errorf("no root CA certs parsed from file %s", caCerts)
		}
		cfg.RootCAs = rootCAs
	}
	if serverName != "" {
		cfg.ServerName = serverName
	}
	return credentials.NewTLS(&cfg), nil
}

func main() {
	retcode := 0
	defer func() { os.Exit(retcode) }()

	ctx, cancel := context.WithCancel(context.Background())

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		sig := <-c
		if sig == os.Interrupt {
			log.Printf("cancellation received")
			cancel()
			return
		}
	}()

	opts := []grpc.DialOption{
		grpc.WithUserAgent(flUserAgent),
		grpc.WithBlock()}
	if flTLS {
		creds, err := buildCredentials(flTLSNoVerify, flTLSCACert, flTLSClientCert, flTLSClientKey, flTLSServerName)
		if err != nil {
			log.Printf("failed to initialize tls credentials. error=%v", err)
			retcode = StatusInvalidArguments
			return
		}
		opts = append(opts, grpc.WithTransportCredentials(creds))
	} else {
		opts = append(opts, grpc.WithInsecure())
	}

	if flVerbose {
		log.Print("establishing connection")
	}
	connStart := time.Now()
	dialCtx, cancel2 := context.WithTimeout(ctx, flConnTimeout)
	defer cancel2()
	conn, err := grpc.DialContext(dialCtx, flAddr, opts...)
	if err != nil {
		if err == context.DeadlineExceeded {
			log.Printf("timeout: failed to connect service %q within %v", flAddr, flConnTimeout)
		} else {
			log.Printf("error: failed to connect service at %q: %+v", flAddr, err)
		}
		retcode = StatusConnectionFailure
		return
	}
	connDuration := time.Since(connStart)
	defer conn.Close()
	if flVerbose {
		log.Printf("connection establisted (took %v)", connDuration)
	}

	rpcStart := time.Now()
	rpcCtx, rpcCancel := context.WithTimeout(ctx, flRPCTimeout)
	defer rpcCancel()
	resp, err := healthpb.NewHealthClient(conn).Check(rpcCtx, &healthpb.HealthCheckRequest{Service: flService})
	if err != nil {
		if stat, ok := status.FromError(err); ok && stat.Code() == codes.Unimplemented {
			log.Printf("error: this server does not implement the grpc health protocol (grpc.health.v1.Health)")
		} else if stat, ok := status.FromError(err); ok && stat.Code() == codes.DeadlineExceeded {
			log.Printf("timeout: health rpc did not complete within %v", flRPCTimeout)
		} else {
			log.Printf("error: health rpc failed: %+v", err)
		}
		retcode = StatusRPCFailure
		return
	}
	rpcDuration := time.Since(rpcStart)

	if resp.GetStatus() != healthpb.HealthCheckResponse_SERVING {
		log.Printf("service unhealthy (responded with %q)", resp.GetStatus().String())
		retcode = StatusUnhealthy
		return
	}
	if flVerbose {
		log.Printf("time elapsed: connect=%v rpc=%v", connDuration, rpcDuration)
	}
	log.Printf("status: %v", resp.GetStatus().String())
}
<commit_msg>Fix the exit status for incorrect flag (#42)<commit_after>// Copyright 2018 Google LLC
//
// 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 main

import (
	"context"
	"crypto/tls"
	"crypto/x509"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/signal"
	"time"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/credentials"
	healthpb "google.golang.org/grpc/health/grpc_health_v1"
	"google.golang.org/grpc/status"
)

var (
	flAddr          string
	flService       string
	flUserAgent     string
	flConnTimeout   time.Duration
	flRPCTimeout    time.Duration
	flTLS           bool
	flTLSNoVerify   bool
	flTLSCACert     string
	flTLSClientCert string
	flTLSClientKey  string
	flTLSServerName string
	flVerbose       bool
)

const (
	// StatusInvalidArguments indicates specified invalid arguments.
	StatusInvalidArguments = 1
	// StatusConnectionFailure indicates connection failed.
	StatusConnectionFailure = 2
	// StatusRPCFailure indicates rpc failed.
	StatusRPCFailure = 3
	// StatusUnhealthy indicates rpc succeeded but indicates unhealthy service.
	StatusUnhealthy = 4
)

func init() {
	flagSet := flag.NewFlagSet("", flag.ContinueOnError)
	log.SetFlags(0)
	flagSet.StringVar(&flAddr, "addr", "", "(required) tcp host:port to connect")
	flagSet.StringVar(&flService, "service", "", "service name to check (default: \"\")")
	flagSet.StringVar(&flUserAgent, "user-agent", "grpc_health_probe", "user-agent header value of health check requests")
	// timeouts
	flagSet.DurationVar(&flConnTimeout, "connect-timeout", time.Second, "timeout for establishing connection")
	flagSet.DurationVar(&flRPCTimeout, "rpc-timeout", time.Second, "timeout for health check rpc")
	// tls settings
	flagSet.BoolVar(&flTLS, "tls", false, "use TLS (default: false, INSECURE plaintext transport)")
	flagSet.BoolVar(&flTLSNoVerify, "tls-no-verify", false, "(with -tls) don't verify the certificate (INSECURE) presented by the server (default: false)")
	flagSet.StringVar(&flTLSCACert, "tls-ca-cert", "", "(with -tls, optional) file containing trusted certificates for verifying server")
	flagSet.StringVar(&flTLSClientCert, "tls-client-cert", "", "(with -tls, optional) client certificate for authenticating to the server (requires -tls-client-key)")
	flagSet.StringVar(&flTLSClientKey, "tls-client-key", "", "(with -tls) client private key for authenticating to the server (requires -tls-client-cert)")
	flagSet.StringVar(&flTLSServerName, "tls-server-name", "", "(with -tls) override the hostname used to verify the server certificate")
	flagSet.BoolVar(&flVerbose, "v", false, "verbose logs")

	err := flagSet.Parse(os.Args[1:])
	if err != nil {
		os.Exit(StatusInvalidArguments)
	}

	argError := func(s string, v ...interface{}) {
		log.Printf("error: "+s, v...)
		os.Exit(StatusInvalidArguments)
	}

	if flAddr == "" {
		argError("-addr not specified")
	}
	if flConnTimeout <= 0 {
		argError("-connect-timeout must be greater than zero (specified: %v)", flConnTimeout)
	}
	if flRPCTimeout <= 0 {
		argError("-rpc-timeout must be greater than zero (specified: %v)", flRPCTimeout)
	}
	if !flTLS && flTLSNoVerify {
		argError("specified -tls-no-verify without specifying -tls")
	}
	if !flTLS && flTLSCACert != "" {
		argError("specified -tls-ca-cert without specifying -tls")
	}
	if !flTLS && flTLSClientCert != "" {
		argError("specified -tls-client-cert without specifying -tls")
	}
	if !flTLS && flTLSServerName != "" {
		argError("specified -tls-server-name without specifying -tls")
	}
	if flTLSClientCert != "" && flTLSClientKey == "" {
		argError("specified -tls-client-cert without specifying -tls-client-key")
	}
	if flTLSClientCert == "" && flTLSClientKey != "" {
		argError("specified -tls-client-key without specifying -tls-client-cert")
	}
	if flTLSNoVerify && flTLSCACert != "" {
		argError("cannot specify -tls-ca-cert with -tls-no-verify (CA cert would not be used)")
	}
	if flTLSNoVerify && flTLSServerName != "" {
		argError("cannot specify -tls-server-name with -tls-no-verify (server name would not be used)")
	}

	if flVerbose {
		log.Printf("parsed options:")
		log.Printf("> addr=%s conn_timeout=%v rpc_timeout=%v", flAddr, flConnTimeout, flRPCTimeout)
		log.Printf("> tls=%v", flTLS)
		if flTLS {
			log.Printf("  > no-verify=%v ", flTLSNoVerify)
			log.Printf("  > ca-cert=%s", flTLSCACert)
			log.Printf("  > client-cert=%s", flTLSClientCert)
			log.Printf("  > client-key=%s", flTLSClientKey)
			log.Printf("  > server-name=%s", flTLSServerName)
		}
	}
}

func buildCredentials(skipVerify bool, caCerts, clientCert, clientKey, serverName string) (credentials.TransportCredentials, error) {
	var cfg tls.Config

	if clientCert != "" && clientKey != "" {
		keyPair, err := tls.LoadX509KeyPair(clientCert, clientKey)
		if err != nil {
			return nil, fmt.Errorf("failed to load tls client cert/key pair. error=%v", err)
		}
		cfg.Certificates = []tls.Certificate{keyPair}
	}

	if skipVerify {
		cfg.InsecureSkipVerify = true
	} else if caCerts != "" {
		// override system roots
		rootCAs := x509.NewCertPool()
		pem, err := ioutil.ReadFile(caCerts)
		if err != nil {
			return nil, fmt.Errorf("failed to load root CA certificates from file (%s) error=%v", caCerts, err)
		}
		if !rootCAs.AppendCertsFromPEM(pem) {
			return nil, fmt.Errorf("no root CA certs parsed from file %s", caCerts)
		}
		cfg.RootCAs = rootCAs
	}
	if serverName != "" {
		cfg.ServerName = serverName
	}
	return credentials.NewTLS(&cfg), nil
}

func main() {
	retcode := 0
	defer func() { os.Exit(retcode) }()

	ctx, cancel := context.WithCancel(context.Background())

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		sig := <-c
		if sig == os.Interrupt {
			log.Printf("cancellation received")
			cancel()
			return
		}
	}()

	opts := []grpc.DialOption{
		grpc.WithUserAgent(flUserAgent),
		grpc.WithBlock()}
	if flTLS {
		creds, err := buildCredentials(flTLSNoVerify, flTLSCACert, flTLSClientCert, flTLSClientKey, flTLSServerName)
		if err != nil {
			log.Printf("failed to initialize tls credentials. error=%v", err)
			retcode = StatusInvalidArguments
			return
		}
		opts = append(opts, grpc.WithTransportCredentials(creds))
	} else {
		opts = append(opts, grpc.WithInsecure())
	}

	if flVerbose {
		log.Print("establishing connection")
	}
	connStart := time.Now()
	dialCtx, cancel2 := context.WithTimeout(ctx, flConnTimeout)
	defer cancel2()
	conn, err := grpc.DialContext(dialCtx, flAddr, opts...)
	if err != nil {
		if err == context.DeadlineExceeded {
			log.Printf("timeout: failed to connect service %q within %v", flAddr, flConnTimeout)
		} else {
			log.Printf("error: failed to connect service at %q: %+v", flAddr, err)
		}
		retcode = StatusConnectionFailure
		return
	}
	connDuration := time.Since(connStart)
	defer conn.Close()
	if flVerbose {
		log.Printf("connection establisted (took %v)", connDuration)
	}

	rpcStart := time.Now()
	rpcCtx, rpcCancel := context.WithTimeout(ctx, flRPCTimeout)
	defer rpcCancel()
	resp, err := healthpb.NewHealthClient(conn).Check(rpcCtx, &healthpb.HealthCheckRequest{Service: flService})
	if err != nil {
		if stat, ok := status.FromError(err); ok && stat.Code() == codes.Unimplemented {
			log.Printf("error: this server does not implement the grpc health protocol (grpc.health.v1.Health)")
		} else if stat, ok := status.FromError(err); ok && stat.Code() == codes.DeadlineExceeded {
			log.Printf("timeout: health rpc did not complete within %v", flRPCTimeout)
		} else {
			log.Printf("error: health rpc failed: %+v", err)
		}
		retcode = StatusRPCFailure
		return
	}
	rpcDuration := time.Since(rpcStart)

	if resp.GetStatus() != healthpb.HealthCheckResponse_SERVING {
		log.Printf("service unhealthy (responded with %q)", resp.GetStatus().String())
		retcode = StatusUnhealthy
		return
	}
	if flVerbose {
		log.Printf("time elapsed: connect=%v rpc=%v", connDuration, rpcDuration)
	}
	log.Printf("status: %v", resp.GetStatus().String())
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"log/syslog"
	"net/http"
	"os"
	"runtime"
	"strconv"
	"strings"
	"vip/fetch"
	"vip/peer"
	"vip/q"
	"vip/store"

	"github.com/bradfitz/http2"
	"github.com/golang/groupcache"
	"github.com/gorilla/mux"
	"github.com/mitchellh/goamz/aws"
	"github.com/mitchellh/goamz/s3"
)

const (
	KeyFilePath  = "/etc/vip/application.key"
	CertFilePath = "/etc/vip/application.pem"
)

var (
	cache     *groupcache.Group
	peers     peer.CachePool
	storage   store.ImageStore
	authToken string
	origins   []string
	limit     int64
	verbose   *bool   = flag.Bool("verbose", false, "verbose logging")
	httpport  *string = flag.String("httpport", "8080", "target port")
	secure    bool    = false
	Queue     q.Queue
)

func listenHttp() {
	log.Printf("Listening on port :%s\n", *httpport)

	port := fmt.Sprintf(":%s", *httpport)

	if secure {
		log.Println("Serving via TLS")
		server := &http.Server{Addr: port, Handler: nil}

		if os.Getenv("DISABLE_HTTP2") == "" {
			http2.ConfigureServer(server, nil)
		}

		if err := server.ListenAndServeTLS(CertFilePath, KeyFilePath); err != nil {
			log.Fatalf("Error starting server: %s\n", err.Error())
		}
	} else {
		if err := http.ListenAndServe(port, nil); err != nil {
			log.Fatalf("Error starting server: %s\n", err.Error())
		}
	}
}

func getRegion() aws.Region {
	region := os.Getenv("AWS_REGION")
	aws_region, ok := aws.Regions[region]
	if ok {
		return aws_region
	} else {
		log.Printf(
			"\"%s\" is not a valid AWS_REGION parameter provided, defaulting to us-east-1",
			region)
		return aws.USEast
	}
}

func init() {
	flag.Parse()
	var err error
	hasKey := true
	hasCert := true
	_, err = os.Stat(KeyFilePath)
	if err != nil {
		log.Printf("No key found at %s\n", KeyFilePath)
		hasKey = false
	}

	_, err = os.Stat(CertFilePath)
	if err != nil {
		log.Printf("No certificate found at %s\n", CertFilePath)
		hasCert = false
	}

	secure = hasCert && hasKey
	Queue = q.New(100)

	r := mux.NewRouter()
	authToken = os.Getenv("AUTH_TOKEN")
	if authToken == "" {
		log.Println("No AUTH_TOKEN parameter provided, uploads are insecure")
	}

	allowedOrigin := os.Getenv("ALLOWED_ORIGIN")
	if allowedOrigin == "" {
		log.Println("No ALLOWED_ORIGIN set, CORS support is disabled.")
	} else {
		origins = strings.Split(allowedOrigin, ",")
	}

	limitSetting := os.Getenv("VIP_SIZE_LIMIT")
	if limitSetting == "" {
		limit = 5
	} else {
		limit, err = strconv.Atoi(limitSetting)
		if err != nil {
			limit = 5
		}
	}

	r.Handle("/upload/{bucket_id}", verifyAuth(handleUpload))
	r.HandleFunc("/{bucket_id}/{image_id}/warmup", handleWarmup)
	r.HandleFunc("/{bucket_id}/{image_id}", handleImageRequest)
	r.HandleFunc("/ping", handlePing)
	http.Handle("/", r)
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	awsAuth, err := aws.EnvAuth()
	if err != nil {
		log.Fatalf(err.Error())
	}

	s3conn := s3.New(awsAuth, getRegion())
	storage = store.NewS3Store(s3conn)

	peers = peer.DebugPool()

	peers.SetContext(func(r *http.Request) groupcache.Context {
		return fetch.RequestContext(r)
	})

	cache = groupcache.NewGroup("ImageProxyCache", 64<<20, groupcache.GetterFunc(
		func(c groupcache.Context, key string, dest groupcache.Sink) error {
			log.Printf("Cache MISS for key -> %s", key)
			// Get image data from S3
			b, err := fetch.ImageData(storage, c)
			if err != nil {
				return err
			}

			return dest.SetBytes(b)
		}))

	if !*verbose {
		logwriter, err := syslog.Dial("udp", "app_syslog:514", syslog.LOG_NOTICE, "vip")
		if err != nil {
			log.Println(err.Error())
			log.Println("using default logger")
		} else {
			log.SetOutput(logwriter)
		}
	}

	go peers.Listen()
	go listenHttp()
	go Queue.Start(4)
	log.Println("Cache listening on port :" + peers.Port())
	s := &http.Server{
		Addr:    ":" + peers.Port(),
		Handler: peers,
	}
	s.ListenAndServe()
}
<commit_msg>limit has to be int64<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"log/syslog"
	"net/http"
	"os"
	"runtime"
	"strconv"
	"strings"
	"vip/fetch"
	"vip/peer"
	"vip/q"
	"vip/store"

	"github.com/bradfitz/http2"
	"github.com/golang/groupcache"
	"github.com/gorilla/mux"
	"github.com/mitchellh/goamz/aws"
	"github.com/mitchellh/goamz/s3"
)

const (
	KeyFilePath  = "/etc/vip/application.key"
	CertFilePath = "/etc/vip/application.pem"
)

var (
	cache     *groupcache.Group
	peers     peer.CachePool
	storage   store.ImageStore
	authToken string
	origins   []string
	limit     int64
	verbose   *bool   = flag.Bool("verbose", false, "verbose logging")
	httpport  *string = flag.String("httpport", "8080", "target port")
	secure    bool    = false
	Queue     q.Queue
)

func listenHttp() {
	log.Printf("Listening on port :%s\n", *httpport)

	port := fmt.Sprintf(":%s", *httpport)

	if secure {
		log.Println("Serving via TLS")
		server := &http.Server{Addr: port, Handler: nil}

		if os.Getenv("DISABLE_HTTP2") == "" {
			http2.ConfigureServer(server, nil)
		}

		if err := server.ListenAndServeTLS(CertFilePath, KeyFilePath); err != nil {
			log.Fatalf("Error starting server: %s\n", err.Error())
		}
	} else {
		if err := http.ListenAndServe(port, nil); err != nil {
			log.Fatalf("Error starting server: %s\n", err.Error())
		}
	}
}

func getRegion() aws.Region {
	region := os.Getenv("AWS_REGION")
	aws_region, ok := aws.Regions[region]
	if ok {
		return aws_region
	} else {
		log.Printf(
			"\"%s\" is not a valid AWS_REGION parameter provided, defaulting to us-east-1",
			region)
		return aws.USEast
	}
}

func init() {
	flag.Parse()
	var err error
	hasKey := true
	hasCert := true
	_, err = os.Stat(KeyFilePath)
	if err != nil {
		log.Printf("No key found at %s\n", KeyFilePath)
		hasKey = false
	}

	_, err = os.Stat(CertFilePath)
	if err != nil {
		log.Printf("No certificate found at %s\n", CertFilePath)
		hasCert = false
	}

	secure = hasCert && hasKey
	Queue = q.New(100)

	authToken = os.Getenv("AUTH_TOKEN")
	if authToken == "" {
		log.Println("No AUTH_TOKEN parameter provided, uploads are insecure")
	}

	allowedOrigin := os.Getenv("ALLOWED_ORIGIN")
	if allowedOrigin == "" {
		log.Println("No ALLOWED_ORIGIN set, CORS support is disabled.")
	} else {
		origins = strings.Split(allowedOrigin, ",")
	}

	limitSetting := os.Getenv("VIP_SIZE_LIMIT")
	if limitSetting == "" {
		limit = 5
	} else {
		limit, err = strconv.ParseInt(limitSetting, 10, 64)
		if err != nil {
			limit = 5
		}
	}

	r := mux.NewRouter()
	r.Handle("/upload/{bucket_id}", verifyAuth(handleUpload))
	r.HandleFunc("/{bucket_id}/{image_id}/warmup", handleWarmup)
	r.HandleFunc("/{bucket_id}/{image_id}", handleImageRequest)
	r.HandleFunc("/ping", handlePing)
	http.Handle("/", r)
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	awsAuth, err := aws.EnvAuth()
	if err != nil {
		log.Fatalf(err.Error())
	}

	s3conn := s3.New(awsAuth, getRegion())
	storage = store.NewS3Store(s3conn)

	peers = peer.DebugPool()

	peers.SetContext(func(r *http.Request) groupcache.Context {
		return fetch.RequestContext(r)
	})

	cache = groupcache.NewGroup("ImageProxyCache", 64<<20, groupcache.GetterFunc(
		func(c groupcache.Context, key string, dest groupcache.Sink) error {
			log.Printf("Cache MISS for key -> %s", key)
			// Get image data from S3
			b, err := fetch.ImageData(storage, c)
			if err != nil {
				return err
			}

			return dest.SetBytes(b)
		}))

	if !*verbose {
		logwriter, err := syslog.Dial("udp", "app_syslog:514", syslog.LOG_NOTICE, "vip")
		if err != nil {
			log.Println(err.Error())
			log.Println("using default logger")
		} else {
			log.SetOutput(logwriter)
		}
	}

	go peers.Listen()
	go listenHttp()
	go Queue.Start(4)
	log.Println("Cache listening on port :" + peers.Port())
	s := &http.Server{
		Addr:    ":" + peers.Port(),
		Handler: peers,
	}
	s.ListenAndServe()
}
<|endoftext|>


<commit_before>package main

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

type Request struct {
	Income float64 `json:"income"`
}

type Response struct {
	Income float64 `json:"income"`
	Tax    float64 `json:"tax"`
}

type ErrorResponse struct {
	Reason string `json:"reason"`
}

func calculateIncomeTax(income float64) float64 {
	if income <= 11000 {
		return 0
	} else if income > 11000 && income <= 25000 {
		return ((income - 11000) * 5110) / 14000
	} else if income > 25000 && income <= 60000 {
		return 5110 + (((income - 25000) * 15125) / 35000)
	} else {
		return 20235 + (income-60000)*0.5
	}
}

type IncomeTaxHandler struct{}

func (t *IncomeTaxHandler) ServeHTTP(res http.ResponseWriter, req *http.Request) {
	var decoder = json.NewDecoder(req.Body)
	var encoder = json.NewEncoder(res)
	var requestJson = &Request{}
	var header = res.Header()
	header["Content-Type"] = []string{"application/json"}
	header["Access-Control-Allow-Origin"] = []string{"*"}

	if req.Method != "POST" {
		res.WriteHeader(http.StatusMethodNotAllowed)
		encoder.Encode(&ErrorResponse{Reason: "Wrong method"})
		return
	}

	if err := decoder.Decode(requestJson); err != nil {
		res.WriteHeader(http.StatusBadRequest)
		encoder.Encode(&ErrorResponse{Reason: "Could not parse JSON: " + err.Error()})
		return
	}

	income := requestJson.Income

	// Convert to 2 decimals precision and parse as float, so it's also
	// encoded as float in JSON
	tax, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", calculateIncomeTax(income)), 64)

	encoder.Encode(&Response{Tax: tax, Income: income})
}

func main() {
	http.Handle("/income-tax", &IncomeTaxHandler{})
	http.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) {
		fmt.Fprintln(res, "See https://github.com/CHH/at-tax for usage.")
	})

	if err := http.ListenAndServe(":"+os.Getenv("PORT"), nil); err != nil {
		log.Fatal(err)
	}
}
<commit_msg>Simpler error logging around http.ListenAndServe<commit_after>package main

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

type Request struct {
	Income float64 `json:"income"`
}

type Response struct {
	Income float64 `json:"income"`
	Tax    float64 `json:"tax"`
}

type ErrorResponse struct {
	Reason string `json:"reason"`
}

func calculateIncomeTax(income float64) float64 {
	if income <= 11000 {
		return 0
	} else if income > 11000 && income <= 25000 {
		return ((income - 11000) * 5110) / 14000
	} else if income > 25000 && income <= 60000 {
		return 5110 + (((income - 25000) * 15125) / 35000)
	} else {
		return 20235 + (income-60000)*0.5
	}
}

type IncomeTaxHandler struct{}

func (t *IncomeTaxHandler) ServeHTTP(res http.ResponseWriter, req *http.Request) {
	var decoder = json.NewDecoder(req.Body)
	var encoder = json.NewEncoder(res)
	var requestJson = &Request{}
	var header = res.Header()
	header["Content-Type"] = []string{"application/json"}
	header["Access-Control-Allow-Origin"] = []string{"*"}

	if req.Method != "POST" {
		res.WriteHeader(http.StatusMethodNotAllowed)
		encoder.Encode(&ErrorResponse{Reason: "Wrong method"})
		return
	}

	if err := decoder.Decode(requestJson); err != nil {
		res.WriteHeader(http.StatusBadRequest)
		encoder.Encode(&ErrorResponse{Reason: "Could not parse JSON: " + err.Error()})
		return
	}

	income := requestJson.Income

	// Convert to 2 decimals precision and parse as float, so it's also
	// encoded as float in JSON
	tax, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", calculateIncomeTax(income)), 64)

	encoder.Encode(&Response{Tax: tax, Income: income})
}

func main() {
	http.Handle("/income-tax", &IncomeTaxHandler{})
	http.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) {
		fmt.Fprintln(res, "See https://github.com/CHH/at-tax for usage.")
	})

	log.Println("Listening on :" + os.Getenv("PORT"))
	log.Fatal(http.ListenAndServe(":"+os.Getenv("PORT"), nil))
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strings"
	"sync"

	"github.com/PuerkitoBio/goquery"
	"github.com/vincent-petithory/dataurl"
)

const yuyuteiURL = "http://yuyu-tei.jp/"
const wsDeckUrl = "http://wsdecks.com/"

type Prox struct {
	// target url of reverse proxy
	target *url.URL
	// instance of Go ReverseProxy thatwill do the job for us
	proxy *httputil.ReverseProxy
}

func New(target string) *Prox {
	url, _ := url.Parse(target)
	// you should handle error on parsing
	return &Prox{target: url, proxy: httputil.NewSingleHostReverseProxy(url)}
}

func (p *Prox) handle(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("X-GoProxy", "GoProxy")
	// call to magic method from ReverseProxy object
	p.proxy.ServeHTTP(w, r)
}
func lowCostSystemToURL(syspath string) string {
	return strings.Replace(syspath, "\\", "/", -1)
}

func convertToJpg(filePath string) {
	// convert -density 150 -trim to_love-ru_darkness_2nd_trial_deck.pdf -quality 100 -sharpen 0x1.0 love.jpg
	cmd := exec.Command("convert", "-density", "150", "-trim", filePath, "-quality", "100", "-sharpen", "0x1.0", filePath+".jpg")
	err := cmd.Start()
	if err != nil {
		fmt.Println(err)
	}
	err = cmd.Wait()
}

func main() {
	proxy := New("http://localhost:8080")
	os.MkdirAll(filepath.Join("static", "yuyutei"), 0744)
	os.MkdirAll(filepath.Join("static", "wsdeck"), 0744)
	// static := http.FileServer(http.Dir("./"))
	http.HandleFunc("/", proxy.handle)

	http.HandleFunc("/translationimages", func(w http.ResponseWriter, r *http.Request) {
		file := r.PostFormValue("file")
		filename := r.PostFormValue("filename")
		uid := strings.Replace(filename, filepath.Ext(filename), "", 1)
		dir := filepath.Join("static", uid)
		filePath := filepath.Join(dir, filename)

		data, err := dataurl.DecodeString(file)
		if err != nil {
			fmt.Println(err)
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
		// fmt.Println(dataURL.Data)
		os.MkdirAll(dir, 0777)
		ioutil.WriteFile(filePath, data.Data, 0644)
		if _, err := os.Stat(dir); os.IsNotExist(err) {
			convertToJpg(filePath)
		}
		if err != nil {
			fmt.Println(err)
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
		listJpg, err := filepath.Glob(filePath + "*.jpg")
		if err != nil {
			fmt.Println(err)
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
		for i, jpgfile := range listJpg {
			listJpg[i] = lowCostSystemToURL(jpgfile)
		}

		b, err := json.Marshal(listJpg)

		if err != nil {
			fmt.Println(err)
			http.Error(w, err.Error(), 500)
			return
		}

		w.Write(b)
	})

	http.HandleFunc("/cardimages", func(w http.ResponseWriter, r *http.Request) {
		var wg sync.WaitGroup

		result := []string{}
		link := r.PostFormValue("url")
		classCSS := r.PostFormValue("class_css")
		filter := ""

		if classCSS == "" {
			classCSS = ".card_list_box"
		}

		if link != "" {
			doc, err := goquery.NewDocument(link)
			uid := ""
			site := ""
			imageURL := ""

			if strings.Contains(link, yuyuteiURL) {
				site = "yuyutei"
				filter = classCSS + " .image img"
				parsedURL, _ := url.Parse(link)
				values, _ := url.ParseQuery(parsedURL.RawQuery)
				uid = values.Get("ver")
			} else if strings.Contains(link, wsDeckUrl) {
				site = "wsdeck"
				filter = ".wscard" + " img"
				uid = filepath.Base(link)
			}
			// currentDir, _ := os.Getwd()
			dir := filepath.Join("static", site, uid)

			if filter == "" {
				http.Error(w, fmt.Sprintln("Url is not supported", link), 500)
			}

			if err != nil {
				fmt.Println("Nope")
			}
			if _, err := os.Stat(dir); os.IsNotExist(err) {
				os.MkdirAll(dir, 0744)
				doc.Find(filter).Each(func(i int, s *goquery.Selection) {
					wg.Add(1)
					val, _ := s.Attr("src")
					if site == "yuyutei" {
						big := strings.Replace(val, "90_126", "front", 1)
						imageURL = yuyuteiURL + big
					} else if site == "wsdeck" {
						imageURL = wsDeckUrl + val
					}

					go func(url string) {
						defer wg.Done()
						// fmt.Println("dir : ", dir)
						fileName := filepath.Join(dir, path.Base(url))
						out, err := os.Create(fileName)
						if err != nil {
							fmt.Println(err)
						}
						defer out.Close()
						reps, err := http.Get(url)

						if err != nil {
							fmt.Println(err)
						}

						file, err := io.Copy(out, reps.Body)
						if err != nil {
							fmt.Println(err)
						}

						fmt.Println("File", file)
						// fmt.Printf("Link: n-%d __ %v%v\n", i, imageURL, uid)
						defer reps.Body.Close()
						// fmt.Println("image url: ", strings.Replace(fileName, "\\", "/", 1))
						result = append(result, lowCostSystemToURL(fileName))
					}(imageURL)
				})
			} else {
				files, err := ioutil.ReadDir(dir)
				if err != nil {
					fmt.Println(err)
				}
				for _, file := range files {
					absPath := filepath.Join(dir, file.Name())
					urlPath := lowCostSystemToURL(absPath)
					result = append(result, urlPath)
				}

			}
		}

		wg.Wait()
		fmt.Printf("Finish")
		b, err := json.Marshal(result)

		if err != nil {
			http.Error(w, err.Error(), 500)
			return
		}
		w.Write(b)
	})

	http.HandleFunc("/static/", func(w http.ResponseWriter, r *http.Request) {
		// fmt.Println("static", r.URL.Path[1:])
		http.ServeFile(w, r, r.URL.Path[1:])
	})

	http.ListenAndServe(":8010", nil)
}
<commit_msg>Add ugly way to get card id from wsdeck<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strings"
	"sync"

	"github.com/PuerkitoBio/goquery"
	"github.com/vincent-petithory/dataurl"
)

const yuyuteiURL = "http://yuyu-tei.jp/"
const wsDeckUrl = "http://wsdecks.com/"
const hoTcURL = "http://www.heartofthecards.com/code/cardlist.html?card=WS_"

type Prox struct {
	// target url of reverse proxy
	target *url.URL
	// instance of Go ReverseProxy thatwill do the job for us
	proxy *httputil.ReverseProxy
}

func New(target string) *Prox {
	url, _ := url.Parse(target)
	// you should handle error on parsing
	return &Prox{target: url, proxy: httputil.NewSingleHostReverseProxy(url)}
}

func (p *Prox) handle(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("X-GoProxy", "GoProxy")
	// call to magic method from ReverseProxy object
	p.proxy.ServeHTTP(w, r)
}
func lowCostSystemToURL(syspath string) string {
	return strings.Replace(syspath, "\\", "/", -1)
}

func convertToJpg(filePath string) {
	// convert -density 150 -trim to_love-ru_darkness_2nd_trial_deck.pdf -quality 100 -sharpen 0x1.0 love.jpg
	cmd := exec.Command("convert", "-density", "150", "-trim", filePath, "-quality", "100", "-sharpen", "0x1.0", filePath+".jpg")
	err := cmd.Start()
	if err != nil {
		fmt.Println(err)
	}
	err = cmd.Wait()
}

func createCardsCodeFile(dirPath string) (string, error) {
	dirPath += "/"
	out, err := os.Create(dirPath + "codes.txt")
	defer out.Close()
	if err != nil {
		return "", err
	}
	cardList, err := filepath.Glob(dirPath + "*.gif")
	if err != nil {
		fmt.Println(err)
		return "", err
	}
	// PI/S40-056
	for _, card := range cardList {
		card = strings.Replace(card, dirPath, "", 1)
		card = strings.Replace(card, "_", "-", 1)
		card = strings.Replace(card, "_", "/", 1)
		ex := strings.Split(card, ".")[0]
		out.WriteString(ex + "\n")
	}
	return out.Name(), nil
}

func main() {
	proxy := New("http://localhost:8080")
	os.MkdirAll(filepath.Join("static", "yuyutei"), 0744)
	os.MkdirAll(filepath.Join("static", "wsdeck"), 0744)
	// static := http.FileServer(http.Dir("./"))
	http.HandleFunc("/", proxy.handle)

	http.HandleFunc("/translationimages", func(w http.ResponseWriter, r *http.Request) {
		file := r.PostFormValue("file")
		filename := r.PostFormValue("filename")
		uid := strings.Replace(filename, filepath.Ext(filename), "", 1)
		dir := filepath.Join("static", uid)
		filePath := filepath.Join(dir, filename)

		data, err := dataurl.DecodeString(file)
		if err != nil {
			fmt.Println(err)
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
		// fmt.Println(dataURL.Data)
		os.MkdirAll(dir, 0777)
		ioutil.WriteFile(filePath, data.Data, 0644)
		if _, err := os.Stat(dir); os.IsNotExist(err) {
			convertToJpg(filePath)
		}
		if err != nil {
			fmt.Println(err)
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
		listJpg, err := filepath.Glob(filePath + "*.jpg")
		if err != nil {
			fmt.Println(err)
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
		for i, jpgfile := range listJpg {
			listJpg[i] = lowCostSystemToURL(jpgfile)
		}

		b, err := json.Marshal(listJpg)

		if err != nil {
			fmt.Println(err)
			http.Error(w, err.Error(), 500)
			return
		}

		w.Write(b)
	})

	http.HandleFunc("/cardimages", func(w http.ResponseWriter, r *http.Request) {
		var wg sync.WaitGroup

		result := []string{}
		link := r.PostFormValue("url")
		classCSS := r.PostFormValue("class_css")
		filter := ""

		if classCSS == "" {
			classCSS = ".card_list_box"
		}

		if link != "" {
			doc, err := goquery.NewDocument(link)
			uid := ""
			site := ""
			imageURL := ""

			if strings.Contains(link, yuyuteiURL) {
				site = "yuyutei"
				filter = classCSS + " .image img"
				parsedURL, _ := url.Parse(link)
				values, _ := url.ParseQuery(parsedURL.RawQuery)
				uid = values.Get("ver")
			} else if strings.Contains(link, wsDeckUrl) {
				site = "wsdeck"
				filter = ".wscard" + " img"
				uid = filepath.Base(link)
			}
			// currentDir, _ := os.Getwd()
			dir := filepath.Join("static", site, uid)

			if filter == "" {
				http.Error(w, fmt.Sprintln("Url is not supported", link), 500)
			}

			if err != nil {
				fmt.Println("Nope")
			}
			if _, err := os.Stat(dir); os.IsNotExist(err) {
				os.MkdirAll(dir, 0744)
				doc.Find(filter).Each(func(i int, s *goquery.Selection) {
					wg.Add(1)
					val, _ := s.Attr("src")
					if site == "yuyutei" {
						big := strings.Replace(val, "90_126", "front", 1)
						imageURL = yuyuteiURL + big
					} else if site == "wsdeck" {
						imageURL = wsDeckUrl + val
					}

					go func(url string) {
						defer wg.Done()
						// fmt.Println("dir : ", dir)
						fileName := filepath.Join(dir, path.Base(url))
						out, err := os.Create(fileName)
						if err != nil {
							fmt.Println(err)
						}
						defer out.Close()
						reps, err := http.Get(url)

						if err != nil {
							fmt.Println(err)
						}

						file, err := io.Copy(out, reps.Body)
						if err != nil {
							fmt.Println(err)
						}

						fmt.Println("File", file)
						// fmt.Printf("Link: n-%d __ %v%v\n", i, imageURL, uid)
						defer reps.Body.Close()
						// fmt.Println("image url: ", strings.Replace(fileName, "\\", "/", 1))
						result = append(result, lowCostSystemToURL(fileName))
					}(imageURL)
				})
			} else {
				files, err := ioutil.ReadDir(dir)
				if err != nil {
					fmt.Println(err)
				}
				for _, file := range files {
					absPath := filepath.Join(dir, file.Name())
					urlPath := lowCostSystemToURL(absPath)
					result = append(result, urlPath)
				}

			}
			createCardsCodeFile(dir)
		}

		wg.Wait()
		fmt.Printf("Finish")
		b, err := json.Marshal(result)

		if err != nil {
			http.Error(w, err.Error(), 500)
			return
		}
		w.Write(b)
	})

	http.HandleFunc("/static/", func(w http.ResponseWriter, r *http.Request) {
		// fmt.Println("static", r.URL.Path[1:])
		http.ServeFile(w, r, r.URL.Path[1:])
	})

	http.ListenAndServe(":8010", nil)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/signal"
	"sync"

	"github.com/valyala/fasthttp"
)

const (
	ACSIP       = "127.0.0.1"
	ACSPort     = 9986
	BankerIP    = "127.0.0.1"
	BankerPort  = 9985
	BidderWin   = 7653
	BidderEvent = 7652
	BidderError = 7651
	BiddingPort = 7654
)

var bidderPort int
var wg sync.WaitGroup
var _agents []Agent

// http client to pace agents (note that it's pointer)
var client = &http.Client{}

func printPortConfigs() {
	log.Printf("Bidder port: %d", bidderPort)
	log.Printf("Win port: %d", BidderWin)
	log.Printf("Event port: %d", BidderEvent)
}

func setupHandlers(agents []Agent) {
	m := func(ctx *fasthttp.RequestCtx) {
		switch string(ctx.Path()) {
		case "/auctions":
			fastHandleAuctions(ctx, agents)
		default:
			ctx.Error("not found", fasthttp.StatusNotFound)
		}
	}

	go fasthttp.ListenAndServe(fmt.Sprintf(":%d", bidderPort), m)
	log.Println("Started Bid Mux")
}

func cleanup(agents []Agent) {
	stopRedisSubscriber()
	// Implement remove agent from ACS
	shutDownAgents(agents)
	fmt.Println("Leaving...")
	for {
		wg.Done()
	}
}

func startAgents(agents []Agent) {
	log.Printf("Starting Up %d Agents", len(agents))
	for _, agent := range agents {
		agent.RegisterAgent(client, ACSIP, ACSPort)
		agent.StartPacer(client, BankerIP, BankerPort)
	}
}

func shutDownAgents(agents []Agent) {
	log.Println("Shutting Down Agents")
	for _, agent := range agents {
		agent.UnregisterAgent(client, ACSIP, ACSPort)
	}
}

func main() {
	var agentsConfigFile = flag.String("config", "agents.json", "Configuration file in JSON.")
	flag.IntVar(&bidderPort, "port", BiddingPort, "Port to listen on for router")
	flag.Parse()

	if *agentsConfigFile == "" {
		log.Fatal("You should provide a configuration file.")
	}

	setupClient()
	go startRedisSubscriber()
	wg.Add(1)

	printPortConfigs()

	// load configuration
	_agents, err := LoadAgentsFromFile(*agentsConfigFile)

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

	startAgents(_agents)

	StartStatOutput()
	setupHandlers(_agents)

	go fasthttp.ListenAndServe(fmt.Sprintf(":%d", BidderEvent), eventMux)
	log.Println("Started event Mux")

	go fasthttp.ListenAndServe(fmt.Sprintf(":%d", BidderError), errorMux)
	log.Println("Started error Mux")

	go fasthttp.ListenAndServe(fmt.Sprintf(":%d", BidderWin), winMux)
	log.Println("Started Win Mux")

	wg.Add(3)

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)

	go func() {
		<-c
		cleanup(_agents)
		os.Exit(1)
	}()

	wg.Wait()
}
<commit_msg>Commenting out redis details<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/signal"
	"sync"

	"github.com/valyala/fasthttp"
)

const (
	ACSIP       = "127.0.0.1"
	ACSPort     = 9986
	BankerIP    = "127.0.0.1"
	BankerPort  = 9985
	BidderWin   = 7653
	BidderEvent = 7652
	BidderError = 7651
	BiddingPort = 7654
)

var bidderPort int
var wg sync.WaitGroup
var _agents []Agent

// http client to pace agents (note that it's pointer)
var client = &http.Client{}

func printPortConfigs() {
	log.Printf("Bidder port: %d", bidderPort)
	log.Printf("Win port: %d", BidderWin)
	log.Printf("Event port: %d", BidderEvent)
}

func setupHandlers(agents []Agent) {
	m := func(ctx *fasthttp.RequestCtx) {
		switch string(ctx.Path()) {
		case "/auctions":
			fastHandleAuctions(ctx, agents)
		default:
			ctx.Error("not found", fasthttp.StatusNotFound)
		}
	}

	go fasthttp.ListenAndServe(fmt.Sprintf(":%d", bidderPort), m)
	log.Println("Started Bid Mux")
}

func cleanup(agents []Agent) {
	// stopRedisSubscriber()
	// Implement remove agent from ACS
	shutDownAgents(agents)
	fmt.Println("Leaving...")
	for {
		wg.Done()
	}
}

func startAgents(agents []Agent) {
	log.Printf("Starting Up %d Agents", len(agents))
	for _, agent := range agents {
		agent.RegisterAgent(client, ACSIP, ACSPort)
		agent.StartPacer(client, BankerIP, BankerPort)
	}
}

func shutDownAgents(agents []Agent) {
	log.Println("Shutting Down Agents")
	for _, agent := range agents {
		agent.UnregisterAgent(client, ACSIP, ACSPort)
	}
}

func main() {
	var agentsConfigFile = flag.String("config", "agents.json", "Configuration file in JSON.")
	flag.IntVar(&bidderPort, "port", BiddingPort, "Port to listen on for router")
	flag.Parse()

	if *agentsConfigFile == "" {
		log.Fatal("You should provide a configuration file.")
	}

	// setupClient()
	// go startRedisSubscriber()
	// wg.Add(1)

	printPortConfigs()

	// load configuration
	_agents, err := LoadAgentsFromFile(*agentsConfigFile)

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

	startAgents(_agents)

	StartStatOutput()
	setupHandlers(_agents)

	go fasthttp.ListenAndServe(fmt.Sprintf(":%d", BidderEvent), eventMux)
	log.Println("Started event Mux")

	go fasthttp.ListenAndServe(fmt.Sprintf(":%d", BidderError), errorMux)
	log.Println("Started error Mux")

	go fasthttp.ListenAndServe(fmt.Sprintf(":%d", BidderWin), winMux)
	log.Println("Started Win Mux")

	wg.Add(3)

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)

	go func() {
		<-c
		cleanup(_agents)
		os.Exit(1)
	}()

	wg.Wait()
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path"
	"time"

	"github.com/cloudflare/cfssl/cli"
	"github.com/cloudflare/cfssl/cli/genkey"
	"github.com/cloudflare/cfssl/cli/sign"
	"github.com/cloudflare/cfssl/config"
	"github.com/cloudflare/cfssl/csr"
	"github.com/cloudflare/cfssl/signer"
)

type cfg struct {
	interval time.Duration
	perms    uint

	csrfile string
	cfgfile string

	certpath string
	certname string
}

var c = &cfg{}
var s = &cli.Config{}

func init() {
	flag.DurationVar(&c.interval, "interval", 0, "repeat interval")
	flag.UintVar(&c.perms, "perms", 0600, "permissions for resulting dirs/files")

	flag.StringVar(&c.csrfile, "csrfile", "", "path to csr json file")
	flag.StringVar(&c.cfgfile, "config", "", "path to file with auth info")

	flag.StringVar(&c.certpath, "certpath", "", "path of resulting cert and key")
	flag.StringVar(&c.certname, "certname", "", "name of resulting cert and key (${certname}.pem, ${certname}-key.pem)")

	flag.StringVar(&s.Hostname, "hostname", "", "hostname for the cert, comma separated")
	flag.StringVar(&s.Profile, "profile", "", "signing config profile")
	flag.StringVar(&s.Label, "label", "", "signing config label")
	flag.StringVar(&s.Remote, "remote", "", "remote cfssl server")
}

func main() {
	flag.Parse()

	if c.interval == 0 {
		log.Fatal("interval is required and must be > 0")
	}

	if len(c.csrfile) == 0 {
		log.Fatal("csrfile is required")
	}

	if len(c.certpath) == 0 {
		log.Fatal("path is required")
	}

	if len(c.certname) == 0 {
		log.Fatal("certname is required")
	}

	if len(s.Remote) == 0 {
		log.Fatal("remote is required")
	}

	log.Println("cfssl-sidecar")
	log.Printf("operating with interval %s", c.interval)

	if err := os.MkdirAll(c.certpath, os.FileMode(c.perms)); err != nil {
		log.Fatal(err)
	}

	if len(c.cfgfile) > 0 {
		loadedCfg, err := config.LoadFile(c.cfgfile)
		if err != nil {
			log.Fatal(err)
		}
		s.CFG = loadedCfg
	} else {
		log.Println("WARNING: no config file specified.")
	}

	log.Println("updating key and csr.")
	keypath, csrpath, err := createKey(c)
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("key(%s) and csr(%s) updated.", *keypath, *csrpath)

	s.CSRFile = *csrpath
	for {
		log.Println("updating certificate.")
		certpath, err := createCert(c, s)
		if err != nil {
			log.Fatal(err)
		}
		log.Printf("cert(%s) updated.", *certpath)

		log.Printf("sleeping for interval %s.", c.interval)
		time.Sleep(c.interval)
	}
}

func createKey(c *cfg) (*string, *string, error) {
	bytes, err := ioutil.ReadFile(c.csrfile)
	if err != nil {
		return nil, nil, err
	}

	req := csr.CertificateRequest{KeyRequest: csr.NewBasicKeyRequest()}
	if err := json.Unmarshal(bytes, &req); err != nil {
		return nil, nil, err
	}

	var keybytes, csrbytes []byte
	g := &csr.Generator{Validator: genkey.Validator}
	csrbytes, keybytes, err = g.ProcessRequest(&req)
	if err != nil {
		return nil, nil, err
	}

	keypath := path.Join(c.certpath, fmt.Sprintf("%s-key.pem", c.certname))
	csrpath := path.Join(c.certpath, fmt.Sprintf("%s.csr", c.certname))

	if err := ioutil.WriteFile(keypath, keybytes, 0600); err != nil {
		return nil, nil, err
	}

	if err := ioutil.WriteFile(csrpath, csrbytes, 0600); err != nil {
		return nil, nil, err
	}

	return &keypath, &csrpath, nil
}

func createCert(c *cfg, s *cli.Config) (*string, error) {
	signr, err := sign.SignerFromConfig(*s)
	if err != nil {
		return nil, err
	}

	csrbytes, err := ioutil.ReadFile(s.CSRFile)
	if err != nil {
		return nil, err
	}

	var cert []byte
	signReq := signer.SignRequest{
		Request: string(csrbytes),
		Hosts:   signer.SplitHosts(s.Hostname),
		Profile: s.Profile,
		Label:   s.Label,
	}

	cert, err = signr.Sign(signReq)
	if err != nil {
		return nil, err
	}

	certpath := path.Join(c.certpath, fmt.Sprintf("%s.pem", c.certname))
	if err := ioutil.WriteFile(certpath, cert, 0600); err != nil {
		return nil, err
	}

	return &certpath, nil
}
<commit_msg>detect key and csr that may be existing<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path"
	"time"

	"github.com/cloudflare/cfssl/cli"
	"github.com/cloudflare/cfssl/cli/genkey"
	"github.com/cloudflare/cfssl/cli/sign"
	"github.com/cloudflare/cfssl/config"
	"github.com/cloudflare/cfssl/csr"
	"github.com/cloudflare/cfssl/signer"
)

type cfg struct {
	interval time.Duration
	perms    uint

	csrfile string
	cfgfile string

	certpath string
	certname string
}

var c = &cfg{}
var s = &cli.Config{}

func init() {
	flag.DurationVar(&c.interval, "interval", 0, "repeat interval")
	flag.UintVar(&c.perms, "perms", 0600, "permissions for resulting dirs/files")

	flag.StringVar(&c.csrfile, "csrfile", "", "path to csr json file")
	flag.StringVar(&c.cfgfile, "config", "", "path to file with auth info")

	flag.StringVar(&c.certpath, "certpath", "", "path of resulting cert and key")
	flag.StringVar(&c.certname, "certname", "", "name of resulting cert and key (${certname}.pem, ${certname}-key.pem)")

	flag.StringVar(&s.Hostname, "hostname", "", "hostname for the cert, comma separated")
	flag.StringVar(&s.Profile, "profile", "", "signing config profile")
	flag.StringVar(&s.Label, "label", "", "signing config label")
	flag.StringVar(&s.Remote, "remote", "", "remote cfssl server")
}

func main() {
	flag.Parse()

	if c.interval == 0 {
		log.Fatal("interval is required and must be > 0")
	}

	if len(c.csrfile) == 0 {
		log.Fatal("csrfile is required")
	}

	if len(c.certpath) == 0 {
		log.Fatal("path is required")
	}

	if len(c.certname) == 0 {
		log.Fatal("certname is required")
	}

	if len(s.Remote) == 0 {
		log.Fatal("remote is required")
	}

	log.Println("cfssl-sidecar")
	log.Printf("operating with interval %s", c.interval)

	if err := os.MkdirAll(c.certpath, os.FileMode(c.perms)); err != nil {
		log.Fatal(err)
	}

	if len(c.cfgfile) > 0 {
		loadedCfg, err := config.LoadFile(c.cfgfile)
		if err != nil {
			log.Fatal(err)
		}
		s.CFG = loadedCfg
	} else {
		log.Println("WARNING: no config file specified.")
	}

	log.Println("updating key and csr.")
	keypath, csrpath, err := createKey(c)
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("key(%s) and csr(%s) updated.", *keypath, *csrpath)

	s.CSRFile = *csrpath
	for {
		log.Println("updating certificate.")
		certpath, err := createCert(c, s)
		if err != nil {
			log.Fatal(err)
		}
		log.Printf("cert(%s) updated.", *certpath)

		log.Printf("sleeping for interval %s.", c.interval)
		time.Sleep(c.interval)
	}
}

func createKey(c *cfg) (*string, *string, error) {
	keypath := path.Join(c.certpath, fmt.Sprintf("%s-key.pem", c.certname))
	csrpath := path.Join(c.certpath, fmt.Sprintf("%s.csr", c.certname))

	_, keyerr := os.Stat(keypath)
	_, csrerr := os.Stat(csrpath)

	if keyerr != nil && csrerr != nil {
		log.Println("key and csr already exist")
		return &keypath, &csrpath, nil
	}

	bytes, err := ioutil.ReadFile(c.csrfile)
	if err != nil {
		return nil, nil, err
	}

	req := csr.CertificateRequest{KeyRequest: csr.NewBasicKeyRequest()}
	if err := json.Unmarshal(bytes, &req); err != nil {
		return nil, nil, err
	}

	var keybytes, csrbytes []byte
	g := &csr.Generator{Validator: genkey.Validator}
	csrbytes, keybytes, err = g.ProcessRequest(&req)
	if err != nil {
		return nil, nil, err
	}

	if err := ioutil.WriteFile(keypath, keybytes, 0600); err != nil {
		return nil, nil, err
	}

	if err := ioutil.WriteFile(csrpath, csrbytes, 0600); err != nil {
		return nil, nil, err
	}

	return &keypath, &csrpath, nil
}

func createCert(c *cfg, s *cli.Config) (*string, error) {
	signr, err := sign.SignerFromConfig(*s)
	if err != nil {
		return nil, err
	}

	csrbytes, err := ioutil.ReadFile(s.CSRFile)
	if err != nil {
		return nil, err
	}

	var cert []byte
	signReq := signer.SignRequest{
		Request: string(csrbytes),
		Hosts:   signer.SplitHosts(s.Hostname),
		Profile: s.Profile,
		Label:   s.Label,
	}

	cert, err = signr.Sign(signReq)
	if err != nil {
		return nil, err
	}

	certpath := path.Join(c.certpath, fmt.Sprintf("%s.pem", c.certname))
	if err := ioutil.WriteFile(certpath, cert, 0600); err != nil {
		return nil, err
	}

	return &certpath, nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/gob"
	"errors"
	"flag"
	"fmt"
	"io"
	"net"
	"os"
	"os/exec"
	"os/signal"
	"runtime"
	"syscall"
	"unsafe"
)

var (
	modshell32         = syscall.NewLazyDLL("shell32.dll")
	procShellExecuteEx = modshell32.NewProc("ShellExecuteExW")
)

const (
	SEE_MASK_NOCLOSEPROCESS = 0x00000040
)

const (
	ERROR_BAD_FORMAT = 11
)

const (
	SE_ERR_FNF             = 2
	SE_ERR_PNF             = 3
	SE_ERR_ACCESSDENIED    = 5
	SE_ERR_OOM             = 8
	SE_ERR_DLLNOTFOUND     = 32
	SE_ERR_SHARE           = 26
	SE_ERR_ASSOCINCOMPLETE = 27
	SE_ERR_DDETIMEOUT      = 28
	SE_ERR_DDEFAIL         = 29
	SE_ERR_DDEBUSY         = 30
	SE_ERR_NOASSOC         = 31
)

type (
	DWORD     uint32
	HANDLE    uintptr
	HINSTANCE HANDLE
	HKEY      HANDLE
	HWND      HANDLE
	ULONG     uint32
	LPCTSTR   uintptr
	LPVOID    uintptr
)

type SHELLEXECUTEINFO struct {
	cbSize         DWORD
	fMask          ULONG
	hwnd           HWND
	lpVerb         LPCTSTR
	lpFile         LPCTSTR
	lpParameters   LPCTSTR
	lpDirectory    LPCTSTR
	nShow          int
	hInstApp       HINSTANCE
	lpIDList       LPVOID
	lpClass        LPCTSTR
	hkeyClass      HKEY
	dwHotKey       DWORD
	hIconOrMonitor HANDLE
	hProcess       HANDLE
}

func ShellExecuteAndWait(hwnd HWND, lpOperation, lpFile, lpParameters, lpDirectory string, nShowCmd int) error {
	var lpctstrVerb, lpctstrParameters, lpctstrDirectory LPCTSTR
	if len(lpOperation) != 0 {
		lpctstrVerb = LPCTSTR(unsafe.Pointer(syscall.StringToUTF16Ptr(lpOperation)))
	}
	if len(lpParameters) != 0 {
		lpctstrParameters = LPCTSTR(unsafe.Pointer(syscall.StringToUTF16Ptr(lpParameters)))
	}
	if len(lpDirectory) != 0 {
		lpctstrDirectory = LPCTSTR(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDirectory)))
	}
	i := &SHELLEXECUTEINFO{
		fMask:        SEE_MASK_NOCLOSEPROCESS,
		hwnd:         hwnd,
		lpVerb:       lpctstrVerb,
		lpFile:       LPCTSTR(unsafe.Pointer(syscall.StringToUTF16Ptr(lpFile))),
		lpParameters: lpctstrParameters,
		lpDirectory:  lpctstrDirectory,
		nShow:        nShowCmd,
	}
	i.cbSize = DWORD(unsafe.Sizeof(*i))
	return ShellExecuteEx(i)
}

func ShellExecuteEx(pExecInfo *SHELLEXECUTEINFO) error {
	ret, _, _ := procShellExecuteEx.Call(uintptr(unsafe.Pointer(pExecInfo)))
	if ret == 1 && pExecInfo.fMask&SEE_MASK_NOCLOSEPROCESS != 0 {
		s, e := syscall.WaitForSingleObject(syscall.Handle(pExecInfo.hProcess), syscall.INFINITE)
		switch s {
		case syscall.WAIT_OBJECT_0:
			break
		case syscall.WAIT_FAILED:
			return os.NewSyscallError("WaitForSingleObject", e)
		default:
			return errors.New("Unexpected result from WaitForSingleObject")
		}
	}
	errorMsg := ""
	if pExecInfo.hInstApp != 0 && pExecInfo.hInstApp <= 32 {
		switch int(pExecInfo.hInstApp) {
		case SE_ERR_FNF:
			errorMsg = "The specified file was not found"
		case SE_ERR_PNF:
			errorMsg = "The specified path was not found"
		case ERROR_BAD_FORMAT:
			errorMsg = "The .exe file is invalid (non-Win32 .exe or error in .exe image)"
		case SE_ERR_ACCESSDENIED:
			errorMsg = "The operating system denied access to the specified file"
		case SE_ERR_ASSOCINCOMPLETE:
			errorMsg = "The file name association is incomplete or invalid"
		case SE_ERR_DDEBUSY:
			errorMsg = "The DDE transaction could not be completed because other DDE transactions were being processed"
		case SE_ERR_DDEFAIL:
			errorMsg = "The DDE transaction failed"
		case SE_ERR_DDETIMEOUT:
			errorMsg = "The DDE transaction could not be completed because the request timed out"
		case SE_ERR_DLLNOTFOUND:
			errorMsg = "The specified DLL was not found"
		case SE_ERR_NOASSOC:
			errorMsg = "There is no application associated with the given file name extension"
		case SE_ERR_OOM:
			errorMsg = "There was not enough memory to complete the operation"
		case SE_ERR_SHARE:
			errorMsg = "A sharing violation occurred"
		default:
			errorMsg = fmt.Sprintf("Unknown error occurred with error code %v", pExecInfo.hInstApp)
		}
	} else {
		return nil
	}
	return errors.New(errorMsg)
}

type msg struct {
	Name string
	Exit int
	Data []byte
}

func msgWrite(enc *gob.Encoder, typ string) io.WriteCloser {
	r, w := io.Pipe()
	go func() {
		defer r.Close()
		var b [4096]byte
		for {
			n, err := r.Read(b[:])
			if err != nil {
				break
			}
			enc.Encode(&msg{Name: typ, Data: b[:n]})
		}
	}()
	return w
}

func client(addr string) int {
	// connect to server
	conn, err := net.Dial("tcp", addr)
	if err != nil {
		fmt.Fprintf(os.Stderr, "cannot find executable: %v\n", os.Args[0])
		return 1
	}
	defer conn.Close()
	enc, dec := gob.NewEncoder(conn), gob.NewDecoder(conn)

	cmd := exec.Command(flag.Arg(0), flag.Args()[1:]...)

	// stdin
	inw, err := cmd.StdinPipe()
	if err != nil {
		fmt.Fprintf(os.Stderr, "cannot find executable: %v\n", os.Args[0])
		return 1
	}
	defer inw.Close()

	// stdout
	outw := msgWrite(enc, "stdout")
	defer outw.Close()
	cmd.Stdout = outw

	// stderr
	errw := msgWrite(enc, "stderr")
	defer errw.Close()
	cmd.Stderr = errw

	go func() {
		defer inw.Close()
	in_loop:
		for {
			var m msg
			err = dec.Decode(&m)
			if err != nil {
				return
			}
			switch m.Name {
			case "close":
				break in_loop
			case "ctrlc":
				if runtime.GOOS == "windows" {
					// windows doesn't support os.Interrupt
					cmd.Process.Kill()
				} else {
					cmd.Process.Signal(os.Interrupt)
				}
			case "stdin":
				inw.Write(m.Data)
			}
		}
	}()

	err = cmd.Run()

	code := 1
	if err != nil {
		if status, ok := cmd.ProcessState.Sys().(syscall.WaitStatus); ok {
			code = status.ExitStatus()
		}
	} else {
		code = 0
	}

	enc.Encode(&msg{Name: "exit", Exit: code})
	return 0
}

func makeCmdLine(args []string) string {
	var s string
	for _, v := range args {
		if s != "" {
			s += " "
		}
		s += syscall.EscapeArg(v)
	}
	return s
}

func server() int {
	// make listner to communicate child process
	lis, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		fmt.Fprintf(os.Stderr, "cannot find executable: %v\n", os.Args[0])
		return 1
	}
	defer lis.Close()

	// make sure executable name to avoid detecting same executable name
	exe, err := os.Executable()
	if err != nil {
		fmt.Fprintf(os.Stderr, "cannot find executable: %v\n", os.Args[0])
		return 1
	}
	args := []string{"-mode", lis.Addr().String()}
	args = append(args, flag.Args()...)

	go func() {
		err = ShellExecuteAndWait(0, "runas", exe, makeCmdLine(args), "", syscall.SW_HIDE)
		if err != nil {
			lis.Close()
		}
	}()

	conn, err := lis.Accept()
	if err != nil {
		fmt.Fprintf(os.Stderr, "cannot execute command: %v\n", makeCmdLine(flag.Args()))
		return 1
	}
	defer conn.Close()

	enc, dec := gob.NewEncoder(conn), gob.NewDecoder(conn)

	sc := make(chan os.Signal, 1)
	signal.Notify(sc, os.Interrupt)
	go func() {
		for range sc {
			enc.Encode(&msg{Name: "ctrlc"})
		}
	}()
	defer close(sc)

	go func() {
		var b [256]byte
		for {
			n, err := os.Stdin.Read(b[:])
			if err != nil {
				// stdin was closed
				enc.Encode(&msg{Name: "close"})
				break
			}
			enc.Encode(&msg{Name: "stdin", Data: b[:n]})
		}
	}()

	for {
		var m msg
		err = dec.Decode(&m)
		if err != nil {
			fmt.Fprintf(os.Stderr, "cannot execute command: %v\n", makeCmdLine(flag.Args()))
			return 1
		}
		switch m.Name {
		case "stdout":
			syscall.Write(syscall.Stdout, m.Data)
		case "stderr":
			syscall.Write(syscall.Stderr, m.Data)
		case "exit":
			return m.Exit
		}
	}
	return 0
}

func main() {
	var mode string
	flag.StringVar(&mode, "mode", "", "mode")
	flag.Parse()
	if mode != "" {
		os.Exit(client(mode))
	}
	os.Exit(server())
}
<commit_msg>return error message<commit_after>package main

import (
	"encoding/gob"
	"errors"
	"flag"
	"fmt"
	"io"
	"net"
	"os"
	"os/exec"
	"os/signal"
	"runtime"
	"syscall"
	"unsafe"
)

var (
	modshell32         = syscall.NewLazyDLL("shell32.dll")
	procShellExecuteEx = modshell32.NewProc("ShellExecuteExW")
)

const (
	SEE_MASK_NOCLOSEPROCESS = 0x00000040
)

const (
	ERROR_BAD_FORMAT = 11
)

const (
	SE_ERR_FNF             = 2
	SE_ERR_PNF             = 3
	SE_ERR_ACCESSDENIED    = 5
	SE_ERR_OOM             = 8
	SE_ERR_DLLNOTFOUND     = 32
	SE_ERR_SHARE           = 26
	SE_ERR_ASSOCINCOMPLETE = 27
	SE_ERR_DDETIMEOUT      = 28
	SE_ERR_DDEFAIL         = 29
	SE_ERR_DDEBUSY         = 30
	SE_ERR_NOASSOC         = 31
)

type (
	DWORD     uint32
	HANDLE    uintptr
	HINSTANCE HANDLE
	HKEY      HANDLE
	HWND      HANDLE
	ULONG     uint32
	LPCTSTR   uintptr
	LPVOID    uintptr
)

type SHELLEXECUTEINFO struct {
	cbSize         DWORD
	fMask          ULONG
	hwnd           HWND
	lpVerb         LPCTSTR
	lpFile         LPCTSTR
	lpParameters   LPCTSTR
	lpDirectory    LPCTSTR
	nShow          int
	hInstApp       HINSTANCE
	lpIDList       LPVOID
	lpClass        LPCTSTR
	hkeyClass      HKEY
	dwHotKey       DWORD
	hIconOrMonitor HANDLE
	hProcess       HANDLE
}

func ShellExecuteAndWait(hwnd HWND, lpOperation, lpFile, lpParameters, lpDirectory string, nShowCmd int) error {
	var lpctstrVerb, lpctstrParameters, lpctstrDirectory LPCTSTR
	if len(lpOperation) != 0 {
		lpctstrVerb = LPCTSTR(unsafe.Pointer(syscall.StringToUTF16Ptr(lpOperation)))
	}
	if len(lpParameters) != 0 {
		lpctstrParameters = LPCTSTR(unsafe.Pointer(syscall.StringToUTF16Ptr(lpParameters)))
	}
	if len(lpDirectory) != 0 {
		lpctstrDirectory = LPCTSTR(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDirectory)))
	}
	i := &SHELLEXECUTEINFO{
		fMask:        SEE_MASK_NOCLOSEPROCESS,
		hwnd:         hwnd,
		lpVerb:       lpctstrVerb,
		lpFile:       LPCTSTR(unsafe.Pointer(syscall.StringToUTF16Ptr(lpFile))),
		lpParameters: lpctstrParameters,
		lpDirectory:  lpctstrDirectory,
		nShow:        nShowCmd,
	}
	i.cbSize = DWORD(unsafe.Sizeof(*i))
	return ShellExecuteEx(i)
}

func ShellExecuteEx(pExecInfo *SHELLEXECUTEINFO) error {
	ret, _, _ := procShellExecuteEx.Call(uintptr(unsafe.Pointer(pExecInfo)))
	if ret == 1 && pExecInfo.fMask&SEE_MASK_NOCLOSEPROCESS != 0 {
		s, e := syscall.WaitForSingleObject(syscall.Handle(pExecInfo.hProcess), syscall.INFINITE)
		switch s {
		case syscall.WAIT_OBJECT_0:
			break
		case syscall.WAIT_FAILED:
			return os.NewSyscallError("WaitForSingleObject", e)
		default:
			return errors.New("Unexpected result from WaitForSingleObject")
		}
	}
	errorMsg := ""
	if pExecInfo.hInstApp != 0 && pExecInfo.hInstApp <= 32 {
		switch int(pExecInfo.hInstApp) {
		case SE_ERR_FNF:
			errorMsg = "The specified file was not found"
		case SE_ERR_PNF:
			errorMsg = "The specified path was not found"
		case ERROR_BAD_FORMAT:
			errorMsg = "The .exe file is invalid (non-Win32 .exe or error in .exe image)"
		case SE_ERR_ACCESSDENIED:
			errorMsg = "The operating system denied access to the specified file"
		case SE_ERR_ASSOCINCOMPLETE:
			errorMsg = "The file name association is incomplete or invalid"
		case SE_ERR_DDEBUSY:
			errorMsg = "The DDE transaction could not be completed because other DDE transactions were being processed"
		case SE_ERR_DDEFAIL:
			errorMsg = "The DDE transaction failed"
		case SE_ERR_DDETIMEOUT:
			errorMsg = "The DDE transaction could not be completed because the request timed out"
		case SE_ERR_DLLNOTFOUND:
			errorMsg = "The specified DLL was not found"
		case SE_ERR_NOASSOC:
			errorMsg = "There is no application associated with the given file name extension"
		case SE_ERR_OOM:
			errorMsg = "There was not enough memory to complete the operation"
		case SE_ERR_SHARE:
			errorMsg = "A sharing violation occurred"
		default:
			errorMsg = fmt.Sprintf("Unknown error occurred with error code %v", pExecInfo.hInstApp)
		}
	} else {
		return nil
	}
	return errors.New(errorMsg)
}

type msg struct {
	Name  string
	Exit  int
	Error string
	Data  []byte
}

func msgWrite(enc *gob.Encoder, typ string) io.WriteCloser {
	r, w := io.Pipe()
	go func() {
		defer r.Close()
		var b [4096]byte
		for {
			n, err := r.Read(b[:])
			if err != nil {
				break
			}
			err = enc.Encode(&msg{Name: typ, Data: b[:n]})
			if err != nil {
				break
			}
		}
	}()
	return w
}

func client(addr string) int {
	// connect to server
	conn, err := net.Dial("tcp", addr)
	if err != nil {
		panic(err.Error())
	}
	defer conn.Close()

	enc, dec := gob.NewEncoder(conn), gob.NewDecoder(conn)

	cmd := exec.Command(flag.Arg(0), flag.Args()[1:]...)

	// stdin
	inw, err := cmd.StdinPipe()
	if err != nil {
		enc.Encode(&msg{Name: "error", Error: fmt.Sprintf("cannot execute command: %v\n", makeCmdLine(flag.Args()))})
		return 1
	}
	defer inw.Close()

	// stdout
	outw := msgWrite(enc, "stdout")
	defer outw.Close()
	cmd.Stdout = outw

	// stderr
	errw := msgWrite(enc, "stderr")
	defer errw.Close()
	cmd.Stderr = errw

	go func() {
		defer inw.Close()
	in_loop:
		for {
			var m msg
			err = dec.Decode(&m)
			if err != nil {
				return
			}
			switch m.Name {
			case "close":
				break in_loop
			case "ctrlc":
				if runtime.GOOS == "windows" {
					// windows doesn't support os.Interrupt
					cmd.Process.Kill()
				} else {
					cmd.Process.Signal(os.Interrupt)
				}
			case "stdin":
				inw.Write(m.Data)
			}
		}
	}()

	err = cmd.Run()

	code := 1
	if err != nil {
		if status, ok := cmd.ProcessState.Sys().(syscall.WaitStatus); ok {
			code = status.ExitStatus()
		}
	} else {
		code = 0
	}

	err = enc.Encode(&msg{Name: "exit", Exit: code})
	if err != nil {
		enc.Encode(&msg{Name: "error", Error: fmt.Sprintf("cannot detect exit code: %v\n", makeCmdLine(flag.Args()))})
		return 1
	}
	return 0
}

func makeCmdLine(args []string) string {
	var s string
	for _, v := range args {
		if s != "" {
			s += " "
		}
		s += syscall.EscapeArg(v)
	}
	return s
}

func server() int {
	// make listner to communicate child process
	lis, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		fmt.Fprintf(os.Stderr, "cannot find executable: %v\n", os.Args[0])
		return 1
	}
	defer lis.Close()

	// make sure executable name to avoid detecting same executable name
	exe, err := os.Executable()
	if err != nil {
		fmt.Fprintf(os.Stderr, "cannot find executable: %v\n", os.Args[0])
		return 1
	}
	args := []string{"-mode", lis.Addr().String()}
	args = append(args, flag.Args()...)

	go func() {
		err = ShellExecuteAndWait(0, "runas", exe, makeCmdLine(args), "", syscall.SW_HIDE)
		if err != nil {
			lis.Close()
		}
	}()

	conn, err := lis.Accept()
	if err != nil {
		fmt.Fprintf(os.Stderr, "cannot execute command: %v\n", makeCmdLine(flag.Args()))
		return 1
	}
	defer conn.Close()

	enc, dec := gob.NewEncoder(conn), gob.NewDecoder(conn)

	sc := make(chan os.Signal, 1)
	signal.Notify(sc, os.Interrupt)
	go func() {
		for range sc {
			enc.Encode(&msg{Name: "ctrlc"})
		}
	}()
	defer close(sc)

	go func() {
		var b [256]byte
		for {
			n, err := os.Stdin.Read(b[:])
			if err != nil {
				// stdin was closed
				enc.Encode(&msg{Name: "close"})
				break
			}
			err := enc.Encode(&msg{Name: "stdin", Data: b[:n]})
			if err != nil {
				break
			}
		}
	}()

	for {
		var m msg
		err = dec.Decode(&m)
		if err != nil {
			fmt.Fprintf(os.Stderr, "cannot execute command: %v\n", makeCmdLine(flag.Args()))
			return 1
		}
		switch m.Name {
		case "stdout":
			syscall.Write(syscall.Stdout, m.Data)
		case "stderr":
			syscall.Write(syscall.Stderr, m.Data)
		case "exit":
			return m.Exit
		}
	}
	return 0
}

func main() {
	var mode string
	flag.StringVar(&mode, "mode", "", "mode")
	flag.Parse()
	if mode != "" {
		os.Exit(client(mode))
	}
	os.Exit(server())
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/signal"
	"regexp"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/mackerelio/mackerel-agent/command"
	"github.com/mackerelio/mackerel-agent/config"
	"github.com/mackerelio/mackerel-agent/logging"
	"github.com/mackerelio/mackerel-agent/version"
)

// allow options like -role=... -role=...
type roleFullnamesFlag []string

var roleFullnamePattern = regexp.MustCompile(`^[\w-]+:\s*[\w-]+$`)

func (r *roleFullnamesFlag) String() string {
	return fmt.Sprint(*r)
}

func (r *roleFullnamesFlag) Set(input string) error {
	inputRoles := strings.Split(input, ",")

	for _, inputRole := range inputRoles {
		if roleFullnamePattern.MatchString(inputRole) == false {
			return fmt.Errorf("Bad format for role fullname (expecting <service>:<role>): %s", inputRole)
		}
	}

	*r = append(*r, inputRoles...)

	return nil
}

var logger = logging.GetLogger("main")

func main() {
	conf, printVersion := resolveConfig()

	if printVersion {
		fmt.Printf("mackerel-agent version %s (rev %s)\n", version.VERSION, version.GITCOMMIT)
		exitWithoutPidfileCleaning(0)
	}

	if conf.Verbose {
		logging.ConfigureLoggers("DEBUG")
	} else {
		logging.ConfigureLoggers("INFO")
	}

	logger.Infof("Starting mackerel-agent version:%s, rev:%s", version.VERSION, version.GITCOMMIT)

	if conf.Apikey == "" {
		logger.Criticalf("Apikey must be specified in the command-line flag or in the config file")
		exit(1, conf)
	}

	if err := start(conf); err != nil {
		exit(1, conf)
	}
}

// resolveConfig parses command line arguments and loads config file to
// return config.Config information.
// As a special case, if `-version` flag is given it stops processing
// and return true for the second return value.
func resolveConfig() (*config.Config, bool) {
	conf := &config.Config{}

	var (
		conffile     = flag.String("conf", config.DefaultConfig.Conffile, "Config file path (Configs in this file are over-written by command line options)")
		apibase      = flag.String("apibase", config.DefaultConfig.Apibase, "API base")
		pidfile      = flag.String("pidfile", config.DefaultConfig.Pidfile, "File containing PID")
		root         = flag.String("root", config.DefaultConfig.Root, "Directory containing variable state information")
		apikey       = flag.String("apikey", "", "API key from mackerel.io web site")
		printVersion = flag.Bool("version", false, "Prints version and exit")
	)

	var verbose bool
	flag.BoolVar(&verbose, "verbose", config.DefaultConfig.Verbose, "Toggle verbosity")
	flag.BoolVar(&verbose, "v", config.DefaultConfig.Verbose, "Toggle verbosity (shorthand)")

	// The value of "role" option is internally "roll fullname",
	// but we call it "role" here for ease.
	var roleFullnames roleFullnamesFlag
	flag.Var(&roleFullnames, "role", "Set this host's roles (format: <service>:<role>)")

	flag.Parse()

	if *printVersion {
		return nil, true
	}

	conf, confErr := config.LoadConfig(*conffile)
	if confErr != nil {
		logger.Criticalf("Failed to load the config file: %s", confErr)
		exitWithoutPidfileCleaning(1)
	}

	// overwrite config from file by config from args
	flag.Visit(func(f *flag.Flag) {
		switch f.Name {
		case "apibase":
			conf.Apibase = *apibase
		case "apikey":
			conf.Apikey = *apikey
		case "pidfile":
			conf.Pidfile = *pidfile
		case "root":
			conf.Root = *root
		case "verbose", "v":
			conf.Verbose = verbose
		case "role":
			conf.Roles = roleFullnames
		}
	})

	return conf, false
}

func createPidFile(pidfile string) error {
	if pidString, err := ioutil.ReadFile(pidfile); err == nil {
		if pid, err := strconv.Atoi(string(pidString)); err == nil {
			if _, err := os.Stat(fmt.Sprintf("/proc/%d/", pid)); err == nil {
				return fmt.Errorf("Pidfile found, try stopping another running mackerel-agent or delete %s", pidfile)
			}
			logger.Warningf("Pidfile found, but there seems no another process of mackerel-agent. Ignoring %s", pidfile)
		} else {
			logger.Warningf("Malformed pidfile found. Ignoring %s", pidfile)
		}
	}

	file, err := os.Create(pidfile)
	if err != nil {
		logger.Criticalf("Failed to create a pidfile: %s", err)
		return err
	}
	defer file.Close()

	_, err = fmt.Fprintf(file, "%d", os.Getpid())
	return err
}

func removePidFile(pidfile string) {
	if err := os.Remove(pidfile); err != nil {
		logger.Errorf("Failed to remove the pidfile: %s: %s", pidfile, err)
	}
}

func exit(exitCode int, conf *config.Config) {
	removePidFile(conf.Pidfile)
	exitWithoutPidfileCleaning(exitCode)
}

func exitWithoutPidfileCleaning(exitCode int) {
	os.Exit(exitCode)
}

const maxTerminatingInterval = 30

func start(conf *config.Config) error {
	if err := createPidFile(conf.Pidfile); err != nil {
		return err
	}

	api, host, err := command.Prepare(conf)
	if err != nil {
		logger.Criticalf(err.Error())
		exit(1, conf)
	}

	termCh := make(chan struct{})
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
	go func() {
		received := false
		for sig := range c {
			if sig == syscall.SIGHUP {
				logger.Debugf("Received signal '%v'", sig)
				// TODO reload configuration file

				command.UpdateHostSpecs(conf, api, host)
			} else {
				if !received {
					received = true
					logger.Infof(
						"Received signal '%v', try graceful shutdown up to %d seconds. If you want force shutdown immediately, send a signal again.",
						sig,
						maxTerminatingInterval)
				} else {
					logger.Infof("Received signal '%v' again, force shutdown.", sig)
				}
				termCh <- struct{}{}
				go func() {
					time.Sleep(maxTerminatingInterval * time.Second)
					logger.Infof("Timed out. force shutdown.")
					termCh <- struct{}{}
				}()
			}
		}
	}()

	exitCode := command.Run(conf, api, host, termCh)
	exit(exitCode, conf)

	return nil
}
<commit_msg>output GOOS GOARCH runtime.Version() when -version option is specified<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/signal"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/mackerelio/mackerel-agent/command"
	"github.com/mackerelio/mackerel-agent/config"
	"github.com/mackerelio/mackerel-agent/logging"
	"github.com/mackerelio/mackerel-agent/version"
)

// allow options like -role=... -role=...
type roleFullnamesFlag []string

var roleFullnamePattern = regexp.MustCompile(`^[\w-]+:\s*[\w-]+$`)

func (r *roleFullnamesFlag) String() string {
	return fmt.Sprint(*r)
}

func (r *roleFullnamesFlag) Set(input string) error {
	inputRoles := strings.Split(input, ",")

	for _, inputRole := range inputRoles {
		if roleFullnamePattern.MatchString(inputRole) == false {
			return fmt.Errorf("Bad format for role fullname (expecting <service>:<role>): %s", inputRole)
		}
	}

	*r = append(*r, inputRoles...)

	return nil
}

var logger = logging.GetLogger("main")

func main() {
	conf, printVersion := resolveConfig()

	if printVersion {
		fmt.Printf("mackerel-agent version %s (rev %s) [%s %s %s] \n",
			version.VERSION, version.GITCOMMIT, runtime.GOOS, runtime.GOARCH, runtime.Version())
		exitWithoutPidfileCleaning(0)
	}

	if conf.Verbose {
		logging.ConfigureLoggers("DEBUG")
	} else {
		logging.ConfigureLoggers("INFO")
	}

	logger.Infof("Starting mackerel-agent version:%s, rev:%s", version.VERSION, version.GITCOMMIT)

	if conf.Apikey == "" {
		logger.Criticalf("Apikey must be specified in the command-line flag or in the config file")
		exit(1, conf)
	}

	if err := start(conf); err != nil {
		exit(1, conf)
	}
}

// resolveConfig parses command line arguments and loads config file to
// return config.Config information.
// As a special case, if `-version` flag is given it stops processing
// and return true for the second return value.
func resolveConfig() (*config.Config, bool) {
	conf := &config.Config{}

	var (
		conffile     = flag.String("conf", config.DefaultConfig.Conffile, "Config file path (Configs in this file are over-written by command line options)")
		apibase      = flag.String("apibase", config.DefaultConfig.Apibase, "API base")
		pidfile      = flag.String("pidfile", config.DefaultConfig.Pidfile, "File containing PID")
		root         = flag.String("root", config.DefaultConfig.Root, "Directory containing variable state information")
		apikey       = flag.String("apikey", "", "API key from mackerel.io web site")
		printVersion = flag.Bool("version", false, "Prints version and exit")
	)

	var verbose bool
	flag.BoolVar(&verbose, "verbose", config.DefaultConfig.Verbose, "Toggle verbosity")
	flag.BoolVar(&verbose, "v", config.DefaultConfig.Verbose, "Toggle verbosity (shorthand)")

	// The value of "role" option is internally "roll fullname",
	// but we call it "role" here for ease.
	var roleFullnames roleFullnamesFlag
	flag.Var(&roleFullnames, "role", "Set this host's roles (format: <service>:<role>)")

	flag.Parse()

	if *printVersion {
		return nil, true
	}

	conf, confErr := config.LoadConfig(*conffile)
	if confErr != nil {
		logger.Criticalf("Failed to load the config file: %s", confErr)
		exitWithoutPidfileCleaning(1)
	}

	// overwrite config from file by config from args
	flag.Visit(func(f *flag.Flag) {
		switch f.Name {
		case "apibase":
			conf.Apibase = *apibase
		case "apikey":
			conf.Apikey = *apikey
		case "pidfile":
			conf.Pidfile = *pidfile
		case "root":
			conf.Root = *root
		case "verbose", "v":
			conf.Verbose = verbose
		case "role":
			conf.Roles = roleFullnames
		}
	})

	return conf, false
}

func createPidFile(pidfile string) error {
	if pidString, err := ioutil.ReadFile(pidfile); err == nil {
		if pid, err := strconv.Atoi(string(pidString)); err == nil {
			if _, err := os.Stat(fmt.Sprintf("/proc/%d/", pid)); err == nil {
				return fmt.Errorf("Pidfile found, try stopping another running mackerel-agent or delete %s", pidfile)
			}
			logger.Warningf("Pidfile found, but there seems no another process of mackerel-agent. Ignoring %s", pidfile)
		} else {
			logger.Warningf("Malformed pidfile found. Ignoring %s", pidfile)
		}
	}

	file, err := os.Create(pidfile)
	if err != nil {
		logger.Criticalf("Failed to create a pidfile: %s", err)
		return err
	}
	defer file.Close()

	_, err = fmt.Fprintf(file, "%d", os.Getpid())
	return err
}

func removePidFile(pidfile string) {
	if err := os.Remove(pidfile); err != nil {
		logger.Errorf("Failed to remove the pidfile: %s: %s", pidfile, err)
	}
}

func exit(exitCode int, conf *config.Config) {
	removePidFile(conf.Pidfile)
	exitWithoutPidfileCleaning(exitCode)
}

func exitWithoutPidfileCleaning(exitCode int) {
	os.Exit(exitCode)
}

const maxTerminatingInterval = 30

func start(conf *config.Config) error {
	if err := createPidFile(conf.Pidfile); err != nil {
		return err
	}

	api, host, err := command.Prepare(conf)
	if err != nil {
		logger.Criticalf(err.Error())
		exit(1, conf)
	}

	termCh := make(chan struct{})
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
	go func() {
		received := false
		for sig := range c {
			if sig == syscall.SIGHUP {
				logger.Debugf("Received signal '%v'", sig)
				// TODO reload configuration file

				command.UpdateHostSpecs(conf, api, host)
			} else {
				if !received {
					received = true
					logger.Infof(
						"Received signal '%v', try graceful shutdown up to %d seconds. If you want force shutdown immediately, send a signal again.",
						sig,
						maxTerminatingInterval)
				} else {
					logger.Infof("Received signal '%v' again, force shutdown.", sig)
				}
				termCh <- struct{}{}
				go func() {
					time.Sleep(maxTerminatingInterval * time.Second)
					logger.Infof("Timed out. force shutdown.")
					termCh <- struct{}{}
				}()
			}
		}
	}()

	exitCode := command.Run(conf, api, host, termCh)
	exit(exitCode, conf)

	return nil
}
<|endoftext|>


<commit_before><commit_msg>update default addr<commit_after><|endoftext|>


<commit_before>package main

import (
	"code.google.com/p/goncurses"
	"fmt"
	"math/rand"
	"os"
	"time"
)

func main() {
	stdscr, err := goncurses.Init()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	defer goncurses.End()
	rand.Seed(time.Now().Unix())

	board := NewBoard(20, 20, 50)
	board.Print(stdscr)

	for {
		board = board.Tick()
		board.Print(stdscr)
		stdscr.Refresh()
		if stdscr.GetChar() == 27 {
			goncurses.End()
			os.Exit(0)
		}
	}
}

type Board struct {
	grid      [][]rune
	w, h, pop int
}

func NewBoard(w, h, pop int) *Board {
	grid := make([][]rune, h)
	for i := range grid {
		grid[i] = make([]rune, w)
		for j := range grid[i] {
			grid[i][j] = ' '
		}
	}

	for i := 0; i < pop; i++ {
		x, y := rand.Intn(w), rand.Intn(h)
		if grid[y][x] == 'X' {
			i--
		} else {
			grid[y][x] = 'X'
		}
	}

	return &Board{grid, w, h, pop}
}

func (board *Board) Print(window *goncurses.Window) {
	for i := range board.grid {
		for j := range board.grid[i] {
			window.MovePrintf(i, j, "%c", board.grid[i][j])
		}
	}
}

func (board *Board) Tick() *Board {
	newBoard := NewBoard(board.w, board.h, 0)
	for i := range board.grid {
		for j := range board.grid[i] {
			adjacent := board.CountAdjacent(j, i)
			if (board.grid[i][j] == 'X' && (adjacent == 2 || adjacent == 3)) || (board.grid[i][j] == ' ' && adjacent == 3) {
				newBoard.grid[i][j] = 'X'
				newBoard.pop++
			}
		}
	}
	return newBoard
}

func (board *Board) CountAdjacent(x, y int) (count int) {
	count = 0
	if x-1 >= 0 && y-1 >= 0 && board.grid[y-1][x-1] == 'X' {
		count++
	}
	if y-1 >= 0 && board.grid[y-1][x] == 'X' {
		count++
	}
	if y-1 >= 0 && x+1 < board.w && board.grid[y-1][x+1] == 'X' {
		count++
	}
	if x+1 < board.w && board.grid[y][x+1] == 'X' {
		count++
	}
	if y+1 < board.h && x+1 < board.w && board.grid[y+1][x+1] == 'X' {
		count++
	}
	if y+1 < board.h && board.grid[y+1][x] == 'X' {
		count++
	}
	if y+1 < board.h && x-1 >= 0 && board.grid[y+1][x-1] == 'X' {
		count++
	}
	if x-1 >= 0 && board.grid[y][x-1] == 'X' {
		count++
	}
	return
}
<commit_msg>args and seeding work<commit_after>package main

import (
	"bytes"
	"code.google.com/p/goncurses"
	"crypto/md5"
	"encoding/binary"
	"flag"
	"fmt"
	"math/rand"
	"os"
	"time"
)

func main() {
	// con := flag.Bool("c", false, "Run continuously instead of pressing a key for each step")
	width := flag.Int("w", 20, "Width of the game board.")
	height := flag.Int("h", 20, "Height of the game board.")
	pop := flag.Int("p", 50, "The starting population of the game board.")
	// seed := flag.Int64("s", time.Now().Unix(), "The seed to generate the board with.")
	seed := flag.String("s", "", "The seed to generate the board with.")
	flag.Parse()

	stdscr, err := goncurses.Init()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	defer goncurses.End()

	if *seed != "" {
		rand.Seed(hash(*seed))
	} else {
		rand.Seed(time.Now().Unix())
	}

	board := NewBoard(*width, *height, *pop)
	board.Print(stdscr)

	for {
		board = board.Tick()
		board.Print(stdscr)
		stdscr.Refresh()
		if stdscr.GetChar() == 27 {
			goncurses.End()
			os.Exit(0)
		}
	}
}

func hash(s string) int64 {
	sum := md5.Sum([]byte(s))
	return bytes2int64(sum[:8]) ^ bytes2int64(sum[8:])
}

func bytes2int64(b []byte) (n int64) {
	buf := bytes.NewBuffer(b)
	binary.Read(buf, binary.LittleEndian, &n)
	return
}

type Board struct {
	grid      [][]rune
	w, h, pop int
}

func NewBoard(w, h, pop int) *Board {
	grid := make([][]rune, h)
	for i := range grid {
		grid[i] = make([]rune, w)
		for j := range grid[i] {
			grid[i][j] = ' '
		}
	}

	for i := 0; i < pop; i++ {
		x, y := rand.Intn(w), rand.Intn(h)
		if grid[y][x] == 'X' {
			i--
		} else {
			grid[y][x] = 'X'
		}
	}

	return &Board{grid, w, h, pop}
}

func (board *Board) Print(window *goncurses.Window) {
	for i := range board.grid {
		for j := range board.grid[i] {
			window.MovePrintf(i, j, "%c", board.grid[i][j])
		}
	}
}

func (board *Board) Tick() *Board {
	newBoard := NewBoard(board.w, board.h, 0)
	for i := range board.grid {
		for j := range board.grid[i] {
			adjacent := board.CountAdjacent(j, i)
			if (board.grid[i][j] == 'X' && (adjacent == 2 || adjacent == 3)) || (board.grid[i][j] == ' ' && adjacent == 3) {
				newBoard.grid[i][j] = 'X'
				newBoard.pop++
			}
		}
	}
	return newBoard
}

func (board *Board) CountAdjacent(x, y int) (count int) {
	count = 0
	if x-1 >= 0 && y-1 >= 0 && board.grid[y-1][x-1] == 'X' {
		count++
	}
	if y-1 >= 0 && board.grid[y-1][x] == 'X' {
		count++
	}
	if y-1 >= 0 && x+1 < board.w && board.grid[y-1][x+1] == 'X' {
		count++
	}
	if x+1 < board.w && board.grid[y][x+1] == 'X' {
		count++
	}
	if y+1 < board.h && x+1 < board.w && board.grid[y+1][x+1] == 'X' {
		count++
	}
	if y+1 < board.h && board.grid[y+1][x] == 'X' {
		count++
	}
	if y+1 < board.h && x-1 >= 0 && board.grid[y+1][x-1] == 'X' {
		count++
	}
	if x-1 >= 0 && board.grid[y][x-1] == 'X' {
		count++
	}
	return
}
<|endoftext|>


<commit_before>// Copyright 2016 tsuru 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 main

import (
	"bytes"
	"flag"
	"fmt"
	"go/ast"
	"go/parser"
	"go/printer"
	"regexp"
	"strings"

	"golang.org/x/tools/go/loader"
	"gopkg.in/yaml.v2"
)

var (
	searchFlag   = flag.String("search", "", "return handlers matching search regexp")
	noSearchFlag = flag.String("no-search", "", "return handlers NOT matching search regexp")
	methodFlag   = flag.String("method", "", "return handlers with method")
	noMethodFlag = flag.String("no-method", "", "return handlers EXCEPT with method")
)

func apiLoader() (*loader.Program, error) {
	var ldr loader.Config
	ldr.ParserMode = parser.ParseComments
	ldr.Import("github.com/tsuru/tsuru/api")
	ldr.Import("github.com/tsuru/tsuru/provision/docker")
	return ldr.Load()
}

func isHandler(object *ast.Object) bool {
	params := object.Decl.(*ast.FuncDecl).Type.Params.List
	if len(params) < 2 {
		return false
	}
	for _, param := range params {
		t, ok := param.Type.(*ast.SelectorExpr)
		if ok {
			if t.Sel.Name == "ResponseWriter" {
				return true
			}
		}
	}
	return false
}

func shouldBeIgnored(objectName string) bool {
	ignoreList := []string{
		"writeEnvVars", "fullHealthcheck", "setVersionHeadersMiddleware",
		"authTokenMiddleware", "runDelayedHandler", "errorHandlingMiddleware",
		"contextClearerMiddleware", "flushingWriterMiddleware", "setRequestIDHeaderMiddleware",
		"bsEnvSetHandler", "bsConfigGetHandler", "bsUpgradeHandler",
	}
	for _, name := range ignoreList {
		if name == objectName {
			return true
		}
	}
	return false
}

func parse(prog *loader.Program) error {
	files := []*ast.File{}
	for _, f := range prog.Imported["github.com/tsuru/tsuru/api"].Files {
		files = append(files, f)
	}
	for _, f := range prog.Imported["github.com/tsuru/tsuru/provision/docker"].Files {
		files = append(files, f)
	}
	for _, f := range files {
		for _, object := range f.Scope.Objects {
			if object.Kind == ast.Fun {
				ok := isHandler(object)
				if !ok {
					continue
				}
				if shouldBeIgnored(object.Name) {
					continue
				}
				commentGroup := object.Decl.(*ast.FuncDecl).Doc
				if commentGroup == nil {
					fmt.Printf("missing docs for %s\n", object.Name)
					continue
				}
				err := handleComments(prog, object, commentGroup)
				if err != nil {
					fmt.Printf("error handling comments for %s: %s\n", object.Name, err)
				}
			}
		}
	}
	return nil
}

func handleComments(prog *loader.Program, object *ast.Object, commentGroup *ast.CommentGroup) error {
	if *searchFlag == "" && *methodFlag == "" && *noSearchFlag == "" && *noMethodFlag == "" {
		for _, comment := range commentGroup.List {
			fmt.Println(comment.Text)
		}
		return nil
	}
	var buf bytes.Buffer
	for _, comment := range commentGroup.List {
		buf.WriteString(strings.Replace(comment.Text, "// ", "", -1))
		buf.WriteString("\n")
	}
	var parsed map[string]interface{}
	err := yaml.Unmarshal(buf.Bytes(), &parsed)
	if err != nil {
		return err
	}
	method, ok := parsed["method"].(string)
	if !ok {
		return fmt.Errorf("invalid method declaration for %s: %v", object.Name, parsed["method"])
	}
	if *methodFlag != "" {
		if strings.ToLower(*methodFlag) != strings.ToLower(method) {
			return nil
		}
	}
	if *noMethodFlag != "" {
		if strings.ToLower(*noMethodFlag) == strings.ToLower(method) {
			return nil
		}
	}
	if *searchFlag != "" || *noSearchFlag != "" {
		value := *searchFlag
		negate := true
		if value == "" {
			value = *noSearchFlag
			negate = false
		}
		var funcBuf bytes.Buffer
		printer.Fprint(&funcBuf, prog.Fset, object.Decl)
		re, err := regexp.Compile(value)
		if err != nil {
			return err
		}
		isMatch := re.Match(funcBuf.Bytes())
		if negate {
			isMatch = !isMatch
		}
		if isMatch {
			return nil
		}
	}
	fmt.Println(object.Name)
	return nil
}

func main() {
	flag.Parse()
	prog, err := apiLoader()
	if err != nil {
		fmt.Println("error loading code ", err)
		return
	}
	err = parse(prog)
	if err != nil {
		fmt.Println("error parsing api ", err)
		return
	}
}
<commit_msg>remove comment tokens from output<commit_after>// Copyright 2016 tsuru 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 main

import (
	"bytes"
	"flag"
	"fmt"
	"go/ast"
	"go/parser"
	"go/printer"
	"regexp"
	"strings"

	"golang.org/x/tools/go/loader"
	"gopkg.in/yaml.v2"
)

var (
	searchFlag   = flag.String("search", "", "return handlers matching search regexp")
	noSearchFlag = flag.String("no-search", "", "return handlers NOT matching search regexp")
	methodFlag   = flag.String("method", "", "return handlers with method")
	noMethodFlag = flag.String("no-method", "", "return handlers EXCEPT with method")
)

func apiLoader() (*loader.Program, error) {
	var ldr loader.Config
	ldr.ParserMode = parser.ParseComments
	ldr.Import("github.com/tsuru/tsuru/api")
	ldr.Import("github.com/tsuru/tsuru/provision/docker")
	return ldr.Load()
}

func isHandler(object *ast.Object) bool {
	params := object.Decl.(*ast.FuncDecl).Type.Params.List
	if len(params) < 2 {
		return false
	}
	for _, param := range params {
		t, ok := param.Type.(*ast.SelectorExpr)
		if ok {
			if t.Sel.Name == "ResponseWriter" {
				return true
			}
		}
	}
	return false
}

func shouldBeIgnored(objectName string) bool {
	ignoreList := []string{
		"writeEnvVars", "fullHealthcheck", "setVersionHeadersMiddleware",
		"authTokenMiddleware", "runDelayedHandler", "errorHandlingMiddleware",
		"contextClearerMiddleware", "flushingWriterMiddleware", "setRequestIDHeaderMiddleware",
		"bsEnvSetHandler", "bsConfigGetHandler", "bsUpgradeHandler",
	}
	for _, name := range ignoreList {
		if name == objectName {
			return true
		}
	}
	return false
}

func parse(prog *loader.Program) error {
	files := []*ast.File{}
	for _, f := range prog.Imported["github.com/tsuru/tsuru/api"].Files {
		files = append(files, f)
	}
	for _, f := range prog.Imported["github.com/tsuru/tsuru/provision/docker"].Files {
		files = append(files, f)
	}
	for _, f := range files {
		for _, object := range f.Scope.Objects {
			if object.Kind == ast.Fun {
				ok := isHandler(object)
				if !ok {
					continue
				}
				if shouldBeIgnored(object.Name) {
					continue
				}
				commentGroup := object.Decl.(*ast.FuncDecl).Doc
				if commentGroup == nil {
					fmt.Printf("missing docs for %s\n", object.Name)
					continue
				}
				err := handleComments(prog, object, commentGroup)
				if err != nil {
					fmt.Printf("error handling comments for %s: %s\n", object.Name, err)
				}
			}
		}
	}
	return nil
}

func handleComments(prog *loader.Program, object *ast.Object, commentGroup *ast.CommentGroup) error {
	if *searchFlag == "" && *methodFlag == "" && *noSearchFlag == "" && *noMethodFlag == "" {
		for _, comment := range commentGroup.List {
			fmt.Println(strings.Replace(comment.Text, "// ", "", -1))
		}
		return nil
	}
	var buf bytes.Buffer
	for _, comment := range commentGroup.List {
		buf.WriteString(strings.Replace(comment.Text, "// ", "", -1))
		buf.WriteString("\n")
	}
	var parsed map[string]interface{}
	err := yaml.Unmarshal(buf.Bytes(), &parsed)
	if err != nil {
		return err
	}
	method, ok := parsed["method"].(string)
	if !ok {
		return fmt.Errorf("invalid method declaration for %s: %v", object.Name, parsed["method"])
	}
	if *methodFlag != "" {
		if strings.ToLower(*methodFlag) != strings.ToLower(method) {
			return nil
		}
	}
	if *noMethodFlag != "" {
		if strings.ToLower(*noMethodFlag) == strings.ToLower(method) {
			return nil
		}
	}
	if *searchFlag != "" || *noSearchFlag != "" {
		value := *searchFlag
		negate := true
		if value == "" {
			value = *noSearchFlag
			negate = false
		}
		var funcBuf bytes.Buffer
		printer.Fprint(&funcBuf, prog.Fset, object.Decl)
		re, err := regexp.Compile(value)
		if err != nil {
			return err
		}
		isMatch := re.Match(funcBuf.Bytes())
		if negate {
			isMatch = !isMatch
		}
		if isMatch {
			return nil
		}
	}
	fmt.Println(object.Name)
	return nil
}

func main() {
	flag.Parse()
	prog, err := apiLoader()
	if err != nil {
		fmt.Println("error loading code ", err)
		return
	}
	err = parse(prog)
	if err != nil {
		fmt.Println("error parsing api ", err)
		return
	}
}
<|endoftext|>