<commit_before>// Copyright 2020 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 webv2

import (
	"context"
	"embed"
	"flag"
	"fmt"
	"os"
	"path"
	"path/filepath"

	"github.com/cloudspannerecosystem/harbourbridge/common/constants"
	"github.com/google/subcommands"
)

var FrontendDir embed.FS

type WebCmd struct {
	DistDir embed.FS
}

// Name returns the name of operation.
func (cmd *WebCmd) Name() string {
	return "web"
}

// Synopsis returns summary of operation.
func (cmd *WebCmd) Synopsis() string {
	return "run the web UI for HarbourBridge"
}

func (cmd *WebCmd) Usage() string {
	return fmt.Sprintf(`%v web`, path.Base(os.Args[0]))
}

func (cmd *WebCmd) SetFlags(f *flag.FlagSet) {
}

func (cmd *WebCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
	os.RemoveAll(filepath.Join(os.TempDir(), constants.HB_TMP_DIR))
	FrontendDir = cmd.DistDir
	App()
	return subcommands.ExitSuccess
}
<commit_msg>Fix: Initialise logger for harbourbridge web command (#392)<commit_after>// Copyright 2020 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 webv2

import (
	"context"
	"embed"
	"flag"
	"fmt"
	"os"
	"path"
	"path/filepath"

	"github.com/cloudspannerecosystem/harbourbridge/common/constants"
	"github.com/cloudspannerecosystem/harbourbridge/logger"
	"github.com/google/subcommands"
	"go.uber.org/zap"
)

var FrontendDir embed.FS

type WebCmd struct {
	DistDir 	embed.FS
	logLevel 	string
}

// Name returns the name of operation.
func (cmd *WebCmd) Name() string {
	return "web"
}

// Synopsis returns summary of operation.
func (cmd *WebCmd) Synopsis() string {
	return "run the web UI for HarbourBridge"
}

func (cmd *WebCmd) Usage() string {
	return fmt.Sprintf(`%v web`, path.Base(os.Args[0]))
}

func (cmd *WebCmd) SetFlags(f *flag.FlagSet) {
	f.StringVar(&cmd.logLevel, "log-level", "INFO", "Configure the logging level for the command (INFO, DEBUG), defaults to INFO")
}

func (cmd *WebCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
	os.RemoveAll(filepath.Join(os.TempDir(), constants.HB_TMP_DIR))
	FrontendDir = cmd.DistDir
	var err error
	defer func() {
		if err != nil {
			logger.Log.Fatal("FATAL error", zap.Error(err))
		}
	}()
	err = logger.InitializeLogger(cmd.logLevel)
	if err != nil {
		fmt.Println("Error initialising logger, did you specify a valid log-level? [DEBUG, INFO, WARN, ERROR, FATAL]", err)
		return subcommands.ExitFailure
	}
	defer logger.Log.Sync()
	App()
	return subcommands.ExitSuccess
}
<|endoftext|>


<commit_before>package swgohgg

import (
	"fmt"
	"net/http"

	"github.com/PuerkitoBio/goquery"
)

type Client struct {
	hc      *http.Client
	profile string
}

func NewClient(profile string) *Client {
	return &Client{
		hc:      http.DefaultClient,
		profile: profile,
	}
}

func (c *Client) Get(url string) (*goquery.Document, error) {
	resp, err := c.hc.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode == 404 {
		return nil, fmt.Errorf("swgohgg: unable to find collection for profile '%s'", c.profile)
	}
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("swgohgg: unexpected status code %d", resp.StatusCode)
	}
	return goquery.NewDocumentFromReader(resp.Body)
}

func (c *Client) UseHTTPClient(hc *http.Client) *Client {
	c.hc = hc
	return c
}

func (c *Client) Profile(profile string) *Client {
	c.profile = profile
	return c
}
<commit_msg>Added LRU caching for API calls.<commit_after>package swgohgg

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

	"github.com/PuerkitoBio/goquery"
	"github.com/hashicorp/golang-lru"
)

var globalCache, _ = lru.New(1024)

type Client struct {
	hc       *http.Client
	profile  string
	useCache bool
}

func NewClient(profile string) *Client {
	return &Client{
		hc:      http.DefaultClient,
		profile: profile,
	}
}

func (c *Client) Get(url string) (*goquery.Document, error) {
	b, ok := globalCache.Get(url)
	if ok && c.useCache {
		// Already on cache, use it!
		return goquery.NewDocumentFromReader(bytes.NewBuffer(b.([]byte)))
	}
	// Not in cache, fetch from remote site
	resp, err := c.hc.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode == 404 {
		return nil, fmt.Errorf("swgohgg: unable to find collection for profile '%s'", c.profile)
	}
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("swgohgg: unexpected status code %d", resp.StatusCode)
	}
	data, err := ioutil.ReadAll(resp.Body)
	if c.useCache {
		globalCache.Add(url, data)
	}
	return goquery.NewDocumentFromReader(bytes.NewBuffer(data))
}

func (c *Client) UseHTTPClient(hc *http.Client) *Client {
	c.hc = hc
	return c
}

func (c *Client) Profile(profile string) *Client {
	c.profile = profile
	return c
}

func (c *Client) UseCache(useCache bool) *Client {
	c.useCache = useCache
	return c
}

func FlushCache() {
	globalCache.Purge()
}
<|endoftext|>


<commit_before>package cache

import (
	"context"
	"os"

	. "github.com/polydawn/go-errcat"

	"go.polydawn.net/go-timeless-api"
	"go.polydawn.net/go-timeless-api/rio"
	cacheapi "go.polydawn.net/rio/cache"
	"go.polydawn.net/rio/fs"
	"go.polydawn.net/rio/fs/osfs"
	"go.polydawn.net/rio/fsOp"
	"go.polydawn.net/rio/lib/guid"
	"go.polydawn.net/rio/stitch/placer"
)

var ShelfFor = cacheapi.ShelfFor

func Lrn2Cache(cacheFs fs.FS, unpackTool rio.UnpackFunc) rio.UnpackFunc {
	return cache{cacheFs, unpackTool}.Unpack
}

type cache struct {
	fs         fs.FS
	unpackTool rio.UnpackFunc
}

/*
	Proxies most args to the cache's unpack tool, except for placementmode and path,
	which it sets to rio.Placement_Direct and a temporary path in the cache filesystem.
	If unpacking completes successfully, the temp path will be moved to a permanent
	location in the cache, which is specified by the public interface `rio/cache.GetShelf`.

	Any behaviors specified by the placementMode -- copying, mounting, etc -- are enacted
	by this func after the unpack finishes and the temp path committed to the cache.
*/
func (c cache) Unpack(
	ctx context.Context,
	wareID api.WareID,
	path string,
	filt api.FilesetFilters,
	placementMode rio.PlacementMode,
	warehouses []api.WarehouseAddr,
	monitor rio.Monitor,
) (api.WareID, error) {
	// Zeroth thing: caches are by hash, but remember that filters can give you a
	//  result hash which is different than the requested ware hash.
	//  Right now we deal with this simply/stupidly: if you used filters, no cache for you.
	resultWareID := wareID
	if isUnpackAltering(filt) {
		resultWareID = api.WareID{"-", "-"} // This value forces cache miss.
	}

	// First thing: Check if we already have the ware in cache and can jump to placement ASAP.
	//  (This must be first because we're willing to read cache even in "direct" mode, but
	//  yet *not* willing to even initialize empty cache dirs in that mode.)
	shelf := ShelfFor(resultWareID)
	_, err := c.fs.Stat(shelf)
	switch Category(err) {
	case fs.ErrNotExists: // "not exists" is just a cache miss...
		switch placementMode {
		case rio.Placement_Direct: // In direct mode: be direct.  Do nothing to cache.
			return c.unpackTool(ctx, wareID, path, filt, rio.Placement_Direct, warehouses, monitor)
		default: // Everyone else: unpack into cache.
			// pass
		}
		// Unpack into the cache.
		resultWareID, shelf, err = c.populate(ctx, wareID, filt, warehouses, monitor)
		if err != nil {
			return resultWareID, err
		}
		// Now that the cache has it, we can fallthrough into the "cache already had it" path.
		fallthrough
	case nil: // Cache has it!  Reaction varies.
		absShelf := c.fs.BasePath().Join(shelf)
		switch placementMode {
		case rio.Placement_None: // If no placement, cache having it is victory!
			return wareID, nil
		case rio.Placement_Direct: // In direct mode, copy.
			_, err := placer.CopyPlacer(absShelf, fs.MustAbsolutePath(path), true)
			return wareID, err
		case rio.Placement_Copy: // In copy mode, ... well obviously copy.
			_, err := placer.CopyPlacer(absShelf, fs.MustAbsolutePath(path), true)
			return wareID, err
		case rio.Placement_Mount: // In mount mode, mount.
			placerFn, err := placer.GetMountPlacer()
			if err != nil {
				return api.WareID{}, err
			}
			_, err = placerFn(absShelf, fs.MustAbsolutePath(path), true)
			return wareID, err
		default:
			panic("unreachable")
		}
	default:
		// Unknown errors reading cache are mostly considered game over.  Except:
		//  Since direct mode has no responsibility to the cache, it can still go.
		switch placementMode {
		case rio.Placement_Direct:
			return c.unpackTool(ctx, wareID, path, filt, rio.Placement_Direct, warehouses, monitor)
		default:
			return api.WareID{}, err
		}
	}
}

func (c cache) populate(
	ctx context.Context,
	wareID api.WareID,
	filt api.FilesetFilters,
	warehouses []api.WarehouseAddr,
	monitor rio.Monitor,
) (api.WareID, fs.RelPath, error) {
	// Initialize cache.
	//  Ensure the cache commit root dir exists.
	//  Also ensure the cache parent dir exists... no bound on recursion.
	if err := fsOp.MkdirAll(osfs.New(fs.AbsolutePath{}), c.fs.BasePath().CoerceRelative(), 0700); err != nil {
		return api.WareID{}, fs.RelPath{}, Errorf(rio.ErrLocalCacheProblem, "cannot initialize cache dirs: %s", err)
	}
	if err := fsOp.MkdirAll(c.fs, fs.MustRelPath(string(wareID.Type)+"/fileset"), 0700); err != nil {
		return api.WareID{}, fs.RelPath{}, Errorf(rio.ErrLocalCacheProblem, "cannot initialize cache dirs: %s", err)
	}

	// Pick a temp path to unpack into.
	tmpPath := fs.MustRelPath("./.tmp.unpack." + guid.New())
	tmpPathStr := c.fs.BasePath().Join(tmpPath).String()
	// Defer cleanup of the temp path.
	//  (If we're successful, we'll have moved it out of this path before return.)
	defer os.RemoveAll(tmpPathStr)
	// Delegate!
	resultWareID, err := c.unpackTool(ctx, wareID, tmpPathStr, filt, rio.Placement_Direct, warehouses, monitor)
	if err != nil {
		return resultWareID, fs.RelPath{}, err
	}

	// Successful unpack: commit it to its shelf location.
	//  This may also require mkdir'ing the prefix dirs of the shelf.
	//  In case of race: accept our fate, assume the racing party acted in good faith,
	//  return the shelf path anyway, and our defer'd rm will act on our wasted copy.
	shelf := ShelfFor(resultWareID)
	c.fs.Mkdir(shelf.Dir().Dir(), 0755)
	c.fs.Mkdir(shelf.Dir(), 0755)
	if err := os.Rename(tmpPathStr, c.fs.BasePath().Join(shelf).String()); err != nil {
		if _, ok := err.(*os.LinkError); ok && os.IsExist(err) {
			// Oh, fine.  Somebody raced us to it.
			return resultWareID, shelf, nil
		}
		// Any other error: sad.
		return resultWareID, shelf, Errorf(rio.ErrLocalCacheProblem, "error commiting %q into cache: %s", resultWareID, err)
	}
	return resultWareID, shelf, nil
}
<commit_msg>transmat/mixins/cache: fix error categorization leak.<commit_after>package cache

import (
	"context"
	"os"

	. "github.com/polydawn/go-errcat"

	"go.polydawn.net/go-timeless-api"
	"go.polydawn.net/go-timeless-api/rio"
	cacheapi "go.polydawn.net/rio/cache"
	"go.polydawn.net/rio/fs"
	"go.polydawn.net/rio/fs/osfs"
	"go.polydawn.net/rio/fsOp"
	"go.polydawn.net/rio/lib/guid"
	"go.polydawn.net/rio/stitch/placer"
)

var ShelfFor = cacheapi.ShelfFor

func Lrn2Cache(cacheFs fs.FS, unpackTool rio.UnpackFunc) rio.UnpackFunc {
	return cache{cacheFs, unpackTool}.Unpack
}

type cache struct {
	fs         fs.FS
	unpackTool rio.UnpackFunc
}

/*
	Proxies most args to the cache's unpack tool, except for placementmode and path,
	which it sets to rio.Placement_Direct and a temporary path in the cache filesystem.
	If unpacking completes successfully, the temp path will be moved to a permanent
	location in the cache, which is specified by the public interface `rio/cache.GetShelf`.

	Any behaviors specified by the placementMode -- copying, mounting, etc -- are enacted
	by this func after the unpack finishes and the temp path committed to the cache.
*/
func (c cache) Unpack(
	ctx context.Context,
	wareID api.WareID,
	path string,
	filt api.FilesetFilters,
	placementMode rio.PlacementMode,
	warehouses []api.WarehouseAddr,
	monitor rio.Monitor,
) (_ api.WareID, err error) {
	defer RequireErrorHasCategory(&err, rio.ErrorCategory(""))

	// Zeroth thing: caches are by hash, but remember that filters can give you a
	//  result hash which is different than the requested ware hash.
	//  Right now we deal with this simply/stupidly: if you used filters, no cache for you.
	resultWareID := wareID
	if isUnpackAltering(filt) {
		resultWareID = api.WareID{"-", "-"} // This value forces cache miss.
	}

	// First thing: Check if we already have the ware in cache and can jump to placement ASAP.
	//  (This must be first because we're willing to read cache even in "direct" mode, but
	//  yet *not* willing to even initialize empty cache dirs in that mode.)
	shelf := ShelfFor(resultWareID)
	_, err = c.fs.Stat(shelf)
	switch Category(err) {
	case fs.ErrNotExists: // "not exists" is just a cache miss...
		switch placementMode {
		case rio.Placement_Direct: // In direct mode: be direct.  Do nothing to cache.
			return c.unpackTool(ctx, wareID, path, filt, rio.Placement_Direct, warehouses, monitor)
		default: // Everyone else: unpack into cache.
			// pass
		}
		// Unpack into the cache.
		resultWareID, shelf, err = c.populate(ctx, wareID, filt, warehouses, monitor)
		if err != nil {
			return resultWareID, err
		}
		// Now that the cache has it, we can fallthrough into the "cache already had it" path.
		fallthrough
	case nil: // Cache has it!  Reaction varies.
		absShelf := c.fs.BasePath().Join(shelf)
		switch placementMode {
		case rio.Placement_None: // If no placement, cache having it is victory!
			return wareID, nil
		case rio.Placement_Direct: // In direct mode, copy.
			_, err := placer.CopyPlacer(absShelf, fs.MustAbsolutePath(path), true)
			return wareID, err
		case rio.Placement_Copy: // In copy mode, ... well obviously copy.
			_, err := placer.CopyPlacer(absShelf, fs.MustAbsolutePath(path), true)
			return wareID, err
		case rio.Placement_Mount: // In mount mode, mount.
			placerFn, err := placer.GetMountPlacer()
			if err != nil {
				return api.WareID{}, err
			}
			_, err = placerFn(absShelf, fs.MustAbsolutePath(path), true)
			return wareID, err
		default:
			panic("unreachable")
		}
	default:
		// Unknown errors reading cache are mostly considered game over.  Except:
		//  Since direct mode has no responsibility to the cache, it can still go.
		switch placementMode {
		case rio.Placement_Direct:
			return c.unpackTool(ctx, wareID, path, filt, rio.Placement_Direct, warehouses, monitor)
		default:
			return api.WareID{}, Errorf(rio.ErrLocalCacheProblem, "error reading cache: %s", err)
		}
	}
}

func (c cache) populate(
	ctx context.Context,
	wareID api.WareID,
	filt api.FilesetFilters,
	warehouses []api.WarehouseAddr,
	monitor rio.Monitor,
) (_ api.WareID, _ fs.RelPath, err error) {
	defer RequireErrorHasCategory(&err, rio.ErrorCategory(""))

	// Initialize cache.
	//  Ensure the cache commit root dir exists.
	//  Also ensure the cache parent dir exists... no bound on recursion.
	if err := fsOp.MkdirAll(osfs.New(fs.AbsolutePath{}), c.fs.BasePath().CoerceRelative(), 0700); err != nil {
		return api.WareID{}, fs.RelPath{}, Errorf(rio.ErrLocalCacheProblem, "cannot initialize cache dirs: %s", err)
	}
	if err := fsOp.MkdirAll(c.fs, fs.MustRelPath(string(wareID.Type)+"/fileset"), 0700); err != nil {
		return api.WareID{}, fs.RelPath{}, Errorf(rio.ErrLocalCacheProblem, "cannot initialize cache dirs: %s", err)
	}

	// Pick a temp path to unpack into.
	tmpPath := fs.MustRelPath("./.tmp.unpack." + guid.New())
	tmpPathStr := c.fs.BasePath().Join(tmpPath).String()
	// Defer cleanup of the temp path.
	//  (If we're successful, we'll have moved it out of this path before return.)
	defer os.RemoveAll(tmpPathStr)
	// Delegate!
	resultWareID, err := c.unpackTool(ctx, wareID, tmpPathStr, filt, rio.Placement_Direct, warehouses, monitor)
	if err != nil {
		return resultWareID, fs.RelPath{}, err
	}

	// Successful unpack: commit it to its shelf location.
	//  This may also require mkdir'ing the prefix dirs of the shelf.
	//  In case of race: accept our fate, assume the racing party acted in good faith,
	//  return the shelf path anyway, and our defer'd rm will act on our wasted copy.
	shelf := ShelfFor(resultWareID)
	c.fs.Mkdir(shelf.Dir().Dir(), 0755)
	c.fs.Mkdir(shelf.Dir(), 0755)
	if err := os.Rename(tmpPathStr, c.fs.BasePath().Join(shelf).String()); err != nil {
		if _, ok := err.(*os.LinkError); ok && os.IsExist(err) {
			// Oh, fine.  Somebody raced us to it.
			return resultWareID, shelf, nil
		}
		// Any other error: sad.
		return resultWareID, shelf, Errorf(rio.ErrLocalCacheProblem, "error commiting %q into cache: %s", resultWareID, err)
	}
	return resultWareID, shelf, nil
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/djthorpe/gopi/rpi/egl"
	"log"
)

func main() {
	egl.BCMHostInit()

	// Initalize display
	display := egl.GetDisplay()
	if err := egl.Initialize(display, nil, nil); err != nil {
		log.Fatalf("Unable to initalize display: %v", err)
	}

	// Choose configuration
	attr := []int32{
		egl.EGL_RED_SIZE, 8,
		egl.EGL_GREEN_SIZE, 8,
		egl.EGL_BLUE_SIZE, 8,
		egl.EGL_ALPHA_SIZE, 8,
		egl.EGL_SURFACE_TYPE, egl.EGL_WINDOW_BIT,
		egl.NONE,
	}

	var (
		config    egl.Config
		numConfig int32
	)

	if err := egl.ChooseConfig(display, attr, &config, 1, &numConfig); err != nil {
		log.Fatalf("Unable to initalize display: %v", err)
	}

	/*
		if ok := egl.GetConfigAttrib(display, config, egl.NATIVE_VISUAL_ID, &vid); !ok {
			egl.LogError(egl.GetError())
		}
		egl.BindAPI(egl.OPENGL_ES_API)
		context = egl.CreateContext(display, config, egl.NO_CONTEXT, &ctxAttr[0])

		screen_width, screen_height = egl.GraphicsGetDisplaySize(0)
		log.Printf("Display size W: %d H: %d\n", screen_width, screen_height)
	*/

	// Terminate display
	if err := egl.Terminate(display); err != nil {
		log.Fatalf("Unable to terminate display: %v", err)
	}
}
<commit_msg>Updated<commit_after>package main

import (
	"github.com/djthorpe/gopi/rpi/egl"
	"log"
)

func main() {
	egl.BCMHostInit()

	// Initalize display
	display := egl.GetDisplay()
	if err := egl.Initialize(display, nil, nil); err != nil {
		log.Fatalf("Unable to initalize display: %v", err)
	}

	// Choose configuration
	attr := []int32{
		egl.EGL_RED_SIZE, 8,
		egl.EGL_GREEN_SIZE, 8,
		egl.EGL_BLUE_SIZE, 8,
		egl.EGL_ALPHA_SIZE, 8,
		egl.EGL_SURFACE_TYPE, egl.EGL_WINDOW_BIT,
		egl.EGL_NONE,
	}

	var (
		config    egl.Config
		numConfig int32
	)

	if err := egl.ChooseConfig(display, attr, &config, 1, &numConfig); err != nil {
		log.Fatalf("Unable to initalize display: %v", err)
	}

	/*
		if ok := egl.GetConfigAttrib(display, config, egl.NATIVE_VISUAL_ID, &vid); !ok {
			egl.LogError(egl.GetError())
		}
		egl.BindAPI(egl.OPENGL_ES_API)
		context = egl.CreateContext(display, config, egl.NO_CONTEXT, &ctxAttr[0])

		screen_width, screen_height = egl.GraphicsGetDisplaySize(0)
		log.Printf("Display size W: %d H: %d\n", screen_width, screen_height)
	*/

	// Terminate display
	if err := egl.Terminate(display); err != nil {
		log.Fatalf("Unable to terminate display: %v", err)
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package wire

import (
	"fmt"
	"io"
)

const (
	// MaxInvPerMsg is the maximum number of inventory vectors that can be in a
	// single bitcoin inv message.
	MaxInvPerMsg = 50000

	// Maximum payload size for an inventory vector.
	maxInvVectPayload = 4 + HashSize
)

// InvType represents the allowed types of inventory vectors.  See InvVect.
type InvType uint32

// These constants define the various supported inventory vector types.
const (
	InvTypeError         InvType = 0
	InvTypeTx            InvType = 1
	InvTypeBlock         InvType = 2
	InvTypeFilteredBlock InvType = 3
)

// Map of service flags back to their constant names for pretty printing.
var ivStrings = map[InvType]string{
	InvTypeError:         "ERROR",
	InvTypeTx:            "MSG_TX",
	InvTypeBlock:         "MSG_BLOCK",
	InvTypeFilteredBlock: "MSG_FILTERED_BLOCK",
}

// String returns the InvType in human-readable form.
func (invtype InvType) String() string {
	if s, ok := ivStrings[invtype]; ok {
		return s
	}

	return fmt.Sprintf("Unknown InvType (%d)", uint32(invtype))
}

// InvVect defines a bitcoin inventory vector which is used to describe data,
// as specified by the Type field, that a peer wants, has, or does not have to
// another peer.
type InvVect struct {
	Type InvType // Type of data
	Hash ShaHash // Hash of the data
}

// NewInvVect returns a new InvVect using the provided type and hash.
func NewInvVect(typ InvType, hash *ShaHash) *InvVect {
	return &InvVect{
		Type: typ,
		Hash: *hash,
	}
}

// readInvVect reads an encoded InvVect from r depending on the protocol
// version.
func readInvVect(r io.Reader, pver uint32, iv *InvVect) error {
	err := readElements(r, &iv.Type, &iv.Hash)
	if err != nil {
		return err
	}
	return nil
}

// writeInvVect serializes an InvVect to w depending on the protocol version.
func writeInvVect(w io.Writer, pver uint32, iv *InvVect) error {
	err := writeElements(w, iv.Type, &iv.Hash)
	if err != nil {
		return err
	}
	return nil
}
<commit_msg>wire: add new witness enabled inventory types<commit_after>// Copyright (c) 2013-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package wire

import (
	"fmt"
	"io"
)

const (
	// MaxInvPerMsg is the maximum number of inventory vectors that can be in a
	// single bitcoin inv message.
	MaxInvPerMsg = 50000

	// Maximum payload size for an inventory vector.
	maxInvVectPayload = 4 + HashSize

	// InvWitnessFlag denotes that the inventory vector type is requesting,
	// or sending a version which includes witness data.
	InvWitnessFlag = 1 << 30
)

// InvType represents the allowed types of inventory vectors.  See InvVect.
type InvType uint32

// These constants define the various supported inventory vector types.
const (
	InvTypeError                InvType = 0
	InvTypeTx                   InvType = 1
	InvTypeBlock                InvType = 2
	InvTypeFilteredBlock        InvType = 3
	InvTypeWitnessBlock         InvType = InvTypeBlock | InvWitnessFlag
	InvTypeWitnessTx            InvType = InvTypeTx | InvWitnessFlag
	InvTypeFilteredWitnessBlock InvType = InvTypeFilteredBlock | InvWitnessFlag
)

// Map of service flags back to their constant names for pretty printing.
var ivStrings = map[InvType]string{
	InvTypeError:                "ERROR",
	InvTypeTx:                   "MSG_TX",
	InvTypeBlock:                "MSG_BLOCK",
	InvTypeFilteredBlock:        "MSG_FILTERED_BLOCK",
	InvTypeWitnessBlock:         "MSG_WITNESS_BLOCK",
	InvTypeWitnessTx:            "MSG_WITNESS_TX",
	InvTypeFilteredWitnessBlock: "MSG_FILTERED_WITNESS_BLOCK",
}

// String returns the InvType in human-readable form.
func (invtype InvType) String() string {
	if s, ok := ivStrings[invtype]; ok {
		return s
	}

	return fmt.Sprintf("Unknown InvType (%d)", uint32(invtype))
}

// InvVect defines a bitcoin inventory vector which is used to describe data,
// as specified by the Type field, that a peer wants, has, or does not have to
// another peer.
type InvVect struct {
	Type InvType // Type of data
	Hash ShaHash // Hash of the data
}

// NewInvVect returns a new InvVect using the provided type and hash.
func NewInvVect(typ InvType, hash *ShaHash) *InvVect {
	return &InvVect{
		Type: typ,
		Hash: *hash,
	}
}

// readInvVect reads an encoded InvVect from r depending on the protocol
// version.
func readInvVect(r io.Reader, pver uint32, iv *InvVect) error {
	err := readElements(r, &iv.Type, &iv.Hash)
	if err != nil {
		return err
	}
	return nil
}

// writeInvVect serializes an InvVect to w depending on the protocol version.
func writeInvVect(w io.Writer, pver uint32, iv *InvVect) error {
	err := writeElements(w, iv.Type, &iv.Hash)
	if err != nil {
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"strconv"
	"path"

	"github.com/gorilla/mux"
	"github.com/lxc/lxd/shared"
	"gopkg.in/lxc/go-lxc.v2"
)

const (
	SYS_CLASS_NET = "/sys/class/net"
)

func networksGet(d *Daemon, r *http.Request) Response {
	recursion_str := r.FormValue("recursion")
	recursion, err := strconv.Atoi(recursion_str)
	if err != nil {
		recursion = 0
	}

	ifs, err := net.Interfaces()
	if err != nil {
		return InternalError(err)
	}

	result_string := make([]string, 0)
	result_map := make([]network, 0)
//	var result []string
	for _, iface := range ifs {
		if (recursion == 0) {
			result_string = append(result_string, fmt.Sprintf("/%s/networks/%s", shared.APIVersion, iface.Name))
		} else {
			net, err := doNetworkGet(d, iface.Name)
			if err != nil {
				continue
			}
			result_map = append(result_map, net)

		}
	}

	if recursion == 0 {
		return SyncResponse(true, result_string)
	} else {
		return SyncResponse(true, result_map)
	}
}

var networksCmd = Command{name: "networks", get: networksGet}

type network struct {
	Name    string   `json:"name"`
	Type    string   `json:"type"`
	Members []string `json:"members"`
}

func isBridge(iface string) bool {
	p := path.Join(SYS_CLASS_NET, iface, "bridge")
	stat, err := os.Stat(p)
	if err != nil {
		return false
	}

	return stat.IsDir()
}

func children(iface string) []string {
	p := path.Join(SYS_CLASS_NET, iface, "brif")

	var ret []string

	ents, err := ioutil.ReadDir(p)
	if err != nil {
		return ret
	}

	for _, ent := range ents {
		ret = append(ret, ent.Name())
	}

	return ret
}

func isOnBridge(c *lxc.Container, bridge string) bool {
	kids := children(bridge)
	for i := 0; i < len(c.ConfigItem("lxc.network")); i++ {
		interfaceType := c.RunningConfigItem(fmt.Sprintf("lxc.network.%d.type", i))
		if interfaceType[0] == "veth" {
			cif := c.RunningConfigItem(fmt.Sprintf("lxc.network.%d.veth.pair", i))[0]
			for _, kif := range kids {
				if cif == kif {
					return true
				}

			}
		}
	}
	return false
}

func networkGet(d *Daemon, r *http.Request) Response {
	name := mux.Vars(r)["name"]

	n, err := doNetworkGet(d, name)
	if err != nil {
		return InternalError(err)
	}

	return SyncResponse(true, &n)
}

func doNetworkGet(d *Daemon, name string) (network, error) {
	iface, err := net.InterfaceByName(name)
	if err != nil {
		return network{}, err
	}

	n := network{}
	n.Name = iface.Name
	n.Members = make([]string, 0)

	if int(iface.Flags&net.FlagLoopback) > 0 {
		n.Type = "loopback"
	} else if isBridge(n.Name) {
		n.Type = "bridge"
		for _, ct := range lxc.ActiveContainerNames(d.lxcpath) {
			c, err := newLxdContainer(ct, d)
			if err != nil {
				return network{}, err
			}

			if isOnBridge(c.c, n.Name) {
				n.Members = append(n.Members, ct)
			}
		}
	} else {
		n.Type = "unknown"
	}

	return n, nil
}

var networkCmd = Command{name: "networks/{name}", get: networkGet}
<commit_msg>gofmt<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"path"
	"strconv"

	"github.com/gorilla/mux"
	"github.com/lxc/lxd/shared"
	"gopkg.in/lxc/go-lxc.v2"
)

const (
	SYS_CLASS_NET = "/sys/class/net"
)

func networksGet(d *Daemon, r *http.Request) Response {
	recursion_str := r.FormValue("recursion")
	recursion, err := strconv.Atoi(recursion_str)
	if err != nil {
		recursion = 0
	}

	ifs, err := net.Interfaces()
	if err != nil {
		return InternalError(err)
	}

	result_string := make([]string, 0)
	result_map := make([]network, 0)
	for _, iface := range ifs {
		if recursion == 0 {
			result_string = append(result_string, fmt.Sprintf("/%s/networks/%s", shared.APIVersion, iface.Name))
		} else {
			net, err := doNetworkGet(d, iface.Name)
			if err != nil {
				continue
			}
			result_map = append(result_map, net)

		}
	}

	if recursion == 0 {
		return SyncResponse(true, result_string)
	} else {
		return SyncResponse(true, result_map)
	}
}

var networksCmd = Command{name: "networks", get: networksGet}

type network struct {
	Name    string   `json:"name"`
	Type    string   `json:"type"`
	Members []string `json:"members"`
}

func isBridge(iface string) bool {
	p := path.Join(SYS_CLASS_NET, iface, "bridge")
	stat, err := os.Stat(p)
	if err != nil {
		return false
	}

	return stat.IsDir()
}

func children(iface string) []string {
	p := path.Join(SYS_CLASS_NET, iface, "brif")

	var ret []string

	ents, err := ioutil.ReadDir(p)
	if err != nil {
		return ret
	}

	for _, ent := range ents {
		ret = append(ret, ent.Name())
	}

	return ret
}

func isOnBridge(c *lxc.Container, bridge string) bool {
	kids := children(bridge)
	for i := 0; i < len(c.ConfigItem("lxc.network")); i++ {
		interfaceType := c.RunningConfigItem(fmt.Sprintf("lxc.network.%d.type", i))
		if interfaceType[0] == "veth" {
			cif := c.RunningConfigItem(fmt.Sprintf("lxc.network.%d.veth.pair", i))[0]
			for _, kif := range kids {
				if cif == kif {
					return true
				}

			}
		}
	}
	return false
}

func networkGet(d *Daemon, r *http.Request) Response {
	name := mux.Vars(r)["name"]

	n, err := doNetworkGet(d, name)
	if err != nil {
		return InternalError(err)
	}

	return SyncResponse(true, &n)
}

func doNetworkGet(d *Daemon, name string) (network, error) {
	iface, err := net.InterfaceByName(name)
	if err != nil {
		return network{}, err
	}

	n := network{}
	n.Name = iface.Name
	n.Members = make([]string, 0)

	if int(iface.Flags&net.FlagLoopback) > 0 {
		n.Type = "loopback"
	} else if isBridge(n.Name) {
		n.Type = "bridge"
		for _, ct := range lxc.ActiveContainerNames(d.lxcpath) {
			c, err := newLxdContainer(ct, d)
			if err != nil {
				return network{}, err
			}

			if isOnBridge(c.c, n.Name) {
				n.Members = append(n.Members, ct)
			}
		}
	} else {
		n.Type = "unknown"
	}

	return n, nil
}

var networkCmd = Command{name: "networks/{name}", get: networkGet}
<|endoftext|>


<commit_before>package writerseeker

import (
	"bytes"
	"errors"
	"io"
)

// WriterSeeker is an in-memory io.WriteSeeker implementation
type WriterSeeker struct {
	buf []byte
	pos int
}

// Write writes to the buffer of this WriterSeeker instance
func (ws *WriterSeeker) Write(p []byte) (n int, err error) {
	minCap := ws.pos + len(p)
	if minCap > cap(ws.buf) { // Make sure buf has enough capacity:
		buf2 := make([]byte, len(ws.buf), minCap+len(p)) // add some extra
		copy(buf2, ws.buf)
		ws.buf = buf2
	}
	if minCap > len(ws.buf) {
		ws.buf = ws.buf[:minCap]
	}
	copy(ws.buf[ws.pos:], p)
	ws.pos += len(p)
	return len(p), nil
}

// Seek seeks in the buffer of this WriterSeeker instance
func (ws *WriterSeeker) Seek(offset int64, whence int) (int64, error) {
	newPos, offs := 0, int(offset)
	switch whence {
	case io.SeekStart:
		newPos = offs
	case io.SeekCurrent:
		newPos = ws.pos + offs
	case io.SeekEnd:
		newPos = len(ws.buf) + offs
	}
	if newPos < 0 {
		return 0, errors.New("negative result pos")
	}
	ws.pos = newPos
	return int64(newPos), nil
}

// Reader returns an io.Reader. Use it, for example, with io.Copy, to copy the content of the WriterSeeker buffer to an io.Writer
func (ws *WriterSeeker) Reader() io.Reader {
	return bytes.NewReader(ws.buf)
}

// Close :
func (ws *WriterSeeker) Close() {
	return
}

// BytesReader returns a *bytes.Reader. Use it when you need a reader that implements the io.ReadSeeker interface
func (ws *WriterSeeker) BytesReader() *bytes.Reader {
	return bytes.NewReader(ws.buf)
}
<commit_msg>close method with nil error<commit_after>package writerseeker

import (
	"bytes"
	"errors"
	"io"
)

// WriterSeeker is an in-memory io.WriteSeeker implementation
type WriterSeeker struct {
	buf []byte
	pos int
}

// Write writes to the buffer of this WriterSeeker instance
func (ws *WriterSeeker) Write(p []byte) (n int, err error) {
	minCap := ws.pos + len(p)
	if minCap > cap(ws.buf) { // Make sure buf has enough capacity:
		buf2 := make([]byte, len(ws.buf), minCap+len(p)) // add some extra
		copy(buf2, ws.buf)
		ws.buf = buf2
	}
	if minCap > len(ws.buf) {
		ws.buf = ws.buf[:minCap]
	}
	copy(ws.buf[ws.pos:], p)
	ws.pos += len(p)
	return len(p), nil
}

// Seek seeks in the buffer of this WriterSeeker instance
func (ws *WriterSeeker) Seek(offset int64, whence int) (int64, error) {
	newPos, offs := 0, int(offset)
	switch whence {
	case io.SeekStart:
		newPos = offs
	case io.SeekCurrent:
		newPos = ws.pos + offs
	case io.SeekEnd:
		newPos = len(ws.buf) + offs
	}
	if newPos < 0 {
		return 0, errors.New("negative result pos")
	}
	ws.pos = newPos
	return int64(newPos), nil
}

// Reader returns an io.Reader. Use it, for example, with io.Copy, to copy the content of the WriterSeeker buffer to an io.Writer
func (ws *WriterSeeker) Reader() io.Reader {
	return bytes.NewReader(ws.buf)
}

// Close :
func (ws *WriterSeeker) Close() error {
	return nil
}

// BytesReader returns a *bytes.Reader. Use it when you need a reader that implements the io.ReadSeeker interface
func (ws *WriterSeeker) BytesReader() *bytes.Reader {
	return bytes.NewReader(ws.buf)
}
<|endoftext|>


<commit_before>package lzma

import "io"

type XWriter struct {
}

func NewXWriter(lzma io.Writer) *XWriter {
	w, err := NewXWriterParams(lzma, WriterParams{})
	if err != nil {
		panic(err)
	}
	return w
}

func NewXWriterParams(lzma io.Writer, p WriterParams) (w *XWriter, err error) {
	panic("TODO")
}

func (w *XWriter) Write(p []byte) (n int, err error) {
	panic("TODO")
}

func (w *XWriter) Close() error {
	panic("TODO")
}
<commit_msg>lzma: removed xwriter.go<commit_after><|endoftext|>


<commit_before>// Copyright 2017 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

package linux

import (
	"runtime"

	"github.com/google/syzkaller/prog"
)

func initTarget(target *prog.Target) {
	arch := &arch{
		mmapSyscall:               target.SyscallMap["mmap"],
		clockGettimeSyscall:       target.SyscallMap["clock_gettime"],
		PROT_READ:                 target.ConstMap["PROT_READ"],
		PROT_WRITE:                target.ConstMap["PROT_WRITE"],
		MAP_ANONYMOUS:             target.ConstMap["MAP_ANONYMOUS"],
		MAP_PRIVATE:               target.ConstMap["MAP_PRIVATE"],
		MAP_FIXED:                 target.ConstMap["MAP_FIXED"],
		MREMAP_MAYMOVE:            target.ConstMap["MREMAP_MAYMOVE"],
		MREMAP_FIXED:              target.ConstMap["MREMAP_FIXED"],
		S_IFREG:                   target.ConstMap["S_IFREG"],
		S_IFCHR:                   target.ConstMap["S_IFCHR"],
		S_IFBLK:                   target.ConstMap["S_IFBLK"],
		S_IFIFO:                   target.ConstMap["S_IFIFO"],
		S_IFSOCK:                  target.ConstMap["S_IFSOCK"],
		SYSLOG_ACTION_CONSOLE_OFF: target.ConstMap["SYSLOG_ACTION_CONSOLE_OFF"],
		SYSLOG_ACTION_CONSOLE_ON:  target.ConstMap["SYSLOG_ACTION_CONSOLE_ON"],
		SYSLOG_ACTION_SIZE_UNREAD: target.ConstMap["SYSLOG_ACTION_SIZE_UNREAD"],
		FIFREEZE:                  target.ConstMap["FIFREEZE"],
		FITHAW:                    target.ConstMap["FITHAW"],
		PTRACE_TRACEME:            target.ConstMap["PTRACE_TRACEME"],
		CLOCK_REALTIME:            target.ConstMap["CLOCK_REALTIME"],
	}

	target.PageSize = pageSize
	target.DataOffset = dataOffset
	target.MmapSyscall = arch.mmapSyscall
	target.MakeMmap = arch.makeMmap
	target.AnalyzeMmap = arch.analyzeMmap
	target.SanitizeCall = arch.sanitizeCall
	target.SpecialStructs = map[string]func(g *prog.Gen, typ *prog.StructType, old *prog.GroupArg) (
		prog.Arg, []*prog.Call){
		"timespec":     arch.generateTimespec,
		"timeval":      arch.generateTimespec,
		"sockaddr_alg": arch.generateSockaddrAlg,
	}
	target.StringDictionary = stringDictionary

	if target.Arch == runtime.GOARCH {
		KCOV_INIT_TRACE = uintptr(target.ConstMap["KCOV_INIT_TRACE"])
		KCOV_ENABLE = uintptr(target.ConstMap["KCOV_ENABLE"])
		KCOV_TRACE_CMP = uintptr(target.ConstMap["KCOV_TRACE_CMP"])
	}
}

const (
	pageSize   = 4 << 10
	dataOffset = 512 << 20
	invalidFD  = ^uint64(0)
)

var (
	// This should not be here, but for now we expose this for syz-fuzzer.
	KCOV_INIT_TRACE uintptr
	KCOV_ENABLE     uintptr
	KCOV_TRACE_CMP  uintptr

	stringDictionary = []string{"user", "keyring", "trusted", "system", "security", "selinux",
		"posix_acl_access", "mime_type", "md5sum", "nodev", "self",
		"bdev", "proc", "cgroup", "cpuset",
		"lo", "eth0", "eth1", "em0", "em1", "wlan0", "wlan1", "ppp0", "ppp1",
		"vboxnet0", "vboxnet1", "vmnet0", "vmnet1", "GPL"}
)

type arch struct {
	mmapSyscall         *prog.Syscall
	clockGettimeSyscall *prog.Syscall

	PROT_READ                 uint64
	PROT_WRITE                uint64
	MAP_ANONYMOUS             uint64
	MAP_PRIVATE               uint64
	MAP_FIXED                 uint64
	MREMAP_MAYMOVE            uint64
	MREMAP_FIXED              uint64
	S_IFREG                   uint64
	S_IFCHR                   uint64
	S_IFBLK                   uint64
	S_IFIFO                   uint64
	S_IFSOCK                  uint64
	SYSLOG_ACTION_CONSOLE_OFF uint64
	SYSLOG_ACTION_CONSOLE_ON  uint64
	SYSLOG_ACTION_SIZE_UNREAD uint64
	FIFREEZE                  uint64
	FITHAW                    uint64
	PTRACE_TRACEME            uint64
	CLOCK_REALTIME            uint64
}

// createMmapCall creates a "normal" mmap call that maps [start, start+npages) page range.
func (arch *arch) makeMmap(start, npages uint64) *prog.Call {
	meta := arch.mmapSyscall
	return &prog.Call{
		Meta: meta,
		Args: []prog.Arg{
			prog.MakePointerArg(meta.Args[0], start, 0, npages, nil),
			prog.MakeConstArg(meta.Args[1], npages*pageSize),
			prog.MakeConstArg(meta.Args[2], arch.PROT_READ|arch.PROT_WRITE),
			prog.MakeConstArg(meta.Args[3], arch.MAP_ANONYMOUS|arch.MAP_PRIVATE|arch.MAP_FIXED),
			prog.MakeResultArg(meta.Args[4], nil, invalidFD),
			prog.MakeConstArg(meta.Args[5], 0),
		},
		Ret: prog.MakeReturnArg(meta.Ret),
	}
}

func (arch *arch) analyzeMmap(c *prog.Call) (start, npages uint64, mapped bool) {
	switch c.Meta.Name {
	case "mmap":
		// Filter out only very wrong arguments.
		npages = c.Args[1].(*prog.ConstArg).Val / pageSize
		if npages == 0 {
			return
		}
		flags := c.Args[3].(*prog.ConstArg).Val
		fd := c.Args[4].(*prog.ResultArg).Val
		if flags&arch.MAP_ANONYMOUS == 0 && fd == invalidFD {
			return
		}
		start = c.Args[0].(*prog.PointerArg).PageIndex
		mapped = true
		return
	case "munmap":
		start = c.Args[0].(*prog.PointerArg).PageIndex
		npages = c.Args[1].(*prog.ConstArg).Val / pageSize
		mapped = false
		return
	case "mremap":
		start = c.Args[4].(*prog.PointerArg).PageIndex
		npages = c.Args[2].(*prog.ConstArg).Val / pageSize
		mapped = true
		return
	default:
		return
	}
}

func (arch *arch) sanitizeCall(c *prog.Call) {
	switch c.Meta.CallName {
	case "mmap":
		// Add MAP_FIXED flag, otherwise it produces non-deterministic results.
		c.Args[3].(*prog.ConstArg).Val |= arch.MAP_FIXED
	case "mremap":
		// Add MREMAP_FIXED flag, otherwise it produces non-deterministic results.
		flags := c.Args[3].(*prog.ConstArg)
		if flags.Val&arch.MREMAP_MAYMOVE != 0 {
			flags.Val |= arch.MREMAP_FIXED
		}
	case "mknod", "mknodat":
		pos := 1
		if c.Meta.CallName == "mknodat" {
			pos = 2
		}
		mode := c.Args[pos].(*prog.ConstArg)
		dev := c.Args[pos+1].(*prog.ConstArg)
		// Char and block devices read/write io ports, kernel memory and do other nasty things.
		// TODO: not required if executor drops privileges.
		switch mode.Val & (arch.S_IFREG | arch.S_IFCHR | arch.S_IFBLK | arch.S_IFIFO | arch.S_IFSOCK) {
		case arch.S_IFREG, arch.S_IFIFO, arch.S_IFSOCK:
		case arch.S_IFBLK:
			// TODO(dvyukov): mknod dev argument is uint32,
			// but prog arguments contain not-truncated uint64 values,
			// so we can mistakenly assume that this is not loop, when it actually is.
			// This is not very harmful, but need to verify other arguments in this function.
			if dev.Val>>8 == 7 {
				break // loop
			}
			mode.Val &^= arch.S_IFBLK
			mode.Val |= arch.S_IFREG
		case arch.S_IFCHR:
			mode.Val &^= arch.S_IFCHR
			mode.Val |= arch.S_IFREG
		}
	case "syslog":
		cmd := c.Args[0].(*prog.ConstArg)
		// These disable console output, but we need it.
		if cmd.Val == arch.SYSLOG_ACTION_CONSOLE_OFF || cmd.Val == arch.SYSLOG_ACTION_CONSOLE_ON {
			cmd.Val = arch.SYSLOG_ACTION_SIZE_UNREAD
		}
	case "ioctl":
		cmd := c.Args[1].(*prog.ConstArg)
		// Freeze kills machine. Though, it is an interesting functions,
		// so we need to test it somehow.
		// TODO: not required if executor drops privileges.
		if uint64(uint32(cmd.Val)) == arch.FIFREEZE {
			cmd.Val = arch.FITHAW
		}
	case "ptrace":
		req := c.Args[0].(*prog.ConstArg)
		// PTRACE_TRACEME leads to unkillable processes, see:
		// https://groups.google.com/forum/#!topic/syzkaller/uGzwvhlCXAw
		if req.Val == arch.PTRACE_TRACEME {
			req.Val = ^uint64(0)
		}
	case "exit", "exit_group":
		code := c.Args[0].(*prog.ConstArg)
		// These codes are reserved by executor.
		if code.Val%128 == 67 || code.Val%128 == 68 {
			code.Val = 1
		}
	}
}

func (arch *arch) generateTimespec(g *prog.Gen, typ *prog.StructType, old *prog.GroupArg) (arg prog.Arg, calls []*prog.Call) {
	// We need to generate timespec/timeval that are either
	// (1) definitely in the past, or
	// (2) definitely in unreachable fututre, or
	// (3) few ms ahead of now.
	// Note: timespec/timeval can be absolute or relative to now.
	// Note: executor has blocking syscall timeout of 20ms,
	// so we generate both 10ms and 30ms.
	usec := typ.Name() == "timeval"
	switch {
	case g.NOutOf(1, 4):
		// Now for relative, past for absolute.
		arg = prog.MakeGroupArg(typ, []prog.Arg{
			prog.MakeResultArg(typ.Fields[0], nil, 0),
			prog.MakeResultArg(typ.Fields[1], nil, 0),
		})
	case g.NOutOf(1, 3):
		// Few ms ahead for relative, past for absolute
		nsec := uint64(10 * 1e6)
		if g.NOutOf(1, 2) {
			nsec = 30 * 1e6
		}
		if usec {
			nsec /= 1e3
		}
		arg = prog.MakeGroupArg(typ, []prog.Arg{
			prog.MakeResultArg(typ.Fields[0], nil, 0),
			prog.MakeResultArg(typ.Fields[1], nil, nsec),
		})
	case g.NOutOf(1, 2):
		// Unreachable fututre for both relative and absolute
		arg = prog.MakeGroupArg(typ, []prog.Arg{
			prog.MakeResultArg(typ.Fields[0], nil, 2e9),
			prog.MakeResultArg(typ.Fields[1], nil, 0),
		})
	default:
		// Few ms ahead for absolute.
		meta := arch.clockGettimeSyscall
		ptrArgType := meta.Args[1].(*prog.PtrType)
		argType := ptrArgType.Type.(*prog.StructType)
		tp := prog.MakeGroupArg(argType, []prog.Arg{
			prog.MakeResultArg(argType.Fields[0], nil, 0),
			prog.MakeResultArg(argType.Fields[1], nil, 0),
		})
		var tpaddr prog.Arg
		tpaddr, calls = g.Alloc(ptrArgType, tp)
		gettime := &prog.Call{
			Meta: meta,
			Args: []prog.Arg{
				prog.MakeConstArg(meta.Args[0], arch.CLOCK_REALTIME),
				tpaddr,
			},
			Ret: prog.MakeReturnArg(meta.Ret),
		}
		calls = append(calls, gettime)
		sec := prog.MakeResultArg(typ.Fields[0], tp.(*prog.GroupArg).Inner[0], 0)
		nsec := prog.MakeResultArg(typ.Fields[1], tp.(*prog.GroupArg).Inner[1], 0)
		msec := uint64(10)
		if g.NOutOf(1, 2) {
			msec = 30
		}
		if usec {
			nsec.(*prog.ResultArg).OpDiv = 1e3
			nsec.(*prog.ResultArg).OpAdd = msec * 1e3
		} else {
			nsec.(*prog.ResultArg).OpAdd = msec * 1e6
		}
		arg = prog.MakeGroupArg(typ, []prog.Arg{sec, nsec})
	}
	return
}
<commit_msg>sys/linux: resolve TODO re argument truncation<commit_after>// Copyright 2017 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

package linux

import (
	"runtime"

	"github.com/google/syzkaller/prog"
)

func initTarget(target *prog.Target) {
	arch := &arch{
		mmapSyscall:               target.SyscallMap["mmap"],
		clockGettimeSyscall:       target.SyscallMap["clock_gettime"],
		PROT_READ:                 target.ConstMap["PROT_READ"],
		PROT_WRITE:                target.ConstMap["PROT_WRITE"],
		MAP_ANONYMOUS:             target.ConstMap["MAP_ANONYMOUS"],
		MAP_PRIVATE:               target.ConstMap["MAP_PRIVATE"],
		MAP_FIXED:                 target.ConstMap["MAP_FIXED"],
		MREMAP_MAYMOVE:            target.ConstMap["MREMAP_MAYMOVE"],
		MREMAP_FIXED:              target.ConstMap["MREMAP_FIXED"],
		S_IFREG:                   target.ConstMap["S_IFREG"],
		S_IFCHR:                   target.ConstMap["S_IFCHR"],
		S_IFBLK:                   target.ConstMap["S_IFBLK"],
		S_IFIFO:                   target.ConstMap["S_IFIFO"],
		S_IFSOCK:                  target.ConstMap["S_IFSOCK"],
		SYSLOG_ACTION_CONSOLE_OFF: target.ConstMap["SYSLOG_ACTION_CONSOLE_OFF"],
		SYSLOG_ACTION_CONSOLE_ON:  target.ConstMap["SYSLOG_ACTION_CONSOLE_ON"],
		SYSLOG_ACTION_SIZE_UNREAD: target.ConstMap["SYSLOG_ACTION_SIZE_UNREAD"],
		FIFREEZE:                  target.ConstMap["FIFREEZE"],
		FITHAW:                    target.ConstMap["FITHAW"],
		PTRACE_TRACEME:            target.ConstMap["PTRACE_TRACEME"],
		CLOCK_REALTIME:            target.ConstMap["CLOCK_REALTIME"],
	}

	target.PageSize = pageSize
	target.DataOffset = dataOffset
	target.MmapSyscall = arch.mmapSyscall
	target.MakeMmap = arch.makeMmap
	target.AnalyzeMmap = arch.analyzeMmap
	target.SanitizeCall = arch.sanitizeCall
	target.SpecialStructs = map[string]func(g *prog.Gen, typ *prog.StructType, old *prog.GroupArg) (
		prog.Arg, []*prog.Call){
		"timespec":     arch.generateTimespec,
		"timeval":      arch.generateTimespec,
		"sockaddr_alg": arch.generateSockaddrAlg,
	}
	target.StringDictionary = stringDictionary

	if target.Arch == runtime.GOARCH {
		KCOV_INIT_TRACE = uintptr(target.ConstMap["KCOV_INIT_TRACE"])
		KCOV_ENABLE = uintptr(target.ConstMap["KCOV_ENABLE"])
		KCOV_TRACE_CMP = uintptr(target.ConstMap["KCOV_TRACE_CMP"])
	}
}

const (
	pageSize   = 4 << 10
	dataOffset = 512 << 20
	invalidFD  = ^uint64(0)
)

var (
	// This should not be here, but for now we expose this for syz-fuzzer.
	KCOV_INIT_TRACE uintptr
	KCOV_ENABLE     uintptr
	KCOV_TRACE_CMP  uintptr

	stringDictionary = []string{"user", "keyring", "trusted", "system", "security", "selinux",
		"posix_acl_access", "mime_type", "md5sum", "nodev", "self",
		"bdev", "proc", "cgroup", "cpuset",
		"lo", "eth0", "eth1", "em0", "em1", "wlan0", "wlan1", "ppp0", "ppp1",
		"vboxnet0", "vboxnet1", "vmnet0", "vmnet1", "GPL"}
)

type arch struct {
	mmapSyscall         *prog.Syscall
	clockGettimeSyscall *prog.Syscall

	PROT_READ                 uint64
	PROT_WRITE                uint64
	MAP_ANONYMOUS             uint64
	MAP_PRIVATE               uint64
	MAP_FIXED                 uint64
	MREMAP_MAYMOVE            uint64
	MREMAP_FIXED              uint64
	S_IFREG                   uint64
	S_IFCHR                   uint64
	S_IFBLK                   uint64
	S_IFIFO                   uint64
	S_IFSOCK                  uint64
	SYSLOG_ACTION_CONSOLE_OFF uint64
	SYSLOG_ACTION_CONSOLE_ON  uint64
	SYSLOG_ACTION_SIZE_UNREAD uint64
	FIFREEZE                  uint64
	FITHAW                    uint64
	PTRACE_TRACEME            uint64
	CLOCK_REALTIME            uint64
}

// createMmapCall creates a "normal" mmap call that maps [start, start+npages) page range.
func (arch *arch) makeMmap(start, npages uint64) *prog.Call {
	meta := arch.mmapSyscall
	return &prog.Call{
		Meta: meta,
		Args: []prog.Arg{
			prog.MakePointerArg(meta.Args[0], start, 0, npages, nil),
			prog.MakeConstArg(meta.Args[1], npages*pageSize),
			prog.MakeConstArg(meta.Args[2], arch.PROT_READ|arch.PROT_WRITE),
			prog.MakeConstArg(meta.Args[3], arch.MAP_ANONYMOUS|arch.MAP_PRIVATE|arch.MAP_FIXED),
			prog.MakeResultArg(meta.Args[4], nil, invalidFD),
			prog.MakeConstArg(meta.Args[5], 0),
		},
		Ret: prog.MakeReturnArg(meta.Ret),
	}
}

func (arch *arch) analyzeMmap(c *prog.Call) (start, npages uint64, mapped bool) {
	switch c.Meta.Name {
	case "mmap":
		// Filter out only very wrong arguments.
		npages = c.Args[1].(*prog.ConstArg).Val / pageSize
		if npages == 0 {
			return
		}
		flags := c.Args[3].(*prog.ConstArg).Val
		fd := c.Args[4].(*prog.ResultArg).Val
		if flags&arch.MAP_ANONYMOUS == 0 && fd == invalidFD {
			return
		}
		start = c.Args[0].(*prog.PointerArg).PageIndex
		mapped = true
		return
	case "munmap":
		start = c.Args[0].(*prog.PointerArg).PageIndex
		npages = c.Args[1].(*prog.ConstArg).Val / pageSize
		mapped = false
		return
	case "mremap":
		start = c.Args[4].(*prog.PointerArg).PageIndex
		npages = c.Args[2].(*prog.ConstArg).Val / pageSize
		mapped = true
		return
	default:
		return
	}
}

func (arch *arch) sanitizeCall(c *prog.Call) {
	switch c.Meta.CallName {
	case "mmap":
		// Add MAP_FIXED flag, otherwise it produces non-deterministic results.
		c.Args[3].(*prog.ConstArg).Val |= arch.MAP_FIXED
	case "mremap":
		// Add MREMAP_FIXED flag, otherwise it produces non-deterministic results.
		flags := c.Args[3].(*prog.ConstArg)
		if flags.Val&arch.MREMAP_MAYMOVE != 0 {
			flags.Val |= arch.MREMAP_FIXED
		}
	case "mknod", "mknodat":
		pos := 1
		if c.Meta.CallName == "mknodat" {
			pos = 2
		}
		mode := c.Args[pos].(*prog.ConstArg)
		dev := c.Args[pos+1].(*prog.ConstArg)
		dev.Val = uint64(uint32(dev.Val))
		// Char and block devices read/write io ports, kernel memory and do other nasty things.
		// TODO: not required if executor drops privileges.
		switch mode.Val & (arch.S_IFREG | arch.S_IFCHR | arch.S_IFBLK | arch.S_IFIFO | arch.S_IFSOCK) {
		case arch.S_IFREG, arch.S_IFIFO, arch.S_IFSOCK:
		case arch.S_IFBLK:
			if dev.Val>>8 == 7 {
				break // loop
			}
			mode.Val &^= arch.S_IFBLK
			mode.Val |= arch.S_IFREG
		case arch.S_IFCHR:
			mode.Val &^= arch.S_IFCHR
			mode.Val |= arch.S_IFREG
		}
	case "syslog":
		cmd := c.Args[0].(*prog.ConstArg)
		cmd.Val = uint64(uint32(cmd.Val))
		// These disable console output, but we need it.
		if cmd.Val == arch.SYSLOG_ACTION_CONSOLE_OFF || cmd.Val == arch.SYSLOG_ACTION_CONSOLE_ON {
			cmd.Val = arch.SYSLOG_ACTION_SIZE_UNREAD
		}
	case "ioctl":
		cmd := c.Args[1].(*prog.ConstArg)
		// Freeze kills machine. Though, it is an interesting functions,
		// so we need to test it somehow.
		// TODO: not required if executor drops privileges.
		if uint64(uint32(cmd.Val)) == arch.FIFREEZE {
			cmd.Val = arch.FITHAW
		}
	case "ptrace":
		req := c.Args[0].(*prog.ConstArg)
		// PTRACE_TRACEME leads to unkillable processes, see:
		// https://groups.google.com/forum/#!topic/syzkaller/uGzwvhlCXAw
		if req.Val == arch.PTRACE_TRACEME {
			req.Val = ^uint64(0)
		}
	case "exit", "exit_group":
		code := c.Args[0].(*prog.ConstArg)
		// These codes are reserved by executor.
		if code.Val%128 == 67 || code.Val%128 == 68 {
			code.Val = 1
		}
	}
}

func (arch *arch) generateTimespec(g *prog.Gen, typ *prog.StructType, old *prog.GroupArg) (arg prog.Arg, calls []*prog.Call) {
	// We need to generate timespec/timeval that are either
	// (1) definitely in the past, or
	// (2) definitely in unreachable fututre, or
	// (3) few ms ahead of now.
	// Note: timespec/timeval can be absolute or relative to now.
	// Note: executor has blocking syscall timeout of 20ms,
	// so we generate both 10ms and 30ms.
	usec := typ.Name() == "timeval"
	switch {
	case g.NOutOf(1, 4):
		// Now for relative, past for absolute.
		arg = prog.MakeGroupArg(typ, []prog.Arg{
			prog.MakeResultArg(typ.Fields[0], nil, 0),
			prog.MakeResultArg(typ.Fields[1], nil, 0),
		})
	case g.NOutOf(1, 3):
		// Few ms ahead for relative, past for absolute
		nsec := uint64(10 * 1e6)
		if g.NOutOf(1, 2) {
			nsec = 30 * 1e6
		}
		if usec {
			nsec /= 1e3
		}
		arg = prog.MakeGroupArg(typ, []prog.Arg{
			prog.MakeResultArg(typ.Fields[0], nil, 0),
			prog.MakeResultArg(typ.Fields[1], nil, nsec),
		})
	case g.NOutOf(1, 2):
		// Unreachable fututre for both relative and absolute
		arg = prog.MakeGroupArg(typ, []prog.Arg{
			prog.MakeResultArg(typ.Fields[0], nil, 2e9),
			prog.MakeResultArg(typ.Fields[1], nil, 0),
		})
	default:
		// Few ms ahead for absolute.
		meta := arch.clockGettimeSyscall
		ptrArgType := meta.Args[1].(*prog.PtrType)
		argType := ptrArgType.Type.(*prog.StructType)
		tp := prog.MakeGroupArg(argType, []prog.Arg{
			prog.MakeResultArg(argType.Fields[0], nil, 0),
			prog.MakeResultArg(argType.Fields[1], nil, 0),
		})
		var tpaddr prog.Arg
		tpaddr, calls = g.Alloc(ptrArgType, tp)
		gettime := &prog.Call{
			Meta: meta,
			Args: []prog.Arg{
				prog.MakeConstArg(meta.Args[0], arch.CLOCK_REALTIME),
				tpaddr,
			},
			Ret: prog.MakeReturnArg(meta.Ret),
		}
		calls = append(calls, gettime)
		sec := prog.MakeResultArg(typ.Fields[0], tp.(*prog.GroupArg).Inner[0], 0)
		nsec := prog.MakeResultArg(typ.Fields[1], tp.(*prog.GroupArg).Inner[1], 0)
		msec := uint64(10)
		if g.NOutOf(1, 2) {
			msec = 30
		}
		if usec {
			nsec.(*prog.ResultArg).OpDiv = 1e3
			nsec.(*prog.ResultArg).OpAdd = msec * 1e3
		} else {
			nsec.(*prog.ResultArg).OpAdd = msec * 1e6
		}
		arg = prog.MakeGroupArg(typ, []prog.Arg{sec, nsec})
	}
	return
}
<|endoftext|>


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

package syslog

import (
	"errors"
	"fmt"
	"io"
	"log"
	"os"

	"github.com/venicegeo/pz-gocommon/elasticsearch"
	piazza "github.com/venicegeo/pz-gocommon/gocommon"
)

const (
	SyslogdNetwork = ""
	SyslogdRaddr   = ""
)

//---------------------------------------------------------------------

// Writer is an interface for writing a Message to some sort of output.
type Writer interface {
	Write(*Message) error
	Close() error
}

// Reader is an interface for reading Messages from some sort of input.
// count is the number of messages to read: 1 means the latest message,
// 2 means the two latest messages, etc. The newest message is at the end
// of the array.
type Reader interface {
	Read(count int) ([]*Message, error)
	GetMessages(*piazza.JsonPagination, *piazza.HttpQueryParams) ([]Message, int, error)
}

type WriterReader interface {
	Reader
	Writer
}

//---------------------------------------------------------------------

// FileWriter implements the Writer interface, writing to a given file
type FileWriter struct {
	FileName string
	file     *os.File
}

// Write writes the message to the supplied file.
func (w *FileWriter) Write(mssg *Message) error {
	var _ Writer = (*FileWriter)(nil)

	var err error

	if w == nil || w.FileName == "" {
		return fmt.Errorf("writer not set not set")
	}

	if w.file == nil {
		w.file, err = os.OpenFile(w.FileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0777)
		if err != nil {
			return err
		}
	}

	s := mssg.String()
	s += "\n"

	_, err = io.WriteString(w.file, s)
	return err
}

// Close closes the file. The creator of the FileWriter must call this.
func (w *FileWriter) Close() error {
	return w.file.Close()
}

//---------------------------------------------------------------------

//STDOUTWriter writes messages to STDOUT
type STDOUTWriter struct {
}

//Writes message to STDOUT
func (w *STDOUTWriter) Write(mssg *Message) error {
	var _ Writer = (*FileWriter)(nil)
	log.Println(mssg.String())
	return nil
}

//Nothing to close for this writer
func Close() error {
	return nil
}

//---------------------------------------------------------------------

// MessageWriter implements Reader and Writer, using an array of Messages
// as the backing store
type LocalReaderWriter struct {
	messages []*Message
}

// Write writes the message to the backing array
func (w *LocalReaderWriter) Write(mssg *Message) error {
	var _ Writer = (*LocalReaderWriter)(nil)

	if w.messages == nil {
		w.messages = make([]*Message, 0)
	}

	w.messages = append(w.messages, mssg)

	return nil
}

// Read reads messages from the backing array. Will only return as many as are
// available; asking for too many is not an error.
func (w *LocalReaderWriter) Read(count int) ([]*Message, error) {
	var _ Reader = (*LocalReaderWriter)(nil)

	if count < 0 {
		return nil, fmt.Errorf("invalid count: %d", count)
	}

	if w.messages == nil || count == 0 {
		return make([]*Message, 0), nil
	}

	if count > len(w.messages) {
		count = len(w.messages)
	}

	n := len(w.messages)
	a := w.messages[n-count : n]

	return a, nil
}

func (w *LocalReaderWriter) GetMessages(*piazza.JsonPagination, *piazza.HttpQueryParams) ([]Message, int, error) {
	return nil, 0, fmt.Errorf("LocalReaderWriter.GetMessages() not supported")
}

func (w *LocalReaderWriter) Close() error {
	return nil
}

//---------------------------------------------------------------------

// HttpWriter implements Writer, by talking to the actual pz-logger service
type HttpWriter struct {
	url string
	h   piazza.Http
}

func NewHttpWriter(url string) (*HttpWriter, error) {
	w := &HttpWriter{}
	w.url = url
	w.h = piazza.Http{BaseUrl: url}
	return w, nil
}

func (w *HttpWriter) Write(mssg *Message) error {
	var _ Writer = (*HttpWriter)(nil)

	jresp := w.h.PzPost("/syslog", mssg)
	if jresp.IsError() {
		return jresp.ToError()
	}
	return nil
}

func (w *HttpWriter) Close() error {
	return nil
}

func (w *HttpWriter) Read(count int) ([]*Message, error) {
	var _ Reader = (*HttpWriter)(nil)

	return nil, fmt.Errorf("HttpWriter.Read() not supported")
}

// GetMessages is only implemented for HttpWriter as it is most likely the only
// Writer to be used for reading back data.
func (w *HttpWriter) GetMessages(
	format *piazza.JsonPagination,
	params *piazza.HttpQueryParams) ([]Message, int, error) {
	var _ Reader = (*HttpWriter)(nil)

	formatString := format.String()
	paramString := params.String()

	var ext string
	if formatString != "" && paramString != "" {
		ext = "?" + formatString + "&" + paramString
	} else if formatString == "" && paramString != "" {
		ext = "?" + paramString
	} else if formatString != "" && paramString == "" {
		ext = "?" + formatString
	} else if formatString == "" && paramString == "" {
		ext = ""
	} else {
		return nil, 0, errors.New("Internal error: failed to parse query params")
	}

	endpoint := "/syslog" + ext
	jresp := w.h.PzGet(endpoint)
	if jresp.IsError() {
		return nil, 0, jresp.ToError()
	}
	var mssgs []Message
	err := jresp.ExtractData(&mssgs)
	if err != nil {
		return nil, 0, err
	}

	return mssgs, jresp.Pagination.Count, nil
}

//---------------------------------------------------------------------

// SyslogdWriter implements a Writer that writes to the syslogd system service.
// This will almost certainly not work on Windows, but that is okay because Piazza
// does not support Windows.
type SyslogdWriter struct {
	writer *DaemonWriter
}

func (w *SyslogdWriter) initWriter() error {
	if w.writer != nil {
		return nil
	}

	tw, err := Dial(SyslogdNetwork, SyslogdRaddr)
	if err != nil {
		return err
	}

	w.writer = tw

	return nil
}

// Write writes the message to the OS's syslogd system.
func (w *SyslogdWriter) Write(mssg *Message) error {
	// compile-time check if interface is implemented
	var _ Writer = (*SyslogdWriter)(nil)

	var err error

	err = w.initWriter()
	if err != nil {
		return err
	}

	s := mssg.String()

	return w.writer.Write(s)
}

// Close closes the underlying network connection.
func (w *SyslogdWriter) Close() error {
	if w.writer == nil {
		return nil
	}
	return w.writer.Close()
}

//---------------------------------------------------------------------

// ElasticWriter implements the Writer, writing to elasticsearch
type ElasticWriter struct {
	Esi elasticsearch.IIndex
	typ string
	id  string
}

func NewElasticWriter(esi elasticsearch.IIndex, typ string) *ElasticWriter {
	ew := &ElasticWriter{
		Esi: esi,
		typ: typ,
	}
	return ew
}

// Write writes the message to the elasticsearch index, type, id
func (w *ElasticWriter) Write(mssg *Message) error {
	var _ Writer = (*ElasticWriter)(nil)

	var err error

	if w == nil || w.Esi == nil || w.typ == "" {
		return fmt.Errorf("writer not set not set")
	}

	_, err = w.Esi.PostData(w.typ, w.id, mssg)
	return err
}

// SetType sets the type to write to
func (w *ElasticWriter) SetType(typ string) error {
	if w == nil {
		return fmt.Errorf("writer not set not set")
	}
	w.typ = typ
	return nil
}

// SetID sets the id to write to
func (w *ElasticWriter) SetID(id string) error {
	if w == nil {
		return fmt.Errorf("writer not set not set")
	}
	w.id = id
	return nil
}

// Close does nothing but satisfy an interface.
func (w *ElasticWriter) Close() error {
	return nil
}

func (w *ElasticWriter) GetMessages(*piazza.JsonPagination, *piazza.HttpQueryParams) ([]Message, int, error) {
	return nil, 0, fmt.Errorf("ElasticWriter.GetMessages not supported")
}
func (w *ElasticWriter) Read(count int) ([]*Message, error) {
	return nil, fmt.Errorf("ElasticWriter.Read not supported")
}

//-------------------------------
// NilWriter doesn't do anything
type NilWriter struct {
}

func (*NilWriter) Write(*Message) error {
	return nil
}

func (*NilWriter) Close() error {
	return nil
}
<commit_msg>Fixed close method<commit_after>// Copyright 2016, RadiantBlue Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package syslog

import (
	"errors"
	"fmt"
	"io"
	"log"
	"os"

	"github.com/venicegeo/pz-gocommon/elasticsearch"
	piazza "github.com/venicegeo/pz-gocommon/gocommon"
)

const (
	SyslogdNetwork = ""
	SyslogdRaddr   = ""
)

//---------------------------------------------------------------------

// Writer is an interface for writing a Message to some sort of output.
type Writer interface {
	Write(*Message) error
	Close() error
}

// Reader is an interface for reading Messages from some sort of input.
// count is the number of messages to read: 1 means the latest message,
// 2 means the two latest messages, etc. The newest message is at the end
// of the array.
type Reader interface {
	Read(count int) ([]*Message, error)
	GetMessages(*piazza.JsonPagination, *piazza.HttpQueryParams) ([]Message, int, error)
}

type WriterReader interface {
	Reader
	Writer
}

//---------------------------------------------------------------------

// FileWriter implements the Writer interface, writing to a given file
type FileWriter struct {
	FileName string
	file     *os.File
}

// Write writes the message to the supplied file.
func (w *FileWriter) Write(mssg *Message) error {
	var _ Writer = (*FileWriter)(nil)

	var err error

	if w == nil || w.FileName == "" {
		return fmt.Errorf("writer not set not set")
	}

	if w.file == nil {
		w.file, err = os.OpenFile(w.FileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0777)
		if err != nil {
			return err
		}
	}

	s := mssg.String()
	s += "\n"

	_, err = io.WriteString(w.file, s)
	return err
}

// Close closes the file. The creator of the FileWriter must call this.
func (w *FileWriter) Close() error {
	return w.file.Close()
}

//---------------------------------------------------------------------

//STDOUTWriter writes messages to STDOUT
type STDOUTWriter struct {
}

//Writes message to STDOUT
func (w *STDOUTWriter) Write(mssg *Message) error {
	var _ Writer = (*FileWriter)(nil)
	log.Println(mssg.String())
	return nil
}

//Nothing to close for this writer
func (w *STDOUTWriter) Close() error {
	return nil
}

//---------------------------------------------------------------------

// MessageWriter implements Reader and Writer, using an array of Messages
// as the backing store
type LocalReaderWriter struct {
	messages []*Message
}

// Write writes the message to the backing array
func (w *LocalReaderWriter) Write(mssg *Message) error {
	var _ Writer = (*LocalReaderWriter)(nil)

	if w.messages == nil {
		w.messages = make([]*Message, 0)
	}

	w.messages = append(w.messages, mssg)

	return nil
}

// Read reads messages from the backing array. Will only return as many as are
// available; asking for too many is not an error.
func (w *LocalReaderWriter) Read(count int) ([]*Message, error) {
	var _ Reader = (*LocalReaderWriter)(nil)

	if count < 0 {
		return nil, fmt.Errorf("invalid count: %d", count)
	}

	if w.messages == nil || count == 0 {
		return make([]*Message, 0), nil
	}

	if count > len(w.messages) {
		count = len(w.messages)
	}

	n := len(w.messages)
	a := w.messages[n-count : n]

	return a, nil
}

func (w *LocalReaderWriter) GetMessages(*piazza.JsonPagination, *piazza.HttpQueryParams) ([]Message, int, error) {
	return nil, 0, fmt.Errorf("LocalReaderWriter.GetMessages() not supported")
}

func (w *LocalReaderWriter) Close() error {
	return nil
}

//---------------------------------------------------------------------

// HttpWriter implements Writer, by talking to the actual pz-logger service
type HttpWriter struct {
	url string
	h   piazza.Http
}

func NewHttpWriter(url string) (*HttpWriter, error) {
	w := &HttpWriter{}
	w.url = url
	w.h = piazza.Http{BaseUrl: url}
	return w, nil
}

func (w *HttpWriter) Write(mssg *Message) error {
	var _ Writer = (*HttpWriter)(nil)

	jresp := w.h.PzPost("/syslog", mssg)
	if jresp.IsError() {
		return jresp.ToError()
	}
	return nil
}

func (w *HttpWriter) Close() error {
	return nil
}

func (w *HttpWriter) Read(count int) ([]*Message, error) {
	var _ Reader = (*HttpWriter)(nil)

	return nil, fmt.Errorf("HttpWriter.Read() not supported")
}

// GetMessages is only implemented for HttpWriter as it is most likely the only
// Writer to be used for reading back data.
func (w *HttpWriter) GetMessages(
	format *piazza.JsonPagination,
	params *piazza.HttpQueryParams) ([]Message, int, error) {
	var _ Reader = (*HttpWriter)(nil)

	formatString := format.String()
	paramString := params.String()

	var ext string
	if formatString != "" && paramString != "" {
		ext = "?" + formatString + "&" + paramString
	} else if formatString == "" && paramString != "" {
		ext = "?" + paramString
	} else if formatString != "" && paramString == "" {
		ext = "?" + formatString
	} else if formatString == "" && paramString == "" {
		ext = ""
	} else {
		return nil, 0, errors.New("Internal error: failed to parse query params")
	}

	endpoint := "/syslog" + ext
	jresp := w.h.PzGet(endpoint)
	if jresp.IsError() {
		return nil, 0, jresp.ToError()
	}
	var mssgs []Message
	err := jresp.ExtractData(&mssgs)
	if err != nil {
		return nil, 0, err
	}

	return mssgs, jresp.Pagination.Count, nil
}

//---------------------------------------------------------------------

// SyslogdWriter implements a Writer that writes to the syslogd system service.
// This will almost certainly not work on Windows, but that is okay because Piazza
// does not support Windows.
type SyslogdWriter struct {
	writer *DaemonWriter
}

func (w *SyslogdWriter) initWriter() error {
	if w.writer != nil {
		return nil
	}

	tw, err := Dial(SyslogdNetwork, SyslogdRaddr)
	if err != nil {
		return err
	}

	w.writer = tw

	return nil
}

// Write writes the message to the OS's syslogd system.
func (w *SyslogdWriter) Write(mssg *Message) error {
	// compile-time check if interface is implemented
	var _ Writer = (*SyslogdWriter)(nil)

	var err error

	err = w.initWriter()
	if err != nil {
		return err
	}

	s := mssg.String()

	return w.writer.Write(s)
}

// Close closes the underlying network connection.
func (w *SyslogdWriter) Close() error {
	if w.writer == nil {
		return nil
	}
	return w.writer.Close()
}

//---------------------------------------------------------------------

// ElasticWriter implements the Writer, writing to elasticsearch
type ElasticWriter struct {
	Esi elasticsearch.IIndex
	typ string
	id  string
}

func NewElasticWriter(esi elasticsearch.IIndex, typ string) *ElasticWriter {
	ew := &ElasticWriter{
		Esi: esi,
		typ: typ,
	}
	return ew
}

// Write writes the message to the elasticsearch index, type, id
func (w *ElasticWriter) Write(mssg *Message) error {
	var _ Writer = (*ElasticWriter)(nil)

	var err error

	if w == nil || w.Esi == nil || w.typ == "" {
		return fmt.Errorf("writer not set not set")
	}

	_, err = w.Esi.PostData(w.typ, w.id, mssg)
	return err
}

// SetType sets the type to write to
func (w *ElasticWriter) SetType(typ string) error {
	if w == nil {
		return fmt.Errorf("writer not set not set")
	}
	w.typ = typ
	return nil
}

// SetID sets the id to write to
func (w *ElasticWriter) SetID(id string) error {
	if w == nil {
		return fmt.Errorf("writer not set not set")
	}
	w.id = id
	return nil
}

// Close does nothing but satisfy an interface.
func (w *ElasticWriter) Close() error {
	return nil
}

func (w *ElasticWriter) GetMessages(*piazza.JsonPagination, *piazza.HttpQueryParams) ([]Message, int, error) {
	return nil, 0, fmt.Errorf("ElasticWriter.GetMessages not supported")
}
func (w *ElasticWriter) Read(count int) ([]*Message, error) {
	return nil, fmt.Errorf("ElasticWriter.Read not supported")
}

//-------------------------------
// NilWriter doesn't do anything
type NilWriter struct {
}

func (*NilWriter) Write(*Message) error {
	return nil
}

func (*NilWriter) Close() error {
	return nil
}
<|endoftext|>


<commit_before>package models

import (
	e "github.com/techjanitor/pram-post/errors"
	u "github.com/techjanitor/pram-post/utils"
)

type FavoriteModel struct {
	Uid   uint
	Image uint
	Ip    string
}

// ValidateInput will make sure all the parameters are valid
func (i *FavoriteModel) ValidateInput() (err error) {

	if i.Uid == 0 || i.Uid == 1 {
		return e.ErrInvalidParam
	}

	if i.Image == 0 {
		return e.ErrInvalidParam
	}

	return

}

// Status will return info
func (i *FavoriteModel) Status() (err error) {

	// Get Database handle
	db, err := u.GetDb()
	if err != nil {
		return
	}

	var check bool

	// Check if favorite is already there
	err = db.QueryRow("SELECT count(1) FROM favorites WHERE image_id = ? AND user_id = ?", i.Image, i.Uid).Scan(&check)
	if err != nil {
		return
	}

	// delete if it does
	if check {

		ps1, err := db.Prepare("DELETE FROM favorites WHERE image_id = ? AND user_id = ? LIMIT 1")
		if err != nil {
			return
		}
		defer ps1.Close()

		_, err = ps1.Exec(i.Image, i.Uid)
		if err != nil {
			return
		}

		return e.ErrFavoriteRemoved

	}

	return

}

// Post will add the fav to the database
func (i *FavoriteModel) Post() (err error) {

	// Get Database handle
	db, err := u.GetDb()
	if err != nil {
		return
	}

	ps1, err := db.Prepare("INSERT into favorites (image_id, user_id) VALUES (?,?)")
	if err != nil {
		return
	}
	defer ps1.Close()

	_, err = ps1.Exec(i.Image, i.Uid)
	if err != nil {
		return
	}

	return

}
<commit_msg>add user favorites<commit_after>package models

import (
	e "github.com/techjanitor/pram-post/errors"
	u "github.com/techjanitor/pram-post/utils"
)

type FavoriteModel struct {
	Uid   uint
	Image uint
	Ip    string
}

// ValidateInput will make sure all the parameters are valid
func (i *FavoriteModel) ValidateInput() (err error) {

	if i.Uid == 0 || i.Uid == 1 {
		return e.ErrInvalidParam
	}

	if i.Image == 0 {
		return e.ErrInvalidParam
	}

	return

}

// Status will return info
func (i *FavoriteModel) Status() (err error) {

	// Get Database handle
	db, err := u.GetDb()
	if err != nil {
		return
	}

	var check bool

	// Check if favorite is already there
	err = db.QueryRow("SELECT count(1) FROM favorites WHERE image_id = ? AND user_id = ?", i.Image, i.Uid).Scan(&check)
	if err != nil {
		return
	}

	// delete if it does
	if check {

		ps1, err := db.Prepare("DELETE FROM favorites WHERE image_id = ? AND user_id = ? LIMIT 1")
		if err != nil {
			return err
		}
		defer ps1.Close()

		_, err = ps1.Exec(i.Image, i.Uid)
		if err != nil {
			return err
		}

		return e.ErrFavoriteRemoved

	}

	return

}

// Post will add the fav to the database
func (i *FavoriteModel) Post() (err error) {

	// Get Database handle
	db, err := u.GetDb()
	if err != nil {
		return
	}

	ps1, err := db.Prepare("INSERT into favorites (image_id, user_id) VALUES (?,?)")
	if err != nil {
		return
	}
	defer ps1.Close()

	_, err = ps1.Exec(i.Image, i.Uid)
	if err != nil {
		return
	}

	return

}
<|endoftext|>


<commit_before>package venom

import (
	"context"
	"fmt"
	"time"
)

//RunTestStep executes a venom testcase is a venom context
func (v *Venom) RunTestStep(tcc TestCaseContext, e *ExecutorWrap, ts *TestSuite, tc *TestCase, step TestStep, l Logger) ExecutorResult {
	var assertRes assertionsApplied

	var retry int
	var result ExecutorResult

	for retry = 0; retry <= e.retry && !assertRes.ok; retry++ {
		if retry > 1 && !assertRes.ok {
			l.Debugf("Sleep %d, it's %d attempt", e.delay, retry)
			time.Sleep(time.Duration(e.delay) * time.Second)
		}

		var err error
		result, err = runTestStepExecutor(tcc, e, ts, step, l)

		if err != nil {
			continue
		}

		// add result in templater
		ts.Templater.Add(tc.Name, stringifyExecutorResult(result))

		l.Debugf("Apply assertions")

		if h, ok := e.executor.(executorWithDefaultAssertions); ok {
			assertRes = applyChecks(&result, step, h.GetDefaultAssertions(), l)
		} else {
			assertRes = applyChecks(&result, step, nil, l)
		}
		// add result again for extracts values
		ts.Templater.Add(tc.Name, stringifyExecutorResult(result))

		l.Debugf("result step:%+v", result)

		if assertRes.ok {
			break
		}
	}
	tc.Errors = append(tc.Errors, assertRes.errors...)
	tc.Failures = append(tc.Failures, assertRes.failures...)
	if retry > 1 && (len(assertRes.failures) > 0 || len(assertRes.errors) > 0) {
		tc.Failures = append(tc.Failures, Failure{Value: fmt.Sprintf("It's a failure after %d attempts", retry)})
	}
	tc.Systemout.Value += assertRes.systemout
	tc.Systemerr.Value += assertRes.systemerr

	return result
}

func stringifyExecutorResult(e ExecutorResult) map[string]string {
	out := make(map[string]string)
	for k, v := range e {
		out[k] = fmt.Sprintf("%v", v)
	}
	return out
}

func runTestStepExecutor(tcc TestCaseContext, e *ExecutorWrap, ts *TestSuite, step TestStep, l Logger) (ExecutorResult, error) {
	if e.timeout == 0 {
		return e.executor.Run(tcc, l, step, ts.WorkDir)
	}

	ctxTimeout, cancel := context.WithTimeout(context.Background(), time.Duration(e.timeout)*time.Second)
	defer cancel()

	ch := make(chan ExecutorResult)
	cherr := make(chan error)
	go func(tcc TestCaseContext, e *ExecutorWrap, step TestStep, l Logger) {
		result, err := e.executor.Run(tcc, l, step, ts.WorkDir)
		if err != nil {
			cherr <- err
		} else {
			ch <- result
		}
	}(tcc, e, step, l)

	select {
	case err := <-cherr:
		return nil, err
	case result := <-ch:
		return result, nil
	case <-ctxTimeout.Done():
		return nil, fmt.Errorf("Timeout after %d second(s)", e.timeout)
	}
}
<commit_msg>fix (failure): rollback check failures (#156)<commit_after>package venom

import (
	"context"
	"fmt"
	"time"
)

//RunTestStep executes a venom testcase is a venom context
func (v *Venom) RunTestStep(tcc TestCaseContext, e *ExecutorWrap, ts *TestSuite, tc *TestCase, step TestStep, l Logger) ExecutorResult {
	var assertRes assertionsApplied

	var retry int
	var result ExecutorResult

	for retry = 0; retry <= e.retry && !assertRes.ok; retry++ {
		if retry > 1 && !assertRes.ok {
			l.Debugf("Sleep %d, it's %d attempt", e.delay, retry)
			time.Sleep(time.Duration(e.delay) * time.Second)
		}

		var err error
		result, err = runTestStepExecutor(tcc, e, ts, step, l)

		if err != nil {
			tc.Failures = append(tc.Failures, Failure{Value: RemoveNotPrintableChar(err.Error())})
			continue
		}

		// add result in templater
		ts.Templater.Add(tc.Name, stringifyExecutorResult(result))

		l.Debugf("Apply assertions")

		if h, ok := e.executor.(executorWithDefaultAssertions); ok {
			assertRes = applyChecks(&result, step, h.GetDefaultAssertions(), l)
		} else {
			assertRes = applyChecks(&result, step, nil, l)
		}
		// add result again for extracts values
		ts.Templater.Add(tc.Name, stringifyExecutorResult(result))

		l.Debugf("result step:%+v", result)

		if assertRes.ok {
			break
		}
	}
	tc.Errors = append(tc.Errors, assertRes.errors...)
	tc.Failures = append(tc.Failures, assertRes.failures...)
	if retry > 1 && (len(assertRes.failures) > 0 || len(assertRes.errors) > 0) {
		tc.Failures = append(tc.Failures, Failure{Value: fmt.Sprintf("It's a failure after %d attempts", retry)})
	}
	tc.Systemout.Value += assertRes.systemout
	tc.Systemerr.Value += assertRes.systemerr

	return result
}

func stringifyExecutorResult(e ExecutorResult) map[string]string {
	out := make(map[string]string)
	for k, v := range e {
		out[k] = fmt.Sprintf("%v", v)
	}
	return out
}

func runTestStepExecutor(tcc TestCaseContext, e *ExecutorWrap, ts *TestSuite, step TestStep, l Logger) (ExecutorResult, error) {
	if e.timeout == 0 {
		return e.executor.Run(tcc, l, step, ts.WorkDir)
	}

	ctxTimeout, cancel := context.WithTimeout(context.Background(), time.Duration(e.timeout)*time.Second)
	defer cancel()

	ch := make(chan ExecutorResult)
	cherr := make(chan error)
	go func(tcc TestCaseContext, e *ExecutorWrap, step TestStep, l Logger) {
		result, err := e.executor.Run(tcc, l, step, ts.WorkDir)
		if err != nil {
			cherr <- err
		} else {
			ch <- result
		}
	}(tcc, e, step, l)

	select {
	case err := <-cherr:
		return nil, err
	case result := <-ch:
		return result, nil
	case <-ctxTimeout.Done():
		return nil, fmt.Errorf("Timeout after %d second(s)", e.timeout)
	}
}
<|endoftext|>


<commit_before>package dita

import (
	"encoding/xml"
	"strings"
)

type Topic struct {
	XMLName   xml.Name
	ID        string   `xml:"id,attr"`
	Title     string   `xml:"title"`
	NavTitle  string   `xml:"titlealts>navtitle"`
	Prolog    Prolog   `xml:"prolog"`
	ShortDesc InnerXML `xml:"shortdesc"`

	RelatedLink []Link `xml:"related-links>link"`
	Elements    []Body `xml:",any"`
}

type Prolog struct {
	Keywords   Keywords    `xml:"metadata>keywords"`
	OtherMeta  []OtherMeta `xml:"metadata>othermeta"`
	ResourceID []struct {
		Name string `xml:"id,attr"`
	} `xml:"resourceid"`
}

type InnerXML struct {
	XMLName xml.Name
	Content string `xml:",innerxml"`
}

func (x *InnerXML) Text() (string, error) { return xmlstriptags(x.Content) }

type Body struct {
	XMLName xml.Name
	Content string `xml:",innerxml"`
}

type Link struct {
	Href   string `xml:"href,attr"`
	Format string `xml:"format,attr,omitempty"`
	Scope  string `xml:"scope,attr,omitempty"`
	Text   string `xml:"linktext,omitempty"`
}

type OtherMeta struct {
	Name    string `xml:"name,attr"`
	Content string `xml:"content,attr"`
}

type Keywords struct {
	Content string `xml:",innerxml"`
}

func (keywords *Keywords) Terms() (terms []string) {
	dec := xml.NewDecoder(strings.NewReader(keywords.Content))
	for {
		token, err := dec.Token()
		if err != nil {
			return
		}

		if _, isEnd := token.(xml.EndElement); isEnd {
			return
		}

		if start, isStart := token.(xml.StartElement); isStart {
			if start.Name.Local == "indexterm" {
				extractCombinations(dec, &terms)
			}
		}
	}

	panic("unreachable")
}

func extractCombinations(dec *xml.Decoder, terms *[]string) {
	prefix := ""
	emitted := false
	for {
		token, err := dec.Token()
		if err != nil {
			if !emitted && prefix != "" {
				*terms = append(*terms, prefix)
			}
			return
		}
		if _, isEnd := token.(xml.EndElement); isEnd {
			if !emitted && prefix != "" {
				*terms = append(*terms, prefix)
			}
			return
		}
		if start, isStart := token.(xml.StartElement); isStart {
			if start.Name.Local == "indexterm" {
				emitted = true
				if prefix != "" {
					suffix, _ := xmltext(dec)
					*terms = append(*terms, prefix+":"+suffix)
				}
			} else {
				panic("unhandled keyword:" + start.Name.Local)
			}
		}

		if data, isData := token.(xml.CharData); isData {
			prefix = string(data)
		}
	}
}
<commit_msg>Use keyword instead of indexterm as the tag source<commit_after>package dita

import (
	"encoding/xml"
)

type Topic struct {
	XMLName   xml.Name
	ID        string   `xml:"id,attr"`
	Title     string   `xml:"title"`
	NavTitle  string   `xml:"titlealts>navtitle"`
	Prolog    Prolog   `xml:"prolog"`
	ShortDesc InnerXML `xml:"shortdesc"`

	RelatedLink []Link `xml:"related-links>link"`
	Elements    []Body `xml:",any"`
}

type Prolog struct {
	Keywords   []string    `xml:"metadata>keywords>keyword"`
	OtherMeta  []OtherMeta `xml:"metadata>othermeta"`
	ResourceID []struct {
		Name string `xml:"id,attr"`
	} `xml:"resourceid"`
}

type InnerXML struct {
	XMLName xml.Name
	Content string `xml:",innerxml"`
}

func (x *InnerXML) Text() (string, error) { return xmlstriptags(x.Content) }

type Body struct {
	XMLName xml.Name
	Content string `xml:",innerxml"`
}

type Link struct {
	Href   string `xml:"href,attr"`
	Format string `xml:"format,attr,omitempty"`
	Scope  string `xml:"scope,attr,omitempty"`
	Text   string `xml:"linktext,omitempty"`
}

type OtherMeta struct {
	Name    string `xml:"name,attr"`
	Content string `xml:"content,attr"`
}
<|endoftext|>