<commit_before>package main

import (
	"github.com/joshsoftware/curem/config"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

// contact type holds the fields related to a particular contact.
// omitempty tag will make sure the database doesn't contain content like:
//
//   {
//    _id: someId
//    company: ABC
//    Person: Xyz
//    Phone:
//    Skype:
//    Country:
//   }
//Instead, it will store the above data as:
//
//   {
//    _id: someId
//    company: ABC
//    Person: Xyz
//   }
type contact struct {
	Id      bson.ObjectId `bson:"_id"               json:"id"`
	Company string        `bson:"company,omitempty" json:"company,omitempty"`
	Person  string        `bson:"person,omitempty"  json:"person,omitempty"`
	Email   string        `bson:"email,omitempty"   json:"email,omitempty"`
	Phone   string        `bson:"phone,omitempty"   json:"phone,omitempty"`
	SkypeId string        `bson:"skypeid,omitempty" json:"skypeid,omitempty"`
	Country string        `bson:"country,omitempty" json:"country,omitempty"`
}

// NewContact takes the fields of a contact, initializes a struct of contact type and returns
// the pointer to that struct.
// Also, It inserts the contact data into a mongoDB collection, which is passed as the first parameter.
func NewContact(c *mgo.Collection, company, person, email, phone, skypeid, country string) (*contact, error) {
	doc := contact{
		Id:      bson.NewObjectId(),
		Company: company,
		Person:  person,
		Email:   email,
		Phone:   phone,
		SkypeId: skypeid,
		Country: country,
	}
	err := c.Insert(doc)
	if err != nil {
		return &contact{}, err
	}
	return &doc, nil
}

// TODO(Hari): Move session logic into a config file and a separate function
func GetContact(i bson.ObjectId) (*contact, error) {
	collection := config.Db.C("newcontact")
	var c contact
	err := collection.FindId(i).One(&c)
	if err != nil {
		return &contact{}, err
	}
	return &c, nil
}

func DeleteContact(i bson.ObjectId) error {
	collection := config.Db.C("newcontact")
	err := collection.RemoveId(i)
	return err
}
<commit_msg>Remove outdated comment<commit_after>package main

import (
	"github.com/joshsoftware/curem/config"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

// contact type holds the fields related to a particular contact.
// omitempty tag will make sure the database doesn't contain content like:
//
//   {
//    _id: someId
//    company: ABC
//    Person: Xyz
//    Phone:
//    Skype:
//    Country:
//   }
//Instead, it will store the above data as:
//
//   {
//    _id: someId
//    company: ABC
//    Person: Xyz
//   }
type contact struct {
	Id      bson.ObjectId `bson:"_id"               json:"id"`
	Company string        `bson:"company,omitempty" json:"company,omitempty"`
	Person  string        `bson:"person,omitempty"  json:"person,omitempty"`
	Email   string        `bson:"email,omitempty"   json:"email,omitempty"`
	Phone   string        `bson:"phone,omitempty"   json:"phone,omitempty"`
	SkypeId string        `bson:"skypeid,omitempty" json:"skypeid,omitempty"`
	Country string        `bson:"country,omitempty" json:"country,omitempty"`
}

// NewContact takes the fields of a contact, initializes a struct of contact type and returns
// the pointer to that struct.
// Also, It inserts the contact data into a mongoDB collection, which is passed as the first parameter.
func NewContact(c *mgo.Collection, company, person, email, phone, skypeid, country string) (*contact, error) {
	doc := contact{
		Id:      bson.NewObjectId(),
		Company: company,
		Person:  person,
		Email:   email,
		Phone:   phone,
		SkypeId: skypeid,
		Country: country,
	}
	err := c.Insert(doc)
	if err != nil {
		return &contact{}, err
	}
	return &doc, nil
}

func GetContact(i bson.ObjectId) (*contact, error) {
	collection := config.Db.C("newcontact")
	var c contact
	err := collection.FindId(i).One(&c)
	if err != nil {
		return &contact{}, err
	}
	return &c, nil
}

func DeleteContact(i bson.ObjectId) error {
	collection := config.Db.C("newcontact")
	err := collection.RemoveId(i)
	return err
}
<|endoftext|>


<commit_before>package web

import (
	"encoding/json"
	"encoding/xml"
	"errors"
	"net/http"
	"net/url"
	"reflect"
	"strconv"
)

// createContext return a web.Context
func createContext(w http.ResponseWriter, r *http.Request, params *Params) *Context {

	ctx := &Context{
		ResponseWriter: w,
		Request:        r,
		params:         params,
	}

	return ctx
}

// Context is type of an web.Context
type Context struct {
	ResponseWriter http.ResponseWriter
	Request        *http.Request
	params         *Params
	urlValues      *url.Values
	UserID         uint64
}

// Param get value from Params
func (ctx *Context) Param(name string) string {
	return ctx.params.Val(name)
}

// Query get value from QueryString
func (ctx *Context) Query(name string) string {
	if ctx.urlValues == nil {
		urlValues := ctx.Request.URL.Query()
		ctx.urlValues = &urlValues
	}

	return ctx.urlValues.Get(name)
}

// Form get value from Form
func (ctx *Context) Form(name string) string {
	if ctx.Request.Form == nil {
		ctx.Request.ParseForm()
	}
	return ctx.Request.Form.Get(name)
}

// TryParse try parse val to v
func (ctx *Context) TryParse(val string, v interface{}) error {
	if v == nil {
		return errors.New("TryParse(nil)")
	}

	rv := reflect.ValueOf(v)

	if rv.Kind() != reflect.Ptr {
		return errors.New("TryParse(non-pointer " + reflect.TypeOf(v).String() + ")")
	}

	if rv.IsNil() {
		return errors.New("TryParse(nil)")
	}

	for rv.Kind() == reflect.Ptr && !rv.IsNil() {
		rv = rv.Elem()
	}

	if !rv.CanSet() {
		return errors.New("TryParse(can not set value to v)")
	}

	switch rv.Interface().(type) {
	case string:
		rv.SetString(val)
		return nil
	case int, int64:
		d, err := strconv.ParseInt(val, 10, 64)
		if err != nil {
			return err
		}
		rv.SetInt(d)
		return nil
	case int32:
		d, err := strconv.ParseInt(val, 10, 32)
		if err != nil {
			return err
		}
		rv.SetInt(d)
		return nil
	default:
		return json.Unmarshal([]byte(val), v)
	}
}

// Parse parse val to v, if error abort
func (ctx *Context) Parse(val string, v interface{}) {
	ctx.Abort(ctx.TryParse(val, v))
}

// TryParseBody decode val from Request.Body
func (ctx *Context) TryParseBody(val interface{}) error {
	if err := json.NewDecoder(ctx.Request.Body).Decode(val); err != nil {
		return err
	}
	defer ctx.Request.Body.Close()
	return nil
}

// ParseBody decode val from Request.Body, if error abort
func (ctx *Context) ParseBody(val interface{}) {
	ctx.Abort(ctx.TryParseBody(val))
}

// TryParseParam decode val from Query
func (ctx *Context) TryParseParam(name string, val interface{}) error {
	return ctx.TryParse(ctx.Param(name), val)
}

// ParseParam decode val from Param, if error abort
func (ctx *Context) ParseParam(name string, val interface{}) {
	ctx.Abort(ctx.TryParseParam(name, val))
}

// TryParseQuery decode val from Query
func (ctx *Context) TryParseQuery(name string, val interface{}) error {
	return ctx.TryParse(ctx.Query(name), val)
}

// ParseQuery decode val from Query, if error abort
func (ctx *Context) ParseQuery(name string, val interface{}) {
	ctx.Abort(ctx.TryParseQuery(name, val))
}

// TryParseForm decode val from Form
func (ctx *Context) TryParseForm(name string, val interface{}) error {
	return ctx.TryParse(ctx.Form(name), val)
}

// ParseForm decode val from Form, if error abort
func (ctx *Context) ParseForm(name string, val interface{}) {
	ctx.Abort(ctx.TryParseForm(name, val))
}

// Abort if error response err message with status 400 then abort
func (ctx *Context) Abort(err error) {
	if err != nil {
		ctx.WriteHeader(defaultHTTPError)
		ctx.WriteString(err.Error())
		panic(err)
	}
}

// AbortIf if error response err message with status 400 then abort
// else response val
func (ctx *Context) AbortIf(val interface{}, err error) {
	if err != nil {
		ctx.WriteHeader(defaultHTTPError)
		ctx.WriteString(err.Error())
		panic(err)
	} else {
		ctx.WriteJSON(val)
	}
}

// Header get value by key from header
func (ctx *Context) Header(key string) string {
	return ctx.Request.Header.Get(key)
}

// Write bytes
func (ctx *Context) Write(val []byte) (int, error) {
	return ctx.ResponseWriter.Write(val)
}

// WriteString Write String
func (ctx *Context) WriteString(val string) (int, error) {
	return ctx.ResponseWriter.Write([]byte(val))
}

// WriteJSON Write JSON
func (ctx *Context) WriteJSON(val interface{}) error {
	return json.NewEncoder(ctx.ResponseWriter).Encode(val)
}

// WriteXML Write XML
func (ctx *Context) WriteXML(val interface{}) error {
	return xml.NewEncoder(ctx.ResponseWriter).Encode(val)
}

// WriteHeader Write Header
func (ctx *Context) WriteHeader(statusCode int) {
	ctx.ResponseWriter.WriteHeader(statusCode)
}

// SetHeader Set Header
func (ctx *Context) SetHeader(key string, value string) {
	ctx.ResponseWriter.Header().Set(key, value)
}

// AddHeader Add Header
func (ctx *Context) AddHeader(key string, value string) {
	ctx.ResponseWriter.Header().Add(key, value)
}

// SetContentType Set Content-Type
func (ctx *Context) SetContentType(val string) {
	ctx.SetHeader("Content-Type", contentType(val))
}

// Redirect to url with status
func (ctx *Context) Redirect(status int, url string) {
	ctx.SetHeader("Location", url)
	ctx.WriteHeader(status)
	ctx.WriteString("Redirecting to: " + url)
}
<commit_msg>alway response jason<commit_after>package web

import (
	"encoding/json"
	"encoding/xml"
	"errors"
	"net/http"
	"net/url"
	"reflect"
	"strconv"
)

// createContext return a web.Context
func createContext(w http.ResponseWriter, r *http.Request, params *Params) *Context {

	ctx := &Context{
		ResponseWriter: w,
		Request:        r,
		params:         params,
	}

	return ctx
}

// Context is type of an web.Context
type Context struct {
	ResponseWriter http.ResponseWriter
	Request        *http.Request
	params         *Params
	urlValues      *url.Values
	UserID         uint64
}

// Param get value from Params
func (ctx *Context) Param(name string) string {
	return ctx.params.Val(name)
}

// Query get value from QueryString
func (ctx *Context) Query(name string) string {
	if ctx.urlValues == nil {
		urlValues := ctx.Request.URL.Query()
		ctx.urlValues = &urlValues
	}

	return ctx.urlValues.Get(name)
}

// Form get value from Form
func (ctx *Context) Form(name string) string {
	if ctx.Request.Form == nil {
		ctx.Request.ParseForm()
	}
	return ctx.Request.Form.Get(name)
}

// TryParse try parse val to v
func (ctx *Context) TryParse(val string, v interface{}) error {
	if v == nil {
		return errors.New("TryParse(nil)")
	}

	rv := reflect.ValueOf(v)

	if rv.Kind() != reflect.Ptr {
		return errors.New("TryParse(non-pointer " + reflect.TypeOf(v).String() + ")")
	}

	if rv.IsNil() {
		return errors.New("TryParse(nil)")
	}

	for rv.Kind() == reflect.Ptr && !rv.IsNil() {
		rv = rv.Elem()
	}

	if !rv.CanSet() {
		return errors.New("TryParse(can not set value to v)")
	}

	switch rv.Interface().(type) {
	case string:
		rv.SetString(val)
		return nil
	case int, int64:
		d, err := strconv.ParseInt(val, 10, 64)
		if err != nil {
			return err
		}
		rv.SetInt(d)
		return nil
	case int32:
		d, err := strconv.ParseInt(val, 10, 32)
		if err != nil {
			return err
		}
		rv.SetInt(d)
		return nil
	default:
		return json.Unmarshal([]byte(val), v)
	}
}

// Parse parse val to v, if error abort
func (ctx *Context) Parse(val string, v interface{}) {
	ctx.Abort(ctx.TryParse(val, v))
}

// TryParseBody decode val from Request.Body
func (ctx *Context) TryParseBody(val interface{}) error {
	if err := json.NewDecoder(ctx.Request.Body).Decode(val); err != nil {
		return err
	}
	defer ctx.Request.Body.Close()
	return nil
}

// ParseBody decode val from Request.Body, if error abort
func (ctx *Context) ParseBody(val interface{}) {
	ctx.Abort(ctx.TryParseBody(val))
}

// TryParseParam decode val from Query
func (ctx *Context) TryParseParam(name string, val interface{}) error {
	return ctx.TryParse(ctx.Param(name), val)
}

// ParseParam decode val from Param, if error abort
func (ctx *Context) ParseParam(name string, val interface{}) {
	ctx.Abort(ctx.TryParseParam(name, val))
}

// TryParseQuery decode val from Query
func (ctx *Context) TryParseQuery(name string, val interface{}) error {
	return ctx.TryParse(ctx.Query(name), val)
}

// ParseQuery decode val from Query, if error abort
func (ctx *Context) ParseQuery(name string, val interface{}) {
	ctx.Abort(ctx.TryParseQuery(name, val))
}

// TryParseForm decode val from Form
func (ctx *Context) TryParseForm(name string, val interface{}) error {
	return ctx.TryParse(ctx.Form(name), val)
}

// ParseForm decode val from Form, if error abort
func (ctx *Context) ParseForm(name string, val interface{}) {
	ctx.Abort(ctx.TryParseForm(name, val))
}

// Abort if error response err message with status 400 then abort
func (ctx *Context) Abort(err error) {
	if err != nil {
		ctx.WriteHeader(defaultHTTPError)
		ctx.WriteJSON(err.Error())
		panic(err)
	}
}

// AbortIf if error response err message with status 400 then abort
// else response val
func (ctx *Context) AbortIf(val interface{}, err error) {
	if err != nil {
		ctx.WriteHeader(defaultHTTPError)
		ctx.WriteJSON(err.Error())
		panic(err)
	} else {
		ctx.WriteHeader(defaultHTTPSuccess)
		ctx.WriteJSON(val)
	}
}

// Header get value by key from header
func (ctx *Context) Header(key string) string {
	return ctx.Request.Header.Get(key)
}

// Write bytes
func (ctx *Context) Write(val []byte) (int, error) {
	return ctx.ResponseWriter.Write(val)
}

// WriteString Write String
func (ctx *Context) WriteString(val string) (int, error) {
	return ctx.ResponseWriter.Write([]byte(val))
}

// WriteJSON Write JSON
func (ctx *Context) WriteJSON(val interface{}) error {
	return json.NewEncoder(ctx.ResponseWriter).Encode(val)
}

// WriteXML Write XML
func (ctx *Context) WriteXML(val interface{}) error {
	return xml.NewEncoder(ctx.ResponseWriter).Encode(val)
}

// WriteHeader Write Header
func (ctx *Context) WriteHeader(statusCode int) {
	ctx.ResponseWriter.WriteHeader(statusCode)
}

// SetHeader Set Header
func (ctx *Context) SetHeader(key string, value string) {
	ctx.ResponseWriter.Header().Set(key, value)
}

// AddHeader Add Header
func (ctx *Context) AddHeader(key string, value string) {
	ctx.ResponseWriter.Header().Add(key, value)
}

// SetContentType Set Content-Type
func (ctx *Context) SetContentType(val string) {
	ctx.SetHeader("Content-Type", contentType(val))
}

// Redirect to url with status
func (ctx *Context) Redirect(status int, url string) {
	ctx.SetHeader("Location", url)
	ctx.WriteHeader(status)
	ctx.WriteString("Redirecting to: " + url)
}
<|endoftext|>


<commit_before>// Copyright 2016 Marcel Gotsch. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package goserv

import "net/http"

// RequestContext stores key-value pairs supporting all data types and
// capture URL parameter values accessible by their parameter name.
type RequestContext struct {
	store  anyMap
	params params
	err    *ContextError
}

// Set sets the value for the specified the key. It replaces any existing values.
func (r *RequestContext) Set(key string, value interface{}) {
	r.store[key] = value
}

// Get retrieves the value for key. If the key doesn't exist in the RequestContext,
// Get returns nil.
func (r *RequestContext) Get(key string) interface{} {
	return r.store[key]
}

// Delete deletes the value associated with key. If the key doesn't exist nothing happens.
func (r *RequestContext) Delete(key string) {
	delete(r.store, key)
}

// Exists returns true if the specified key exists in the RequestContext, otherwise false is returned.
func (r *RequestContext) Exists(key string) bool {
	_, exists := r.store[key]
	return exists
}

// Param returns the capture URL parameter value for the given parameter name. The name is
// the one specified in one of the routing functions without the leading ":".
func (r *RequestContext) Param(name string) string {
	return r.params[name]
}

// Error sets a ContextError which will be passed to the next error handler.
// Calling Error twice will cause a runtime panic!
func (r *RequestContext) Error(err error, code int) {
	if r.err != nil {
		panic("RequestContext: called .Error() twice")
	}
	r.err = &ContextError{err, code}
}

func newRequestContext() *RequestContext {
	return &RequestContext{
		store:  make(anyMap),
		params: make(params),
		err:    nil,
	}
}

// Stores a RequestContext for each Request.
var requestContextMap = make(map[*http.Request]*RequestContext)

// Context returns the corresponding RequestContext for the given Request.
func Context(r *http.Request) *RequestContext {
	return requestContextMap[r]
}

// Stores a new RequestContext for the specified Request in the requestContextMap.
// This may overwrite an existing RequestContext!
func createRequestContext(r *http.Request) {
	requestContextMap[r] = newRequestContext()
}

type params map[string]string
type anyMap map[string]interface{}
<commit_msg>Update context docs<commit_after>// Copyright 2016 Marcel Gotsch. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package goserv

import "net/http"

// RequestContext allows sharing of data between handlers by storing
// key-value pairs of arbitrary types. It also provides the captured
// URL parameter values depending on the current route.
//
// Any occuring errors during the processing of handlers can be
// set on the RequestContext using .Error. By setting an error
// all Routers and Routes will stop processing immediately and the
// error is passed to the next error handler.
type RequestContext struct {
	store  anyMap
	params params
	err    *ContextError
}

// Set sets the value for the specified the key. It replaces any existing values.
func (r *RequestContext) Set(key string, value interface{}) {
	r.store[key] = value
}

// Get retrieves the value for key. If the key doesn't exist in the RequestContext,
// Get returns nil.
func (r *RequestContext) Get(key string) interface{} {
	return r.store[key]
}

// Delete deletes the value associated with key. If the key doesn't exist nothing happens.
func (r *RequestContext) Delete(key string) {
	delete(r.store, key)
}

// Exists returns true if the specified key exists in the RequestContext, otherwise false is returned.
func (r *RequestContext) Exists(key string) bool {
	_, exists := r.store[key]
	return exists
}

// Param returns the capture URL parameter value for the given parameter name. The name is
// the one specified in one of the routing functions without the leading ":".
func (r *RequestContext) Param(name string) string {
	return r.params[name]
}

// Error sets a ContextError which will be passed to the next error handler and
// forces all Routers and Routes to stop processing.
//
// Note: calling Error twice will cause a runtime panic!
func (r *RequestContext) Error(err error, code int) {
	if r.err != nil {
		panic("RequestContext: called .Error() twice")
	}
	r.err = &ContextError{err, code}
}

func newRequestContext() *RequestContext {
	return &RequestContext{
		store:  make(anyMap),
		params: make(params),
		err:    nil,
	}
}

// Stores a RequestContext for each Request.
var requestContextMap = make(map[*http.Request]*RequestContext)

// Context returns the corresponding RequestContext for the given Request.
func Context(r *http.Request) *RequestContext {
	return requestContextMap[r]
}

// Stores a new RequestContext for the specified Request in the requestContextMap.
// This may overwrite an existing RequestContext!
func createRequestContext(r *http.Request) {
	requestContextMap[r] = newRequestContext()
}

type params map[string]string
type anyMap map[string]interface{}
<|endoftext|>


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

package decnumber

/*
#cgo CFLAGS: -Ilibdecnumber

#include "go-decnumber.h"
#include "decContext.h"
#include <stdlib.h>
*/
import "C"

// FreeListSize holds the default size of the free list of Number pointers for contexts. This
// is a tunable parameter. Set it to the desired value before creating a Context.
var FreeListSize uint32 = 128

// Rounding represents the rounding mode used by a given Context.
type Rounding uint32

const (
	RoundCeiling  Rounding = iota // round towards +infinity
	RoundUp                       // round away from 0
	RoundHalfUp                   // 0.5 rounds up
	RoundHalfEven                 // 0.5 rounds to nearest even
	RoundHalfDown                 // 0.5 rounds down
	RoundDown                     // round towards 0 (truncate)
	RoundFloor                    // round towards -infinity
	Round05Up                     // round for reround
	RoundMax                      // enum must be less than this
)

// ContextKind to use when creating a new Context with NewContext()
type ContextKind int32

const (
	InitDecimal32  ContextKind = 32
	InitDecimal64  ContextKind = 64
	InitDecimal128 ContextKind = 128
	// Synonyms
	InitSingle ContextKind = InitDecimal32
	InitDouble ContextKind = InitDecimal64
	InitQuad   ContextKind = InitDecimal128
)

// Limits for the digits, emin and emax parameters in NewCustomContext()
const (
	MaxDigits = 999999999
	MinDigits = 1
	MaxEMax   = 999999999
	MinEMax   = 0
	MaxEMin   = 0
	MinEMin   = -999999999
	MaxMath   = 999999
)

// free list of numbers
type freeNumberList struct {
	size int32 // number of digits. Needed to create new numbers of the proper size
	ch   chan *Number
}

// Get a *Number from the list or create a new one
func (l *freeNumberList) Get() *Number {
	select {
	case n := <-l.ch:
		return n
	default:
	}
	return newNumber(l.size)
}

// Put back a *Number in the free list
func (l *freeNumberList) Put(n *Number) {
	select {
	case l.ch <- n:
	default:
	}
}

// A Context wraps a decNumber context, the data structure used for providing the context
// for operations and for managing exceptional conditions.
//
// Contexts must be created using the NewContext() or NewCustomContext() functions.
//
// Most accessor and status manipulation functions (one liners) have be rewriten in pure Go in
// order to allow inlining and improve performance.
type Context struct {
	ctx C.decContext
	fn  *freeNumberList
}

// NewContext creates a new context of the requested kind.
//
// Although the native byte order should be properly detected at build time, NewContext() will
// check the runtime byte order and panic if the byte order is not set correctly. If your code panics
// on this check, please file a bug report. Providing in an invalid ContextKind will also
// cause your code to panic; this is by design.
//
// For arbitrary precision arithmetic, use NewCustomContext() instead.
//
// The Context is setup as follows, depending on the specified ContextKind:
//
// InitDecimal32 (32 bits precision):
//
//	digits = 7
//	emax = 96
//	emin = -95
//	rouning = RoundHalfEven
//	clamp = 1
//
// InitDecimal64 (64 bits precision):
//
//	digits = 16
//	emax = 384
//	emin = -383
//	rouning = RoundHalfEven
//	clamp = 1
//
// InitDecimal128 (128 bits precision):
//
//	digits = 34
//	emax = 6144
//	emin = -6143
//	rouning = RoundHalfEven
//	clamp = 1
//
func NewContext(kind ContextKind) (pContext *Context) {
	if C.decContextTestEndian(1) != 0 {
		panic("Wrong byte order for this architecture. Please file a bug report.")
	}
	if kind != InitDecimal32 && kind != InitDecimal64 && kind != InitDecimal128 {
		panic("Unsupported context kind.")
	}
	pContext = new(Context)
	C.decContextDefault(&pContext.ctx, C.int32_t(kind))
	pContext.ctx.traps = 0 // disable traps
	pContext.fn = &freeNumberList{int32(pContext.ctx.digits), make(chan *Number, FreeListSize)}
	return
}

// NewCustom context returns a new Context setup with the requested parameters.
//
// digits is used to set the precision to be used for an operation. The result of an
// operation will be rounded to this length if necessary. digits should be in [MinDigits, MaxDigits].
// The maximum supported value for digits in many arithmetic operations is MaxMath.
//
// emax is used to set the magnitude of the largest adjusted exponent that is
// permitted. The adjusted exponent is calculated as though the number were expressed in
// scientific notation (that is, except for 0, expressed with one non-zero digit before the
// decimal point).
// If the adjusted exponent for a result or conversion would be larger than emax then an
// overflow results. emax should be in [MinEMax, MaxEMax]. The maximum supported value for iemax
// in many arithmetic operations is MaxMath.
//
// emin is used to set the smallest adjusted exponent that is permitted for normal
// numbers. The adjusted exponent is calculated as though the number were expressed in
// scientific notation (that is, except for 0, expressed with one non-zero digit before the
// decimal point).
// If the adjusted exponent for a result or conversion would be smaller than emin then the
// result is subnormal. If the result is also inexact, an underflow results. The exponent of
// the smallest possible number (closest to zero) will be emin-digits+1. emin is usually set to
// -emax or to -(emax-1). emin should be in [MinEMin, MaxEMin]. The minimum supported value for
// emin in many arithmetic operations is -MaxMath.
//
// round is used to select the rounding algorithm to be used if rounding is
// necessary during an operation. It must be one of the values in the Rounding
// enumeration.
//
// clamp controls explicit exponent clamping, as is applied when a result is
// encoded in one of the compressed formats. When 0, a result exponent is limited to a
// maximum of emax and a minimum of emin (for example, the exponent of a zero result
// will be clamped to be in this range). When 1, a result exponent has the same minimum
// but is limited to a maximum of emax-(digits-1). As well as clamping zeros, this may
// cause the coefficient of a result to be padded with zeros on the right in order to bring the
// exponent within range.
// For example, if emax is +96 and digits is 7, the result 1.23E+96 would have a [sign,
// coefficient, exponent] of [0, 123, 94] if clamp were 0, but would give [0, 1230000,
// 90] if clamp were 1.
// Also when 1, clamp limits the length of NaN payloads to digits-1 (rather than digits) when
// constructing a NaN by conversion from a string.
func NewCustomContext(digits int32, emax int32, emin int32, round Rounding, clamp uint8) (pContext *Context) {
	if C.decContextTestEndian(1) != 0 {
		panic("Wrong byte order for this architecture. Please file a bug report.")
	}
	pContext = new(Context)
	c := &pContext.ctx
	C.decContextDefault(c, C.DEC_INIT_BASE)
	c.digits = C.int32_t(digits)
	c.emax = C.int32_t(emax)
	c.emin = C.int32_t(emin)
	c.round = uint32(round) // weird type for enums
	c.clamp = C.uint8_t(clamp)
	c.traps = 0 // disable traps
	pContext.fn = &freeNumberList{int32(c.digits), make(chan *Number, FreeListSize)}
	return
}

// Digits gets the working precision
func (c *Context) Digits() int32 {
	return int32(c.ctx.digits)
}

// EMin returns the Context's EMin setting
func (c *Context) EMin() int32 {
	return int32(c.ctx.emin)
}

// EMax returns the Context's EMax setting
func (c *Context) EMax() int32 {
	return int32(c.ctx.emax)
}

// Clamp returns the Context's clamping setting
func (c *Context) Clamp() int8 {
	return int8(c.ctx.clamp)
}

// Rounding gets the rounding mode
func (c *Context) Rounding() Rounding {
	// return Rounding(C.decContextGetRounding(&c.ctx))
	return Rounding(c.ctx.round)
}

// SetRounding sets the rounding mode
func (c *Context) SetRounding(newRounding Rounding) *Context {
	// C.decContextSetRounding(&c.ctx, uint32(newRounding))
	c.ctx.round = uint32(newRounding) // C enums have a Go type, not C
	return c
}

// Status returns the status of a Context
func (c *Context) Status() *Status {
	// return Status(C.decContextGetStatus(&c.ctx))
	return (*Status)(&c.ctx.status)
}

// Func ErrorStatus() checks the Context status for any error condition
// and returns, as an error, a ContextError if any, nil otherwise.
// Convert the return value with err.(decnumber.ContextError) to compare it
// against any of the Status values. This is a shorthand for Context.Status().ToError()
func (c *Context) ErrorStatus() error {
	return c.Status().ToError()
}
<commit_msg>Put back InitBAse + added ZeroStatus() method<commit_after>// Copyright 2014 Denis Bernard. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package decnumber

/*
#cgo CFLAGS: -Ilibdecnumber

#include "go-decnumber.h"
#include "decContext.h"
#include <stdlib.h>
*/
import "C"

// FreeListSize holds the default size of the free list of Number pointers for contexts. This
// is a tunable parameter. Set it to the desired value before creating a Context.
var FreeListSize uint32 = 128

// Rounding represents the rounding mode used by a given Context.
type Rounding uint32

const (
	RoundCeiling  Rounding = iota // round towards +infinity
	RoundUp                       // round away from 0
	RoundHalfUp                   // 0.5 rounds up
	RoundHalfEven                 // 0.5 rounds to nearest even
	RoundHalfDown                 // 0.5 rounds down
	RoundDown                     // round towards 0 (truncate)
	RoundFloor                    // round towards -infinity
	Round05Up                     // round for reround
	RoundMax                      // enum must be less than this
)

// ContextKind to use when creating a new Context with NewContext()
type ContextKind int32

const (
	InitBase       ContextKind = 0
	InitDecimal32  ContextKind = 32
	InitDecimal64  ContextKind = 64
	InitDecimal128 ContextKind = 128
	// Synonyms
	InitSingle ContextKind = InitDecimal32
	InitDouble ContextKind = InitDecimal64
	InitQuad   ContextKind = InitDecimal128
)

// Limits for the digits, emin and emax parameters in NewCustomContext()
const (
	MaxDigits = 999999999
	MinDigits = 1
	MaxEMax   = 999999999
	MinEMax   = 0
	MaxEMin   = 0
	MinEMin   = -999999999
	MaxMath   = 999999
)

// free list of numbers
type freeNumberList struct {
	size int32 // number of digits. Needed to create new numbers of the proper size
	ch   chan *Number
}

// Get a *Number from the list or create a new one
func (l *freeNumberList) Get() *Number {
	select {
	case n := <-l.ch:
		return n
	default:
	}
	return newNumber(l.size)
}

// Put back a *Number in the free list
func (l *freeNumberList) Put(n *Number) {
	select {
	case l.ch <- n:
	default:
	}
}

// A Context wraps a decNumber context, the data structure used for providing the context
// for operations and for managing exceptional conditions.
//
// Contexts must be created using the NewContext() or NewCustomContext() functions.
//
// Most accessor and status manipulation functions (one liners) have be rewriten in pure Go in
// order to allow inlining and improve performance.
type Context struct {
	ctx C.decContext
	fn  *freeNumberList
}

// NewContext creates a new context of the requested kind.
//
// Although the native byte order should be properly detected at build time, NewContext() will
// check the runtime byte order and panic if the byte order is not set correctly. If your code panics
// on this check, please file a bug report. New context will also panic if initialized with an
// Unsupported ContextKind.
//
// The Context is setup as follows, depending on the specified ContextKind:
//
// InitBase : do not use this setting as EMin and EMax will be out of bounds for most arithmetic operations. Use
// NewCustomContext() instead.
//
//	digits = 9
//	emax = 999999999
//	emin = -999999999
//	rouning = RoundHalfUp
//	clamp = 0
//
// InitDecimal32
//
//	digits = 7
//	emax = 96
//	emin = -95
//	rouning = RoundHalfEven
//	clamp = 1
//
// InitDecimal64
//
//	digits = 16
//	emax = 384
//	emin = -383
//	rouning = RoundHalfEven
//	clamp = 1
//
// InitDecimal128
//
//	digits = 34
//	emax = 6144
//	emin = -6143
//	rouning = RoundHalfEven
//	clamp = 1
//
func NewContext(kind ContextKind) (pContext *Context) {
	if C.decContextTestEndian(1) != 0 {
		panic("Wrong byte order for this architecture. Please file a bug report.")
	}
	pContext = new(Context)
	C.decContextDefault(&pContext.ctx, C.int32_t(kind))
	if pContext.Status().Test(Errors) {
		// Happens if kind not in [0, 32, 64, 128]
		panic("Unsupported context kind.")
	}
	pContext.ctx.traps = 0 // disable traps
	pContext.fn = &freeNumberList{int32(pContext.ctx.digits), make(chan *Number, FreeListSize)}
	return
}

// NewCustom context returns a new Context setup with the requested parameters.
//
// digits is used to set the precision to be used for an operation. The result of an
// operation will be rounded to this length if necessary. digits should be in [MinDigits, MaxDigits].
// The maximum supported value for digits in many arithmetic operations is MaxMath.
//
// emax is used to set the magnitude of the largest adjusted exponent that is
// permitted. The adjusted exponent is calculated as though the number were expressed in
// scientific notation (that is, except for 0, expressed with one non-zero digit before the
// decimal point).
// If the adjusted exponent for a result or conversion would be larger than emax then an
// overflow results. emax should be in [MinEMax, MaxEMax]. The maximum supported value for iemax
// in many arithmetic operations is MaxMath.
//
// emin is used to set the smallest adjusted exponent that is permitted for normal
// numbers. The adjusted exponent is calculated as though the number were expressed in
// scientific notation (that is, except for 0, expressed with one non-zero digit before the
// decimal point).
// If the adjusted exponent for a result or conversion would be smaller than emin then the
// result is subnormal. If the result is also inexact, an underflow results. The exponent of
// the smallest possible number (closest to zero) will be emin-digits+1. emin is usually set to
// -emax or to -(emax-1). emin should be in [MinEMin, MaxEMin]. The minimum supported value for
// emin in many arithmetic operations is -MaxMath.
//
// round is used to select the rounding algorithm to be used if rounding is
// necessary during an operation. It must be one of the values in the Rounding
// enumeration.
//
// clamp controls explicit exponent clamping, as is applied when a result is
// encoded in one of the compressed formats. When 0, a result exponent is limited to a
// maximum of emax and a minimum of emin (for example, the exponent of a zero result
// will be clamped to be in this range). When 1, a result exponent has the same minimum
// but is limited to a maximum of emax-(digits-1). As well as clamping zeros, this may
// cause the coefficient of a result to be padded with zeros on the right in order to bring the
// exponent within range.
// For example, if emax is +96 and digits is 7, the result 1.23E+96 would have a [sign,
// coefficient, exponent] of [0, 123, 94] if clamp were 0, but would give [0, 1230000,
// 90] if clamp were 1.
// Also when 1, clamp limits the length of NaN payloads to digits-1 (rather than digits) when
// constructing a NaN by conversion from a string.
func NewCustomContext(digits int32, emax int32, emin int32, round Rounding, clamp uint8) (pContext *Context) {
	if C.decContextTestEndian(1) != 0 {
		panic("Wrong byte order for this architecture. Please file a bug report.")
	}
	pContext = new(Context)
	c := &pContext.ctx
	C.decContextDefault(c, C.DEC_INIT_BASE)
	c.digits = C.int32_t(digits)
	c.emax = C.int32_t(emax)
	c.emin = C.int32_t(emin)
	c.round = uint32(round) // weird type for enums
	c.clamp = C.uint8_t(clamp)
	c.traps = 0 // disable traps
	pContext.fn = &freeNumberList{int32(c.digits), make(chan *Number, FreeListSize)}
	return
}

// Digits gets the working precision
func (c *Context) Digits() int32 {
	return int32(c.ctx.digits)
}

// EMin returns the Context's EMin setting
func (c *Context) EMin() int32 {
	return int32(c.ctx.emin)
}

// EMax returns the Context's EMax setting
func (c *Context) EMax() int32 {
	return int32(c.ctx.emax)
}

// Clamp returns the Context's clamping setting
func (c *Context) Clamp() int8 {
	return int8(c.ctx.clamp)
}

// Rounding gets the rounding mode
func (c *Context) Rounding() Rounding {
	// return Rounding(C.decContextGetRounding(&c.ctx))
	return Rounding(c.ctx.round)
}

// SetRounding sets the rounding mode
func (c *Context) SetRounding(newRounding Rounding) *Context {
	// C.decContextSetRounding(&c.ctx, uint32(newRounding))
	c.ctx.round = uint32(newRounding) // C enums have a Go type, not C
	return c
}

// Status returns the status of a Context
func (c *Context) Status() *Status {
	// return Status(C.decContextGetStatus(&c.ctx))
	return (*Status)(&c.ctx.status)
}

// Func ErrorStatus() checks the Context status for any error condition
// and returns, as an error, a ContextError if any, nil otherwise.
// Convert the return value with err.(decnumber.ContextError) to compare it
// against any of the Status values. This is a shorthand for Context.Status().ToError()
func (c *Context) ErrorStatus() error {
	return c.Status().ToError()
}

// ZeroStatus is used to clear (set to zero) all the status bits of the context.
// This is a shorthand for Status().Zero() that makes chain calling easier.
//
// Returns c.
func (c *Context) ZeroStatus() *Context {
	c.ctx.status = 0
	return c
}
<|endoftext|>


<commit_before>package cpf

import (
	"fmt"
	"math"
	"math/rand"
	"strconv"
	"strings"

	"github.com/go-chat-bot/bot"
)

const (
	tamanhoCPF                      = 11
	msgParametroInvalido            = "Parâmetro inválido."
	msgQuantidadeParametrosInvalida = "Quantidade de parâmetros inválida."
	msgFmtCpfValido                 = "CPF %s é válido."
	msgFmtCpfInvalido               = "CPF %s é inválido."
)

func cpf(command *bot.Cmd) (string, error) {

	var param string
	if len(command.Args) == 0 {
		param = "1"
	} else if len(command.Args) == 1 {
		param = command.Args[0]
	} else {
		return msgQuantidadeParametrosInvalida, nil
	}

	if len(param) > 2 {
		if valid(param) {
			return fmt.Sprintf(msgFmtCpfValido, command.Args[0]), nil
		}
		return fmt.Sprintf(msgFmtCpfInvalido, command.Args[0]), nil
	}

	qtCPF, err := strconv.Atoi(param)
	if err != nil {
		return msgParametroInvalido, nil
	}

	var cpf string
	for i := 0; i < qtCPF; i++ {
		cpf += gerarCPF() + " "
	}
	return cpf, nil
}

func gerarCPF() string {
	doc := rand.Perm(9)
	dv1 := calcDV(doc)
	doc = append(doc, dv1)
	dv2 := calcDV(doc)
	doc = append(doc, dv2)

	var str string
	for _, value := range doc {
		str += strconv.Itoa(value)
	}
	return str
}

func calcDV(doc []int) int {
	var calc float64
	for i, j := 2, len(doc)-1; j >= 0; i, j = i+1, j-1 {
		calc += float64(i * doc[j])
	}
	mod := int(math.Mod(calc*10, 11))
	if mod == 10 {
		return 0
	}
	return mod
}

func valid(cpf string) bool {
	if len(cpf) != tamanhoCPF {
		return false
	}

	for i := 0; i <= 9; i++ {
		if cpf == strings.Repeat(string(i), 11) {
			return false
		}
	}

	s := strings.Split(cpf, "")

	doc := make([]int, 9)
	for i := 0; i <= 8; i++ {
		digito, err := strconv.Atoi(s[i])
		if err != nil {
			return false
		}
		doc[i] = digito
	}

	dv1 := calcDV(doc)
	doc = append(doc, dv1)
	dv2 := calcDV(doc)

	dv1Valido := strconv.Itoa(dv1) == string(s[9])
	dv2Valido := strconv.Itoa(dv2) == string(s[10])
	return dv1Valido && dv2Valido
}

func init() {
	bot.RegisterCommand(
		"cpf",
		"Gerador/Validador de CPF.",
		"n para gerar n CPF e !cpf 11111111111 para validar um CPF",
		cpf)
}
<commit_msg>Refactored obtaining parameters<commit_after>package cpf

import (
	"fmt"
	"math"
	"math/rand"
	"strconv"
	"strings"

	"github.com/go-chat-bot/bot"
)

const (
	tamanhoCPF                      = 11
	msgParametroInvalido            = "Parâmetro inválido."
	msgQuantidadeParametrosInvalida = "Quantidade de parâmetros inválida."
	msgFmtCpfValido                 = "CPF %s é válido."
	msgFmtCpfInvalido               = "CPF %s é inválido."
)

func cpf(command *bot.Cmd) (string, error) {

	var param string
	switch len(command.Args) {
	case 0:
		param = "1"
	case 1:
		param = command.Args[0]
	default:
		return msgQuantidadeParametrosInvalida, nil

	}

	if len(param) > 2 {
		if valid(param) {
			return fmt.Sprintf(msgFmtCpfValido, command.Args[0]), nil
		}
		return fmt.Sprintf(msgFmtCpfInvalido, command.Args[0]), nil
	}

	qtCPF, err := strconv.Atoi(param)
	if err != nil {
		return msgParametroInvalido, nil
	}

	var cpf string
	for i := 0; i < qtCPF; i++ {
		cpf += gerarCPF() + " "
	}
	return cpf, nil
}

func gerarCPF() string {
	doc := rand.Perm(9)
	dv1 := calcDV(doc)
	doc = append(doc, dv1)
	dv2 := calcDV(doc)
	doc = append(doc, dv2)

	var str string
	for _, value := range doc {
		str += strconv.Itoa(value)
	}
	return str
}

func calcDV(doc []int) int {
	var calc float64
	for i, j := 2, len(doc)-1; j >= 0; i, j = i+1, j-1 {
		calc += float64(i * doc[j])
	}
	mod := int(math.Mod(calc*10, 11))
	if mod == 10 {
		return 0
	}
	return mod
}

func valid(cpf string) bool {
	if len(cpf) != tamanhoCPF {
		return false
	}

	for i := 0; i <= 9; i++ {
		if cpf == strings.Repeat(string(i), 11) {
			return false
		}
	}

	s := strings.Split(cpf, "")

	doc := make([]int, 9)
	for i := 0; i <= 8; i++ {
		digito, err := strconv.Atoi(s[i])
		if err != nil {
			return false
		}
		doc[i] = digito
	}

	dv1 := calcDV(doc)
	doc = append(doc, dv1)
	dv2 := calcDV(doc)

	dv1Valido := strconv.Itoa(dv1) == string(s[9])
	dv2Valido := strconv.Itoa(dv2) == string(s[10])
	return dv1Valido && dv2Valido
}

func init() {
	bot.RegisterCommand(
		"cpf",
		"Gerador/Validador de CPF.",
		"n para gerar n CPF e !cpf 12345678909 para validar um CPF",
		cpf)
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"log"
	"net"
	"strconv"
	"time"

	"github.com/btcsuite/btcd/wire"
)

type crawlError struct {
	errLoc string
	Err    error
}

// Error returns a formatted error about a crawl
func (e *crawlError) Error() string {
	return "err: " + e.errLoc + ": " + e.Err.Error()
}

// crawlNode runs in a goroutine, crawls the remote ip and updates the master
// list of currently active addresses
func crawlNode(rc chan *result, s *dnsseeder, nd *node) {

	res := &result{
		node: net.JoinHostPort(nd.na.IP.String(), strconv.Itoa(int(nd.na.Port))),
	}

	// connect to the remote ip and ask them for their addr list
	res.nas, res.msg = crawlIP(s, res)

	// all done so push the result back to the seeder.
	//This will block until the seeder reads the result
	rc <- res

	// goroutine will end and be cleaned up
}

// crawlIP retrievs a slice of ip addresses from a client
func crawlIP(s *dnsseeder, r *result) ([]*wire.NetAddress, *crawlError) {

	conn, err := net.DialTimeout("tcp", r.node, time.Second*10)
	if err != nil {
		if config.debug {
			log.Printf("%s - debug - Could not connect to %s - %v\n", s.name, r.node, err)
		}
		return nil, &crawlError{"", err}
	}

	defer conn.Close()
	if config.debug {
		log.Printf("%s - debug - Connected to remote address: %s\n", s.name, r.node)
	}

	// set a deadline for all comms to be done by. After this all i/o will error
	conn.SetDeadline(time.Now().Add(time.Second * maxTo))

	// First command to remote end needs to be a version command
	// last parameter is lastblock
	msgver, err := wire.NewMsgVersionFromConn(conn, nounce, 0)
	if err != nil {
		return nil, &crawlError{"Create NewMsgVersionFromConn", err}
	}

	err = wire.WriteMessage(conn, msgver, s.pver, s.id)
	if err != nil {
		// Log and handle the error
		return nil, &crawlError{"Write Version Message", err}
	}

	// first message received should be version
	msg, _, err := wire.ReadMessage(conn, s.pver, s.id)
	if err != nil {
		// Log and handle the error
		return nil, &crawlError{"Read message after sending Version", err}
	}

	switch msg := msg.(type) {
	case *wire.MsgVersion:
		// The message is a pointer to a MsgVersion struct.
		if config.debug {
			log.Printf("%s - debug - %s - Remote version: %v\n", s.name, r.node, msg.ProtocolVersion)
		}
		// fill the node struct with the remote details
		r.version = msg.ProtocolVersion
		r.services = msg.Services
		r.lastBlock = msg.LastBlock
		r.strVersion = msg.UserAgent
	default:
		return nil, &crawlError{"Did not receive expected Version message from remote client", errors.New("")}
	}

	// send verack command
	msgverack := wire.NewMsgVerAck()

	err = wire.WriteMessage(conn, msgverack, s.pver, s.id)
	if err != nil {
		return nil, &crawlError{"writing message VerAck", err}
	}

	// second message received should be verack
	msg, _, err = wire.ReadMessage(conn, s.pver, s.id)
	if err != nil {
		return nil, &crawlError{"reading expected Ver Ack from remote client", err}
	}

	switch msg.(type) {
	case *wire.MsgVerAck:
		if config.debug {
			log.Printf("%s - debug - %s - received Version Ack\n", s.name, r.node)
		}
	default:
		return nil, &crawlError{"Did not receive expected Ver Ack message from remote client", errors.New("")}
	}

	// if we get this far and if the seeder is full then don't ask for addresses. This will reduce bandwith usage while still
	// confirming that we can connect to the remote node
	if len(s.theList) > s.maxSize {
		return nil, nil
	}
	// send getaddr command
	msgGetAddr := wire.NewMsgGetAddr()

	err = wire.WriteMessage(conn, msgGetAddr, s.pver, s.id)
	if err != nil {
		return nil, &crawlError{"writing Addr message to remote client", err}
	}

	c := 0
	dowhile := true
	for dowhile == true {

		// Using the Bitcoin lib for the some networks means it does not understand some
		// of the commands and will error. We can ignore these as we are only
		// interested in the addr message and its content.
		msgaddr, _, _ := wire.ReadMessage(conn, s.pver, s.id)
		if msgaddr != nil {
			switch msg := msgaddr.(type) {
			case *wire.MsgAddr:
				// received the addr message so return the result
				if config.debug {
					log.Printf("%s - debug - %s - received valid addr message\n", s.name, r.node)
				}
				dowhile = false
				return msg.AddrList, nil
			default:
				if config.debug {
					log.Printf("%s - debug - %s - ignoring message - %v\n", s.name, r.node, msg.Command())
				}
			}
		}
		// if we get more than 25 messages before the addr we asked for then give up on this client
		if c++; c >= 25 {
			dowhile = false
		}
	}

	// received too many messages before requested Addr
	return nil, &crawlError{"message loop - did not receive remote addresses in first 25 messages from remote client", errors.New("")}
}

/*

 */
<commit_msg>change to NewMsgVersion<commit_after>package main

import (
	"errors"
	"log"
	"net"
	"strconv"
	"time"

	"github.com/btcsuite/btcd/wire"
)

type crawlError struct {
	errLoc string
	Err    error
}

// Error returns a formatted error about a crawl
func (e *crawlError) Error() string {
	return "err: " + e.errLoc + ": " + e.Err.Error()
}

// crawlNode runs in a goroutine, crawls the remote ip and updates the master
// list of currently active addresses
func crawlNode(rc chan *result, s *dnsseeder, nd *node) {

	res := &result{
		node: net.JoinHostPort(nd.na.IP.String(), strconv.Itoa(int(nd.na.Port))),
	}

	// connect to the remote ip and ask them for their addr list
	res.nas, res.msg = crawlIP(s, res)

	// all done so push the result back to the seeder.
	//This will block until the seeder reads the result
	rc <- res

	// goroutine will end and be cleaned up
}

// crawlIP retrievs a slice of ip addresses from a client
func crawlIP(s *dnsseeder, r *result) ([]*wire.NetAddress, *crawlError) {

	conn, err := net.DialTimeout("tcp", r.node, time.Second*10)
	if err != nil {
		if config.debug {
			log.Printf("%s - debug - Could not connect to %s - %v\n", s.name, r.node, err)
		}
		return nil, &crawlError{"", err}
	}

	defer conn.Close()
	if config.debug {
		log.Printf("%s - debug - Connected to remote address: %s\n", s.name, r.node)
	}

	// set a deadline for all comms to be done by. After this all i/o will error
	conn.SetDeadline(time.Now().Add(time.Second * maxTo))

	meAddr, youAddr := conn.LocalAddr(), conn.RemoteAddr()
	me := wire.NewNetAddress(meAddr.(*net.TCPAddr), wire.SFNodeNetwork)
	you := wire.NewNetAddress(youAddr.(*net.TCPAddr), wire.SFNodeNetwork)
	msgver := wire.NewMsgVersion(me, you, nounce, 0)

	err = wire.WriteMessage(conn, msgver, s.pver, s.id)
	if err != nil {
		// Log and handle the error
		return nil, &crawlError{"Write Version Message", err}
	}

	// first message received should be version
	msg, _, err := wire.ReadMessage(conn, s.pver, s.id)
	if err != nil {
		// Log and handle the error
		return nil, &crawlError{"Read message after sending Version", err}
	}

	switch msg := msg.(type) {
	case *wire.MsgVersion:
		// The message is a pointer to a MsgVersion struct.
		if config.debug {
			log.Printf("%s - debug - %s - Remote version: %v\n", s.name, r.node, msg.ProtocolVersion)
		}
		// fill the node struct with the remote details
		r.version = msg.ProtocolVersion
		r.services = msg.Services
		r.lastBlock = msg.LastBlock
		r.strVersion = msg.UserAgent
	default:
		return nil, &crawlError{"Did not receive expected Version message from remote client", errors.New("")}
	}

	// send verack command
	msgverack := wire.NewMsgVerAck()

	err = wire.WriteMessage(conn, msgverack, s.pver, s.id)
	if err != nil {
		return nil, &crawlError{"writing message VerAck", err}
	}

	// second message received should be verack
	msg, _, err = wire.ReadMessage(conn, s.pver, s.id)
	if err != nil {
		return nil, &crawlError{"reading expected Ver Ack from remote client", err}
	}

	switch msg.(type) {
	case *wire.MsgVerAck:
		if config.debug {
			log.Printf("%s - debug - %s - received Version Ack\n", s.name, r.node)
		}
	default:
		return nil, &crawlError{"Did not receive expected Ver Ack message from remote client", errors.New("")}
	}

	// if we get this far and if the seeder is full then don't ask for addresses. This will reduce bandwith usage while still
	// confirming that we can connect to the remote node
	if len(s.theList) > s.maxSize {
		return nil, nil
	}
	// send getaddr command
	msgGetAddr := wire.NewMsgGetAddr()

	err = wire.WriteMessage(conn, msgGetAddr, s.pver, s.id)
	if err != nil {
		return nil, &crawlError{"writing Addr message to remote client", err}
	}

	c := 0
	dowhile := true
	for dowhile == true {

		// Using the Bitcoin lib for the some networks means it does not understand some
		// of the commands and will error. We can ignore these as we are only
		// interested in the addr message and its content.
		msgaddr, _, _ := wire.ReadMessage(conn, s.pver, s.id)
		if msgaddr != nil {
			switch msg := msgaddr.(type) {
			case *wire.MsgAddr:
				// received the addr message so return the result
				if config.debug {
					log.Printf("%s - debug - %s - received valid addr message\n", s.name, r.node)
				}
				dowhile = false
				return msg.AddrList, nil
			default:
				if config.debug {
					log.Printf("%s - debug - %s - ignoring message - %v\n", s.name, r.node, msg.Command())
				}
			}
		}
		// if we get more than 25 messages before the addr we asked for then give up on this client
		if c++; c >= 25 {
			dowhile = false
		}
	}

	// received too many messages before requested Addr
	return nil, &crawlError{"message loop - did not receive remote addresses in first 25 messages from remote client", errors.New("")}
}

/*

 */
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"strconv"
)

type ControlUnit24bit struct {
	data *ControlUnitData
	ProgramCounter int64
}

/*
nThe Memory is 1 "BytesPerElement" larger than the number of PEs. This is so the CU may have its own memory.
*/
func NewControlUnit24bit(indexRegisters uint, processingElements uint, memoryBytesPerElement uint) ControlUnit {
	var cu ControlUnit24bit
	cu.data = NewControlUnitData(indexRegisters, processingElements, memoryBytesPerElement)
	return &cu
}

func (cu *ControlUnit24bit) Data() *ControlUnitData {
	return cu.data
}

func (cu *ControlUnit24bit) PrintMachine() {
	fmt.Println("Machine: 24bit")
	cu.data.PrintMachine()
}

func (cu *ControlUnit24bit) RunProgram(program Program) error {
	cu.ProgramCounter = 0
	for cu.ProgramCounter != int64(program.Size()) {
		pc := cu.ProgramCounter
		inst := program.At(pc)
		op := OpCode(inst[0]) & 63 // 63 = 00111111
		if !isMem(op) {
			param1 := inst[0]>>6 | inst[1]<<2&63
			param2 := inst[1]>>4 | inst[2]<<4&63
			param3 := inst[2] >> 2

			if cu.data.Verbose {
				fmt.Printf("Run() PC: %3d  IS: %5s  P1: %d  P2: %d  P3: %d\n", cu.ProgramCounter, op.String(), param1, param2, param3) // debug
			}
			cu.Execute(op, []byte{param1, param2, param3})
			if cu.data.Verbose {
				cu.data.PrintMachine() // debug
			}
		} else {
			param := inst[0]>>6 | inst[1]<<2&63
			memParam := uint16(inst[1]>>4) | uint16(inst[2])<<4
			if cu.data.Verbose {
				fmt.Printf("Run() PC: %3d  IS: %5s  P: %d  MP: %d\n", cu.ProgramCounter, op.String(), param, memParam) // debug
			}
			cu.ExecuteMem(op, param, memParam)
			if cu.data.Verbose {
				cu.data.PrintMachine() // debug
			}
		}
		cu.ProgramCounter++
	}
	return nil
}

func (cu *ControlUnit24bit) Run(file string) error {
	program, err := LoadProgram24bit(file)
	if err != nil {
		return err
	}
	return cu.RunProgram(program)
}

func (cu *ControlUnit24bit) ExecuteMem(op OpCode, param byte, memParam uint16) {
	switch op {
	case isLdx:
		cu.Ldx(param, memParam)
	case isStx:
		cu.Stx(param, memParam)
	case isCload:
		cu.Cload(memParam)
	case isCstore:
		cu.Cstore(memParam)
	}
}

/// @param params must have as many members as the instruction takes parameters
func (cu *ControlUnit24bit) Execute(instruction OpCode, params []byte) {
	switch instruction {
	case isLdxi:
		cu.Ldxi(params[0], params[1])
	case isIncx:
		cu.Incx(params[0], params[1])
	case isDecx:
		cu.Decx(params[0], params[1])
	case isMulx:
		cu.Mulx(params[0], params[1])
	case isCmpx:
		cu.Cmpx(params[0], params[1], params[2])
	case isCbcast:
		cu.Cbcast()
	case isLod:
		cu.Lod(params[0], params[1])
	case isSto:
		cu.Sto(params[0], params[1])
	case isAdd:
		cu.Add(params[0], params[1])
	case isSub:
		cu.Sub(params[0], params[1])
	case isMul:
		cu.Mul(params[0], params[1])
	case isDiv:
		cu.Div(params[0], params[1])
	case isBcast:
		cu.Bcast(params[0])
	case isMov:
		cu.Mov(RegisterType(params[0]), RegisterType(params[1])) ///< @todo change to be multiple 'instructions' ?
	case isRadd:
		cu.Radd()
	case isRsub:
		cu.Rsub()
	case isRmul:
		cu.Rmul()
	case isRdiv:
		cu.Rdiv()
	}
}

//
// control instructions
//
func (cu *ControlUnit24bit) Ldx(index byte, a uint16) {
	//	fmt.Printf("ldx: cu.data.index[%d] = cu.data.Memory[%d] (%d)"
	cu.data.IndexRegister[index] = cu.data.Memory[a]
}
func (cu *ControlUnit24bit) Stx(index byte, a uint16) {
	fmt.Println("debug: stx " + strconv.Itoa(int(index)) + " into " + strconv.Itoa(int(a)))
	cu.data.Memory[a] = cu.data.IndexRegister[index]
}
func (cu *ControlUnit24bit) Ldxi(index byte, a byte) {
	cu.data.IndexRegister[index] = int64(a)
}
func (cu *ControlUnit24bit) Incx(index byte, a byte) {
	cu.data.IndexRegister[index] += int64(a)
}
func (cu *ControlUnit24bit) Decx(index byte, a byte) {
	cu.data.IndexRegister[index] -= int64(a)
}
func (cu *ControlUnit24bit) Mulx(index byte, a byte) {
	cu.data.IndexRegister[index] *= int64(a)
}
func (cu *ControlUnit24bit) Cload(index uint16) {
//	fmt.Println("debug: cload " + strconv.Itoa(int(index)));
	cu.data.ArithmeticRegister = cu.data.Memory[index]
}
func (cu *ControlUnit24bit) Cstore(index uint16) {
	cu.data.Memory[index] = cu.data.ArithmeticRegister
}

/// @todo fix this to take a larger jump (a). Byte only allows for 256 instructions. That's not a very big program
func (cu *ControlUnit24bit) Cmpx(index byte, ix2 byte, a byte) {
	if cu.data.IndexRegister[index] < cu.data.IndexRegister[ix2] {
		cu.ProgramCounter = int64(a) - 1 // -1 because the PC will be incremented.
	}
}

// control broadcast. Broadcasts the Control's Arithmetic Register to every PE's Routing Register
func (cu *ControlUnit24bit) Cbcast() {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].RoutingRegister = cu.data.ArithmeticRegister
	}
}

// Block until all PE's are done
func (cu *ControlUnit24bit) Barrier() {
	for i := 0; i != len(cu.data.PE); i++ {
		<-cu.data.Done
	}
}

//
// vector instructions
//
func (cu *ControlUnit24bit) Lod(a byte, idx byte) {
	//	fmt.Printf("PE-Lod %d + %d (%d)\n", a, cu.data.IndexRegister[idx], idx)
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Lod <- ByteTuple{a, byte(cu.data.IndexRegister[idx])} ///< @todo is this ok? Should we be loading the index register somewhere else?
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Sto(a byte, idx byte) {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Sto <- ByteTuple{a, byte(cu.data.IndexRegister[idx])}
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Add(a byte, idx byte) {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Add <- ByteTuple{a, byte(cu.data.IndexRegister[idx])}
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Sub(a byte, idx byte) {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Sub <- ByteTuple{a, byte(cu.data.IndexRegister[idx])}
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Mul(a byte, idx byte) {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Mul <- ByteTuple{a, byte(cu.data.IndexRegister[idx])}
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Div(a byte, idx byte) {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Div <- ByteTuple{a, byte(cu.data.IndexRegister[idx])}
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Bcast(idx byte) {
	idx = byte(cu.data.IndexRegister[idx]) ///< @todo is this ok? Should we be loading the index register here?
	for i, _ := range cu.data.PE {
		if !cu.data.PE[i].Enabled {
			continue
		}
		cu.data.PE[i].RoutingRegister = cu.data.PE[idx].RoutingRegister
	}
}
func (cu *ControlUnit24bit) Mov(from RegisterType, to RegisterType) {
	/// @todo remove this? speed for safety?
	if from == to {
		return
	}
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Mov <- ByteTuple{byte(from), byte(to)}
	}
	cu.Barrier()
}

func (cu *ControlUnit24bit) Radd() {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Radd <- true
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Rsub() {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Rsub <- true
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Rmul() {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Rmul <- true
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Rdiv() {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Rdiv <- true
	}
	cu.Barrier()
}
<commit_msg>removed debug print<commit_after>package main

import (
	"fmt"
//	"strconv"
)

type ControlUnit24bit struct {
	data *ControlUnitData
	ProgramCounter int64
}

/*
nThe Memory is 1 "BytesPerElement" larger than the number of PEs. This is so the CU may have its own memory.
*/
func NewControlUnit24bit(indexRegisters uint, processingElements uint, memoryBytesPerElement uint) ControlUnit {
	var cu ControlUnit24bit
	cu.data = NewControlUnitData(indexRegisters, processingElements, memoryBytesPerElement)
	return &cu
}

func (cu *ControlUnit24bit) Data() *ControlUnitData {
	return cu.data
}

func (cu *ControlUnit24bit) PrintMachine() {
	fmt.Println("Machine: 24bit")
	cu.data.PrintMachine()
}

func (cu *ControlUnit24bit) RunProgram(program Program) error {
	cu.ProgramCounter = 0
	for cu.ProgramCounter != int64(program.Size()) {
		pc := cu.ProgramCounter
		inst := program.At(pc)
		op := OpCode(inst[0]) & 63 // 63 = 00111111
		if !isMem(op) {
			param1 := inst[0]>>6 | inst[1]<<2&63
			param2 := inst[1]>>4 | inst[2]<<4&63
			param3 := inst[2] >> 2

			if cu.data.Verbose {
				fmt.Printf("Run() PC: %3d  IS: %5s  P1: %d  P2: %d  P3: %d\n", cu.ProgramCounter, op.String(), param1, param2, param3) // debug
			}
			cu.Execute(op, []byte{param1, param2, param3})
			if cu.data.Verbose {
				cu.data.PrintMachine() // debug
			}
		} else {
			param := inst[0]>>6 | inst[1]<<2&63
			memParam := uint16(inst[1]>>4) | uint16(inst[2])<<4
			if cu.data.Verbose {
				fmt.Printf("Run() PC: %3d  IS: %5s  P: %d  MP: %d\n", cu.ProgramCounter, op.String(), param, memParam) // debug
			}
			cu.ExecuteMem(op, param, memParam)
			if cu.data.Verbose {
				cu.data.PrintMachine() // debug
			}
		}
		cu.ProgramCounter++
	}
	return nil
}

func (cu *ControlUnit24bit) Run(file string) error {
	program, err := LoadProgram24bit(file)
	if err != nil {
		return err
	}
	return cu.RunProgram(program)
}

func (cu *ControlUnit24bit) ExecuteMem(op OpCode, param byte, memParam uint16) {
	switch op {
	case isLdx:
		cu.Ldx(param, memParam)
	case isStx:
		cu.Stx(param, memParam)
	case isCload:
		cu.Cload(memParam)
	case isCstore:
		cu.Cstore(memParam)
	}
}

/// @param params must have as many members as the instruction takes parameters
func (cu *ControlUnit24bit) Execute(instruction OpCode, params []byte) {
	switch instruction {
	case isLdxi:
		cu.Ldxi(params[0], params[1])
	case isIncx:
		cu.Incx(params[0], params[1])
	case isDecx:
		cu.Decx(params[0], params[1])
	case isMulx:
		cu.Mulx(params[0], params[1])
	case isCmpx:
		cu.Cmpx(params[0], params[1], params[2])
	case isCbcast:
		cu.Cbcast()
	case isLod:
		cu.Lod(params[0], params[1])
	case isSto:
		cu.Sto(params[0], params[1])
	case isAdd:
		cu.Add(params[0], params[1])
	case isSub:
		cu.Sub(params[0], params[1])
	case isMul:
		cu.Mul(params[0], params[1])
	case isDiv:
		cu.Div(params[0], params[1])
	case isBcast:
		cu.Bcast(params[0])
	case isMov:
		cu.Mov(RegisterType(params[0]), RegisterType(params[1])) ///< @todo change to be multiple 'instructions' ?
	case isRadd:
		cu.Radd()
	case isRsub:
		cu.Rsub()
	case isRmul:
		cu.Rmul()
	case isRdiv:
		cu.Rdiv()
	}
}

//
// control instructions
//
func (cu *ControlUnit24bit) Ldx(index byte, a uint16) {
	//	fmt.Printf("ldx: cu.data.index[%d] = cu.data.Memory[%d] (%d)"
	cu.data.IndexRegister[index] = cu.data.Memory[a]
}
func (cu *ControlUnit24bit) Stx(index byte, a uint16) {
//	fmt.Println("debug: stx " + strconv.Itoa(int(index)) + " into " + strconv.Itoa(int(a)))
	cu.data.Memory[a] = cu.data.IndexRegister[index]
}
func (cu *ControlUnit24bit) Ldxi(index byte, a byte) {
	cu.data.IndexRegister[index] = int64(a)
}
func (cu *ControlUnit24bit) Incx(index byte, a byte) {
	cu.data.IndexRegister[index] += int64(a)
}
func (cu *ControlUnit24bit) Decx(index byte, a byte) {
	cu.data.IndexRegister[index] -= int64(a)
}
func (cu *ControlUnit24bit) Mulx(index byte, a byte) {
	cu.data.IndexRegister[index] *= int64(a)
}
func (cu *ControlUnit24bit) Cload(index uint16) {
//	fmt.Println("debug: cload " + strconv.Itoa(int(index)));
	cu.data.ArithmeticRegister = cu.data.Memory[index]
}
func (cu *ControlUnit24bit) Cstore(index uint16) {
	cu.data.Memory[index] = cu.data.ArithmeticRegister
}

/// @todo fix this to take a larger jump (a). Byte only allows for 256 instructions. That's not a very big program
func (cu *ControlUnit24bit) Cmpx(index byte, ix2 byte, a byte) {
	if cu.data.IndexRegister[index] < cu.data.IndexRegister[ix2] {
		cu.ProgramCounter = int64(a) - 1 // -1 because the PC will be incremented.
	}
}

// control broadcast. Broadcasts the Control's Arithmetic Register to every PE's Routing Register
func (cu *ControlUnit24bit) Cbcast() {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].RoutingRegister = cu.data.ArithmeticRegister
	}
}

// Block until all PE's are done
func (cu *ControlUnit24bit) Barrier() {
	for i := 0; i != len(cu.data.PE); i++ {
		<-cu.data.Done
	}
}

//
// vector instructions
//
func (cu *ControlUnit24bit) Lod(a byte, idx byte) {
	//	fmt.Printf("PE-Lod %d + %d (%d)\n", a, cu.data.IndexRegister[idx], idx)
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Lod <- ByteTuple{a, byte(cu.data.IndexRegister[idx])} ///< @todo is this ok? Should we be loading the index register somewhere else?
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Sto(a byte, idx byte) {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Sto <- ByteTuple{a, byte(cu.data.IndexRegister[idx])}
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Add(a byte, idx byte) {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Add <- ByteTuple{a, byte(cu.data.IndexRegister[idx])}
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Sub(a byte, idx byte) {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Sub <- ByteTuple{a, byte(cu.data.IndexRegister[idx])}
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Mul(a byte, idx byte) {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Mul <- ByteTuple{a, byte(cu.data.IndexRegister[idx])}
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Div(a byte, idx byte) {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Div <- ByteTuple{a, byte(cu.data.IndexRegister[idx])}
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Bcast(idx byte) {
	idx = byte(cu.data.IndexRegister[idx]) ///< @todo is this ok? Should we be loading the index register here?
	for i, _ := range cu.data.PE {
		if !cu.data.PE[i].Enabled {
			continue
		}
		cu.data.PE[i].RoutingRegister = cu.data.PE[idx].RoutingRegister
	}
}
func (cu *ControlUnit24bit) Mov(from RegisterType, to RegisterType) {
	/// @todo remove this? speed for safety?
	if from == to {
		return
	}
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Mov <- ByteTuple{byte(from), byte(to)}
	}
	cu.Barrier()
}

func (cu *ControlUnit24bit) Radd() {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Radd <- true
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Rsub() {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Rsub <- true
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Rmul() {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Rmul <- true
	}
	cu.Barrier()
}
func (cu *ControlUnit24bit) Rdiv() {
	for i, _ := range cu.data.PE {
		cu.data.PE[i].Rdiv <- true
	}
	cu.Barrier()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"math/big"
	"os"
	"text/tabwriter"

	"github.com/NebulousLabs/Sia/api"
	"github.com/NebulousLabs/Sia/modules"
	"github.com/NebulousLabs/Sia/types"

	"github.com/spf13/cobra"
)

var (
	hostCmd = &cobra.Command{
		Use:   "host",
		Short: "Perform host actions",
		Long:  "View or modify host settings.",
		Run:   wrap(hostcmd),
	}

	hostConfigCmd = &cobra.Command{
		Use:   "config [setting] [value]",
		Short: "Modify host settings",
		Long: `Modify host settings.

Available settings:
     acceptingcontracts:       boolean
     maxduration:              blocks
     maxdownloadbatchsize:     int
     maxrevisebatchsize:       int
     netaddress:               string
     windowsize:               blocks

     collateral:               currency
     collateralbudget:         currency
     maxcollateral:            currency

     mincontractprice:         currency
     mindownloadbandwithprice: currency / TB
     minstorageprice:          currency / TB / Month
     minuploadbandwidthprice:  currency / TB

Currency units can be specified, e.g. 10SC; run 'siac help wallet' for details.

Blocks are approximately 10 minutes each.

For a description of each parameter, see doc/API.md.

To configure the host to accept new contracts, set acceptingcontracts to true:
	siac host config acceptingcontracts true
`,
		Run: wrap(hostconfigcmd),
	}

	hostAnnounceCmd = &cobra.Command{
		Use:   "announce",
		Short: "Announce yourself as a host",
		Long: `Announce yourself as a host on the network.
Announcing will also configure the host to start accepting contracts.
You can revert this by running:
	siac host config acceptingcontracts false
You may also supply a specific address to be announced, e.g.:
	siac host announce my-host-domain.com:9001
Doing so will override the standard connectivity checks.`,
		Run: hostannouncecmd,
	}

	hostFolderCmd = &cobra.Command{
		Use:   "folder",
		Short: "Add, remove, or resize a storage folder",
		Long:  "Add, remove, or resize a storage folder.",
	}

	hostFolderAddCmd = &cobra.Command{
		Use:   "add [path] [size]",
		Short: "Add a storage folder to the host",
		Long:  "Add a storage folder to the host, specifying how much data it should store",
		Run:   wrap(hostfolderaddcmd),
	}

	hostFolderRemoveCmd = &cobra.Command{
		Use:   "remove [path]",
		Short: "Remove a storage folder from the host",
		Long: `Remove a storage folder from the host. Note that this does not delete any
data; it will instead be distributed across the remaining storage folders.`,

		Run: wrap(hostfolderremovecmd),
	}

	hostFolderResizeCmd = &cobra.Command{
		Use:   "resize [path] [size]",
		Short: "Resize a storage folder",
		Long: `Change how much data a storage folder should store. If the new size is less
than what the folder is currently storing, data will be distributed across the
other storage folders.`,
		Run: wrap(hostfolderresizecmd),
	}

	hostSectorCmd = &cobra.Command{
		Use:   "sector",
		Short: "Add or delete a sector (add not supported)",
		Long: `Add or delete a sector. Adding is not currently supported. Note that
deleting a sector may impact host revenue.`,
	}

	hostSectorDeleteCmd = &cobra.Command{
		Use:   "delete [root]",
		Short: "Delete a sector",
		Long: `Delete a sector, identified by its Merkle root. Note that deleting a
sector may impact host revenue.`,
		Run: wrap(hostsectordeletecmd),
	}
)

// hostcmd is the handler for the command `siac host`.
// Prints info about the host and its storage folders.
func hostcmd() {
	hg := new(api.HostGET)
	err := getAPI("/host", hg)
	if err != nil {
		die("Could not fetch host settings:", err)
	}
	sg := new(api.StorageGET)
	err = getAPI("/host/storage", sg)
	if err != nil {
		die("Could not fetch storage info:", err)
	}

	// Determine the competitive price string.
	ah := new(api.ActiveHosts)
	var competitivePrice string
	err = getAPI("/hostdb/active?numhosts=24", ah)
	if err != nil || len(ah.Hosts) == 0 {
		competitivePrice = "Unavailable"
	} else {
		var sum types.Currency
		for _, host := range ah.Hosts {
			sum = sum.Add(host.StoragePrice)
		}

		// Divide by the number of hosts to get the average price, and then
		// trim 5% to present what would be a competitive edge.
		competitivePrice = currencyUnits(sum.Div64(uint64(len(ah.Hosts))).MulFloat(0.95).Mul(modules.BlockBytesPerMonthTerabyte))
	}

	es := hg.ExternalSettings
	fm := hg.FinancialMetrics
	is := hg.InternalSettings
	nm := hg.NetworkMetrics

	// calculate total storage available and remaining
	var totalstorage, storageremaining uint64
	for _, folder := range sg.Folders {
		totalstorage += folder.Capacity
		storageremaining += folder.CapacityRemaining
	}

	// convert price from bytes/block to TB/Month
	price := currencyUnits(is.MinStoragePrice.Mul(modules.BlockBytesPerMonthTerabyte))
	// calculate total revenue
	totalRevenue := fm.ContractCompensation.
		Add(fm.StorageRevenue).
		Add(fm.DownloadBandwidthRevenue).
		Add(fm.UploadBandwidthRevenue)
	totalPotentialRevenue := fm.PotentialContractCompensation.
		Add(fm.PotentialStorageRevenue).
		Add(fm.PotentialDownloadBandwidthRevenue).
		Add(fm.PotentialUploadBandwidthRevenue)
	// determine the display method for the net address.
	netaddr := es.NetAddress
	if is.NetAddress == "" {
		netaddr += " (automatically determined)"
	} else {
		netaddr += " (manually specified)"
	}

	if hostVerbose {
		// describe net address
		fmt.Printf(`General Info:
	Estimated Comptetitive Price: %v

Host Internal Settings:
	acceptingcontracts:   %v
	maxduration:          %v Weeks
	maxdownloadbatchsize: %v
	maxrevisebatchsize:   %v
	netaddress:           %v
	windowsize:           %v Weeks

	collateral:       %v / TB / Month
	collateralbudget: %v
	maxcollateral:    %v Per Contract

	mincontractprice:         %v
	mindownloadbandwithprice: %v / TB
	minstorageprice:          %v / TB / Month
	minuploadbandwidthprice:  %v / TB

Host Financials:
	Contract Count:               %v
	Transaction Fee Compensation: %v
	Transaction Fee Expenses:     %v

	Storage Revenue:           %v
	Potential Storage Revenue: %v

	Locked Collateral: %v
	Risked Collateral: %v
	Lost Collateral:   %v

	Download Revenue:           %v
	Potential Download Revenue: %v
	Upload Revenue :            %v
	Potential Upload Revenue:   %v

RPC Stats:
	Error Calls:        %v
	Unrecognized Calls: %v
	Download Calls:     %v
	Renew Calls:        %v
	Revise Calls:       %v
	Settings Calls:     %v
	FormContract Calls: %v
`,
			competitivePrice,

			yesNo(is.AcceptingContracts), periodUnits(is.MaxDuration),
			filesizeUnits(int64(is.MaxDownloadBatchSize)),
			filesizeUnits(int64(is.MaxReviseBatchSize)), netaddr,
			periodUnits(is.WindowSize),

			currencyUnits(is.Collateral.Mul(modules.BlockBytesPerMonthTerabyte)),
			currencyUnits(is.CollateralBudget),
			currencyUnits(is.MaxCollateral),

			currencyUnits(is.MinContractPrice),
			currencyUnits(is.MinDownloadBandwidthPrice.Mul(modules.BytesPerTerabyte)),
			currencyUnits(is.MinStoragePrice.Mul(modules.BlockBytesPerMonthTerabyte)),
			currencyUnits(is.MinUploadBandwidthPrice.Mul(modules.BytesPerTerabyte)),

			fm.ContractCount, currencyUnits(fm.ContractCompensation),
			currencyUnits(fm.TransactionFeeExpenses),

			currencyUnits(fm.StorageRevenue),
			currencyUnits(fm.PotentialStorageRevenue),

			currencyUnits(fm.LockedStorageCollateral),
			currencyUnits(fm.RiskedStorageCollateral),
			currencyUnits(fm.LostStorageCollateral),

			currencyUnits(fm.DownloadBandwidthRevenue),
			currencyUnits(fm.PotentialDownloadBandwidthRevenue),
			currencyUnits(fm.UploadBandwidthRevenue),
			currencyUnits(fm.PotentialUploadBandwidthRevenue),

			nm.ErrorCalls, nm.UnrecognizedCalls, nm.DownloadCalls,
			nm.RenewCalls, nm.ReviseCalls, nm.SettingsCalls,
			nm.FormContractCalls)
	} else {
		fmt.Printf(`Host info:
	Estimated Comptetitive Price: %v

	Storage:      %v (%v used)
	Price:        %v / TB / Month
	Max Duration: %v Weeks

	Accepting Contracts: %v
	Anticipated Revenue: %v
	Locked Collateral:   %v
	Revenue:             %v
`,
			competitivePrice,

			filesizeUnits(int64(totalstorage)),
			filesizeUnits(int64(totalstorage-storageremaining)), price,
			periodUnits(is.MaxDuration),

			yesNo(is.AcceptingContracts), currencyUnits(totalPotentialRevenue),
			currencyUnits(fm.LockedStorageCollateral),
			currencyUnits(totalRevenue))
	}

	fmt.Println("\nStorage Folders:")

	// display storage folder info
	if len(sg.Folders) == 0 {
		fmt.Println("No storage folders configured")
		return
	}
	w := tabwriter.NewWriter(os.Stdout, 0, 0, 4, ' ', 0)
	fmt.Fprintf(w, "\tUsed\tCapacity\t%% Used\tPath\n")
	for _, folder := range sg.Folders {
		curSize := int64(folder.Capacity - folder.CapacityRemaining)
		pctUsed := 100 * (float64(curSize) / float64(folder.Capacity))
		fmt.Fprintf(w, "\t%s\t%s\t%.2f\t%s\n", filesizeUnits(curSize), filesizeUnits(int64(folder.Capacity)), pctUsed, folder.Path)
	}
	w.Flush()
}

// hostconfigcmd is the handler for the command `siac host config [setting] [value]`.
// Modifies host settings.
func hostconfigcmd(param, value string) {
	switch param {
	// currency (convert to hastings)
	case "collateralbudget", "maxcollateral", "mincontractprice":
		hastings, err := parseCurrency(value)
		if err != nil {
			die("Could not parse "+param+":", err)
		}
		value = hastings

	// currency/TB (convert to hastings/byte)
	case "collateral", "mindownloadbandwidthprice", "minuploadbandwidthprice":
		hastings, err := parseCurrency(value)
		if err != nil {
			die("Could not parse "+param+":", err)
		}
		i, _ := new(big.Int).SetString(hastings, 10)
		c := types.NewCurrency(i).Div(modules.BytesPerTerabyte)
		value = c.String()

	// currency/TB/month (convert to hastings/byte/block)
	case "minstorageprice":
		hastings, err := parseCurrency(value)
		if err != nil {
			die("Could not parse "+param+":", err)
		}
		i, _ := new(big.Int).SetString(hastings, 10)
		c := types.NewCurrency(i).Div(modules.BlockBytesPerMonthTerabyte)
		value = c.String()

	// other valid settings
	case "acceptingcontracts", "maxdownloadbatchsize", "maxduration",
		"maxrevisebatchsize", "netaddress", "windowsize":

	// invalid settings
	default:
		die("\"" + param + "\" is not a host setting")
	}
	err := post("/host", param+"="+value)
	if err != nil {
		die("Could not update host settings:", err)
	}
	fmt.Println("Host settings updated.")
}

// hostannouncecmd is the handler for the command `siac host announce`.
// Announces yourself as a host to the network. Optionally takes an address to
// announce as.
func hostannouncecmd(cmd *cobra.Command, args []string) {
	var err error
	switch len(args) {
	case 0:
		err = post("/host/announce", "")
	case 1:
		err = post("/host/announce", "netaddress="+args[0])
	default:
		cmd.Usage()
		os.Exit(exitCodeUsage)
	}
	if err != nil {
		die("Could not announce host:", err)
	}
	fmt.Println("Host announcement submitted to network.")

	// start accepting contracts
	err = post("/host", "acceptingcontracts=true")
	if err != nil {
		die("Could not configure host to accept contracts:", err)
	}
	fmt.Println(`
The host has also been configured to accept contracts.
To revert this, run:
	siac host config acceptingcontracts false
`)
}

// hostfolderaddcmd adds a folder to the host.
func hostfolderaddcmd(path, size string) {
	size, err := parseFilesize(size)
	if err != nil {
		die("Could not parse size:", err)
	}
	err = post("/host/storage/folders/add", fmt.Sprintf("path=%s&size=%s", abs(path), size))
	if err != nil {
		die("Could not add folder:", err)
	}
	fmt.Println("Added folder", path)
}

// hostfolderremovecmd removes a folder from the host.
func hostfolderremovecmd(path string) {
	err := post("/host/storage/folders/remove", "path="+abs(path))
	if err != nil {
		die("Could not remove folder:", err)
	}
	fmt.Println("Removed folder", path)
}

// hostfolderresizecmd resizes a folder in the host.
func hostfolderresizecmd(path, newsize string) {
	newsize, err := parseFilesize(newsize)
	if err != nil {
		die("Could not parse size:", err)
	}
	err = post("/host/storage/folders/resize", fmt.Sprintf("path=%s&newsize=%s", abs(path), newsize))
	if err != nil {
		die("Could not resize folder:", err)
	}
	fmt.Printf("Resized folder %v to %v\n", path, newsize)
}

// hostsectordeletecmd deletes a sector from the host.
func hostsectordeletecmd(root string) {
	err := post("/host/storage/sectors/delete/"+root, "")
	if err != nil {
		die("Could not delete sector:", err)
	}
	fmt.Println("Deleted sector", root)
}
<commit_msg>fix siac spelling mistake<commit_after>package main

import (
	"fmt"
	"math/big"
	"os"
	"text/tabwriter"

	"github.com/NebulousLabs/Sia/api"
	"github.com/NebulousLabs/Sia/modules"
	"github.com/NebulousLabs/Sia/types"

	"github.com/spf13/cobra"
)

var (
	hostCmd = &cobra.Command{
		Use:   "host",
		Short: "Perform host actions",
		Long:  "View or modify host settings.",
		Run:   wrap(hostcmd),
	}

	hostConfigCmd = &cobra.Command{
		Use:   "config [setting] [value]",
		Short: "Modify host settings",
		Long: `Modify host settings.

Available settings:
     acceptingcontracts:       boolean
     maxduration:              blocks
     maxdownloadbatchsize:     int
     maxrevisebatchsize:       int
     netaddress:               string
     windowsize:               blocks

     collateral:               currency
     collateralbudget:         currency
     maxcollateral:            currency

     mincontractprice:         currency
     mindownloadbandwithprice: currency / TB
     minstorageprice:          currency / TB / Month
     minuploadbandwidthprice:  currency / TB

Currency units can be specified, e.g. 10SC; run 'siac help wallet' for details.

Blocks are approximately 10 minutes each.

For a description of each parameter, see doc/API.md.

To configure the host to accept new contracts, set acceptingcontracts to true:
	siac host config acceptingcontracts true
`,
		Run: wrap(hostconfigcmd),
	}

	hostAnnounceCmd = &cobra.Command{
		Use:   "announce",
		Short: "Announce yourself as a host",
		Long: `Announce yourself as a host on the network.
Announcing will also configure the host to start accepting contracts.
You can revert this by running:
	siac host config acceptingcontracts false
You may also supply a specific address to be announced, e.g.:
	siac host announce my-host-domain.com:9001
Doing so will override the standard connectivity checks.`,
		Run: hostannouncecmd,
	}

	hostFolderCmd = &cobra.Command{
		Use:   "folder",
		Short: "Add, remove, or resize a storage folder",
		Long:  "Add, remove, or resize a storage folder.",
	}

	hostFolderAddCmd = &cobra.Command{
		Use:   "add [path] [size]",
		Short: "Add a storage folder to the host",
		Long:  "Add a storage folder to the host, specifying how much data it should store",
		Run:   wrap(hostfolderaddcmd),
	}

	hostFolderRemoveCmd = &cobra.Command{
		Use:   "remove [path]",
		Short: "Remove a storage folder from the host",
		Long: `Remove a storage folder from the host. Note that this does not delete any
data; it will instead be distributed across the remaining storage folders.`,

		Run: wrap(hostfolderremovecmd),
	}

	hostFolderResizeCmd = &cobra.Command{
		Use:   "resize [path] [size]",
		Short: "Resize a storage folder",
		Long: `Change how much data a storage folder should store. If the new size is less
than what the folder is currently storing, data will be distributed across the
other storage folders.`,
		Run: wrap(hostfolderresizecmd),
	}

	hostSectorCmd = &cobra.Command{
		Use:   "sector",
		Short: "Add or delete a sector (add not supported)",
		Long: `Add or delete a sector. Adding is not currently supported. Note that
deleting a sector may impact host revenue.`,
	}

	hostSectorDeleteCmd = &cobra.Command{
		Use:   "delete [root]",
		Short: "Delete a sector",
		Long: `Delete a sector, identified by its Merkle root. Note that deleting a
sector may impact host revenue.`,
		Run: wrap(hostsectordeletecmd),
	}
)

// hostcmd is the handler for the command `siac host`.
// Prints info about the host and its storage folders.
func hostcmd() {
	hg := new(api.HostGET)
	err := getAPI("/host", hg)
	if err != nil {
		die("Could not fetch host settings:", err)
	}
	sg := new(api.StorageGET)
	err = getAPI("/host/storage", sg)
	if err != nil {
		die("Could not fetch storage info:", err)
	}

	// Determine the competitive price string.
	ah := new(api.ActiveHosts)
	var competitivePrice string
	err = getAPI("/hostdb/active?numhosts=24", ah)
	if err != nil || len(ah.Hosts) == 0 {
		competitivePrice = "Unavailable"
	} else {
		var sum types.Currency
		for _, host := range ah.Hosts {
			sum = sum.Add(host.StoragePrice)
		}

		// Divide by the number of hosts to get the average price, and then
		// trim 5% to present what would be a competitive edge.
		competitivePrice = currencyUnits(sum.Div64(uint64(len(ah.Hosts))).MulFloat(0.95).Mul(modules.BlockBytesPerMonthTerabyte))
	}

	es := hg.ExternalSettings
	fm := hg.FinancialMetrics
	is := hg.InternalSettings
	nm := hg.NetworkMetrics

	// calculate total storage available and remaining
	var totalstorage, storageremaining uint64
	for _, folder := range sg.Folders {
		totalstorage += folder.Capacity
		storageremaining += folder.CapacityRemaining
	}

	// convert price from bytes/block to TB/Month
	price := currencyUnits(is.MinStoragePrice.Mul(modules.BlockBytesPerMonthTerabyte))
	// calculate total revenue
	totalRevenue := fm.ContractCompensation.
		Add(fm.StorageRevenue).
		Add(fm.DownloadBandwidthRevenue).
		Add(fm.UploadBandwidthRevenue)
	totalPotentialRevenue := fm.PotentialContractCompensation.
		Add(fm.PotentialStorageRevenue).
		Add(fm.PotentialDownloadBandwidthRevenue).
		Add(fm.PotentialUploadBandwidthRevenue)
	// determine the display method for the net address.
	netaddr := es.NetAddress
	if is.NetAddress == "" {
		netaddr += " (automatically determined)"
	} else {
		netaddr += " (manually specified)"
	}

	if hostVerbose {
		// describe net address
		fmt.Printf(`General Info:
	Estimated Competitive Price: %v

Host Internal Settings:
	acceptingcontracts:   %v
	maxduration:          %v Weeks
	maxdownloadbatchsize: %v
	maxrevisebatchsize:   %v
	netaddress:           %v
	windowsize:           %v Weeks

	collateral:       %v / TB / Month
	collateralbudget: %v
	maxcollateral:    %v Per Contract

	mincontractprice:         %v
	mindownloadbandwithprice: %v / TB
	minstorageprice:          %v / TB / Month
	minuploadbandwidthprice:  %v / TB

Host Financials:
	Contract Count:               %v
	Transaction Fee Compensation: %v
	Transaction Fee Expenses:     %v

	Storage Revenue:           %v
	Potential Storage Revenue: %v

	Locked Collateral: %v
	Risked Collateral: %v
	Lost Collateral:   %v

	Download Revenue:           %v
	Potential Download Revenue: %v
	Upload Revenue :            %v
	Potential Upload Revenue:   %v

RPC Stats:
	Error Calls:        %v
	Unrecognized Calls: %v
	Download Calls:     %v
	Renew Calls:        %v
	Revise Calls:       %v
	Settings Calls:     %v
	FormContract Calls: %v
`,
			competitivePrice,

			yesNo(is.AcceptingContracts), periodUnits(is.MaxDuration),
			filesizeUnits(int64(is.MaxDownloadBatchSize)),
			filesizeUnits(int64(is.MaxReviseBatchSize)), netaddr,
			periodUnits(is.WindowSize),

			currencyUnits(is.Collateral.Mul(modules.BlockBytesPerMonthTerabyte)),
			currencyUnits(is.CollateralBudget),
			currencyUnits(is.MaxCollateral),

			currencyUnits(is.MinContractPrice),
			currencyUnits(is.MinDownloadBandwidthPrice.Mul(modules.BytesPerTerabyte)),
			currencyUnits(is.MinStoragePrice.Mul(modules.BlockBytesPerMonthTerabyte)),
			currencyUnits(is.MinUploadBandwidthPrice.Mul(modules.BytesPerTerabyte)),

			fm.ContractCount, currencyUnits(fm.ContractCompensation),
			currencyUnits(fm.TransactionFeeExpenses),

			currencyUnits(fm.StorageRevenue),
			currencyUnits(fm.PotentialStorageRevenue),

			currencyUnits(fm.LockedStorageCollateral),
			currencyUnits(fm.RiskedStorageCollateral),
			currencyUnits(fm.LostStorageCollateral),

			currencyUnits(fm.DownloadBandwidthRevenue),
			currencyUnits(fm.PotentialDownloadBandwidthRevenue),
			currencyUnits(fm.UploadBandwidthRevenue),
			currencyUnits(fm.PotentialUploadBandwidthRevenue),

			nm.ErrorCalls, nm.UnrecognizedCalls, nm.DownloadCalls,
			nm.RenewCalls, nm.ReviseCalls, nm.SettingsCalls,
			nm.FormContractCalls)
	} else {
		fmt.Printf(`Host info:
	Estimated Competitive Price: %v

	Storage:      %v (%v used)
	Price:        %v / TB / Month
	Max Duration: %v Weeks

	Accepting Contracts: %v
	Anticipated Revenue: %v
	Locked Collateral:   %v
	Revenue:             %v
`,
			competitivePrice,

			filesizeUnits(int64(totalstorage)),
			filesizeUnits(int64(totalstorage-storageremaining)), price,
			periodUnits(is.MaxDuration),

			yesNo(is.AcceptingContracts), currencyUnits(totalPotentialRevenue),
			currencyUnits(fm.LockedStorageCollateral),
			currencyUnits(totalRevenue))
	}

	fmt.Println("\nStorage Folders:")

	// display storage folder info
	if len(sg.Folders) == 0 {
		fmt.Println("No storage folders configured")
		return
	}
	w := tabwriter.NewWriter(os.Stdout, 0, 0, 4, ' ', 0)
	fmt.Fprintf(w, "\tUsed\tCapacity\t%% Used\tPath\n")
	for _, folder := range sg.Folders {
		curSize := int64(folder.Capacity - folder.CapacityRemaining)
		pctUsed := 100 * (float64(curSize) / float64(folder.Capacity))
		fmt.Fprintf(w, "\t%s\t%s\t%.2f\t%s\n", filesizeUnits(curSize), filesizeUnits(int64(folder.Capacity)), pctUsed, folder.Path)
	}
	w.Flush()
}

// hostconfigcmd is the handler for the command `siac host config [setting] [value]`.
// Modifies host settings.
func hostconfigcmd(param, value string) {
	switch param {
	// currency (convert to hastings)
	case "collateralbudget", "maxcollateral", "mincontractprice":
		hastings, err := parseCurrency(value)
		if err != nil {
			die("Could not parse "+param+":", err)
		}
		value = hastings

	// currency/TB (convert to hastings/byte)
	case "collateral", "mindownloadbandwidthprice", "minuploadbandwidthprice":
		hastings, err := parseCurrency(value)
		if err != nil {
			die("Could not parse "+param+":", err)
		}
		i, _ := new(big.Int).SetString(hastings, 10)
		c := types.NewCurrency(i).Div(modules.BytesPerTerabyte)
		value = c.String()

	// currency/TB/month (convert to hastings/byte/block)
	case "minstorageprice":
		hastings, err := parseCurrency(value)
		if err != nil {
			die("Could not parse "+param+":", err)
		}
		i, _ := new(big.Int).SetString(hastings, 10)
		c := types.NewCurrency(i).Div(modules.BlockBytesPerMonthTerabyte)
		value = c.String()

	// other valid settings
	case "acceptingcontracts", "maxdownloadbatchsize", "maxduration",
		"maxrevisebatchsize", "netaddress", "windowsize":

	// invalid settings
	default:
		die("\"" + param + "\" is not a host setting")
	}
	err := post("/host", param+"="+value)
	if err != nil {
		die("Could not update host settings:", err)
	}
	fmt.Println("Host settings updated.")
}

// hostannouncecmd is the handler for the command `siac host announce`.
// Announces yourself as a host to the network. Optionally takes an address to
// announce as.
func hostannouncecmd(cmd *cobra.Command, args []string) {
	var err error
	switch len(args) {
	case 0:
		err = post("/host/announce", "")
	case 1:
		err = post("/host/announce", "netaddress="+args[0])
	default:
		cmd.Usage()
		os.Exit(exitCodeUsage)
	}
	if err != nil {
		die("Could not announce host:", err)
	}
	fmt.Println("Host announcement submitted to network.")

	// start accepting contracts
	err = post("/host", "acceptingcontracts=true")
	if err != nil {
		die("Could not configure host to accept contracts:", err)
	}
	fmt.Println(`
The host has also been configured to accept contracts.
To revert this, run:
	siac host config acceptingcontracts false
`)
}

// hostfolderaddcmd adds a folder to the host.
func hostfolderaddcmd(path, size string) {
	size, err := parseFilesize(size)
	if err != nil {
		die("Could not parse size:", err)
	}
	err = post("/host/storage/folders/add", fmt.Sprintf("path=%s&size=%s", abs(path), size))
	if err != nil {
		die("Could not add folder:", err)
	}
	fmt.Println("Added folder", path)
}

// hostfolderremovecmd removes a folder from the host.
func hostfolderremovecmd(path string) {
	err := post("/host/storage/folders/remove", "path="+abs(path))
	if err != nil {
		die("Could not remove folder:", err)
	}
	fmt.Println("Removed folder", path)
}

// hostfolderresizecmd resizes a folder in the host.
func hostfolderresizecmd(path, newsize string) {
	newsize, err := parseFilesize(newsize)
	if err != nil {
		die("Could not parse size:", err)
	}
	err = post("/host/storage/folders/resize", fmt.Sprintf("path=%s&newsize=%s", abs(path), newsize))
	if err != nil {
		die("Could not resize folder:", err)
	}
	fmt.Printf("Resized folder %v to %v\n", path, newsize)
}

// hostsectordeletecmd deletes a sector from the host.
func hostsectordeletecmd(root string) {
	err := post("/host/storage/sectors/delete/"+root, "")
	if err != nil {
		die("Could not delete sector:", err)
	}
	fmt.Println("Deleted sector", root)
}
<|endoftext|>