<commit_before>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/

package main

import (
	"errors"
	"fmt"
	"strconv"

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Printf("Init called, initializing chaincode")

	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var err error

	if len(args) != 4 {
		return nil, errors.New("Incorrect number of arguments. Expecting 4")
	}

	// Initialize the chaincode
	A = args[0]
	Aval, err = strconv.Atoi(args[1])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	B = args[2]
	Bval, err = strconv.Atoi(args[3])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Transaction makes payment of X units from A to B but 2 times the value
func (t *SimpleChaincode) invoke2(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	fmt.Printf("Running invoke2")

	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var X int          // Transaction value
	var err error

	if len(args) != 3 {
		return nil, errors.New("Incorrect number of arguments. Expecting 3")
	}

	A = args[0]
	B = args[1]

	// Get the state from the ledger
	// TODO: will be nice to have a GetAllState call to ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Avalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Aval, _ = strconv.Atoi(string(Avalbytes))

	Bvalbytes, err := stub.GetState(B)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Bvalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Bval, _ = strconv.Atoi(string(Bvalbytes))

	// Perform the execution
	X, err = strconv.Atoi(args[2])
	Aval = Aval - X - X
	Bval = Bval + X + X
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state back to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Transaction makes payment of X units from A to B
func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	fmt.Printf("Running invoke")

	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var X int          // Transaction value
	var err error

	if len(args) != 3 {
		return nil, errors.New("Incorrect number of arguments. Expecting 3")
	}

	A = args[0]
	B = args[1]

	// Get the state from the ledger
	// TODO: will be nice to have a GetAllState call to ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Avalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Aval, _ = strconv.Atoi(string(Avalbytes))

	Bvalbytes, err := stub.GetState(B)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Bvalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Bval, _ = strconv.Atoi(string(Bvalbytes))

	// Perform the execution
	X, err = strconv.Atoi(args[2])
	Aval = Aval - X
	Bval = Bval + X
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state back to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	fmt.Printf("Running delete")

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 3")
	}

	A := args[0]

	// Delete the key from the state in ledger
	err := stub.DelState(A)
	if err != nil {
		return nil, errors.New("Failed to delete state")
	}

	return nil, nil
}

// Invoke callback representing the invocation of a chaincode
// This chaincode will manage two accounts A and B and will transfer X units from A to B upon invoke
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Printf("Invoke called, determining function")

	// Handle different functions
	if function == "invoke" {
		// Transaction makes payment of X units from A to B
		fmt.Printf("Function is invoke")
		return t.invoke(stub, args)
	} else if function == "init" {
		fmt.Printf("Function is init")
		return t.Init(stub, function, args)
	} else if function == "invoke2" {
		fmt.Printf("Function is invoke2")
		return t.invoke2(stub, args)
	} else if function == "delete" {
		// Deletes an entity from its state
		fmt.Printf("Function is delete")
		return t.delete(stub, args)
	}

	return nil, errors.New("Received unknown function invocation")
}

func (t* SimpleChaincode) Run(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Printf("Run called, passing through to Invoke (same function)")

	// Handle different functions
	if function == "invoke" {
		// Transaction makes payment of X units from A to B
		fmt.Printf("Function is invoke")
		return t.invoke(stub, args)
	} else if function == "invoke2" {
		fmt.Printf("Function is invoke2")
		return t.invoke2(stub, args)
	} else if function == "init" {
		fmt.Printf("Function is init")
		return t.Init(stub, function, args)
	} else if function == "delete" {
		// Deletes an entity from its state
		fmt.Printf("Function is delete")
		return t.delete(stub, args)
	}

	return nil, errors.New("Received unknown function invocation")
}

// Query callback representing the query of a chaincode
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Printf("Query called, determining function")

	if function != "query" {
		fmt.Printf("Function is query")
		return nil, errors.New("Invalid query function name. Expecting \"query\"")
	}
	var A string // Entities
	var err error

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the person to query")
	}

	A = args[0]

	// Get the state from the ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	if Avalbytes == nil {
		jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)
	return Avalbytes, nil
}

func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}
<commit_msg>POC_1<commit_after>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/

package main

import (
	"errors"
	"fmt"
	"strconv"

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

//iQOS Changes starts ----------------------------------------------------------------
// Assembly comprises of one Serial ID and multiple Batch IDs
type AssemblyLine struct{
	AssemblyId string `json:"assemblyId"`
	SerialId string `json:"serialId"`
	OriginalFilamentBatchId string `json:"originalFilamentBatchId"`
	OriginalLedBatchId string `json:"originalLedBatchId"`
	OriginalCircuitBoardBatchId string `json:"originalCircuitBoardBatchId"`
	OriginalWireBatchId string `json:"originalWireBatchId"`
	OriginalCasingBatchId string `json:"originalCasingBatchId"`
	OriginalAdaptorBatchId string `json:"originalAdaptorBatchId"`
	OriginalStickPodBatchId string `json:"originalStickPodBatchId"`
	AssemblyStatus string `json:"assemblyStatus"`
	}

// GetAssemblyLineStatus is for storing retreived Assembly Line Status
type GetAssemblyLineStatus struct{
	AssemblyLineStatus string `json:"assemblyLineStatus"`
}
//iQOS Changes ends ----------------------------------------------------------------

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Printf("Init called, initializing chaincode")

	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var err error
    var err1 error

	if len(args) != 4 {
		return nil, errors.New("Incorrect number of arguments. Expecting 4")
	}

	// Initialize the chaincode
	A = args[0]
	Aval, err = strconv.Atoi(args[1])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	B = args[2]
	Bval, err = strconv.Atoi(args[3])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}

	//iQOS Changes starts ---------------------------------------------------------------------
	/*
	// Check if table already exists
	_, err1 := stub.GetTable("AssemblyLine")
	if err1 == nil {
		// Table already exists; do not recreate
		return nil, nil
	}
*/
	// Create application Table
	err1 = stub.CreateTable("AssemblyLine", []*shim.ColumnDefinition{
		&shim.ColumnDefinition{Name: "assemblyId", Type: shim.ColumnDefinition_STRING, Key: true},
		&shim.ColumnDefinition{Name: "serialId", Type: shim.ColumnDefinition_STRING, Key: false},
		&shim.ColumnDefinition{Name: "originalFilamentBatchId", Type: shim.ColumnDefinition_STRING, Key: false},
		&shim.ColumnDefinition{Name: "originalLedBatchId", Type: shim.ColumnDefinition_STRING, Key: false},
		&shim.ColumnDefinition{Name: "originalCircuitBoardBatchId", Type: shim.ColumnDefinition_STRING, Key: false},
		&shim.ColumnDefinition{Name: "originalWireBatchId", Type: shim.ColumnDefinition_STRING, Key: false},
		&shim.ColumnDefinition{Name: "originalCasingBatchId", Type: shim.ColumnDefinition_STRING, Key: false},
		&shim.ColumnDefinition{Name: "originalAdaptorBatchId", Type: shim.ColumnDefinition_STRING, Key: false},
		&shim.ColumnDefinition{Name: "originalStickPodBatchId", Type: shim.ColumnDefinition_STRING, Key: false},
		&shim.ColumnDefinition{Name: "assemblyStatus", Type: shim.ColumnDefinition_STRING, Key: false},

	})
	if err1 != nil {
		return nil, errors.New("Failed creating AssemblyLine.")
	}
//iQOS Changes ends ---------------------------------------------------------------------

	return nil, nil
}

// Transaction makes payment of X units from A to B but 2 times the value
func (t *SimpleChaincode) invoke2(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	fmt.Printf("Running invoke2")

	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var X int          // Transaction value
	var err error

	if len(args) != 3 {
		return nil, errors.New("Incorrect number of arguments. Expecting 3")
	}

	A = args[0]
	B = args[1]

	// Get the state from the ledger
	// TODO: will be nice to have a GetAllState call to ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Avalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Aval, _ = strconv.Atoi(string(Avalbytes))

	Bvalbytes, err := stub.GetState(B)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Bvalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Bval, _ = strconv.Atoi(string(Bvalbytes))

	// Perform the execution
	X, err = strconv.Atoi(args[2])
	Aval = Aval - X - X
	Bval = Bval + X + X
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state back to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Transaction makes payment of X units from A to B
func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	fmt.Printf("Running invoke")

	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var X int          // Transaction value
	var err error

	if len(args) != 3 {
		return nil, errors.New("Incorrect number of arguments. Expecting 3")
	}

	A = args[0]
	B = args[1]

	// Get the state from the ledger
	// TODO: will be nice to have a GetAllState call to ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Avalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Aval, _ = strconv.Atoi(string(Avalbytes))

	Bvalbytes, err := stub.GetState(B)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Bvalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Bval, _ = strconv.Atoi(string(Bvalbytes))

	// Perform the execution
	X, err = strconv.Atoi(args[2])
	Aval = Aval - X
	Bval = Bval + X
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state back to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	fmt.Printf("Running delete")

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 3")
	}

	A := args[0]

	// Delete the key from the state in ledger
	err := stub.DelState(A)
	if err != nil {
		return nil, errors.New("Failed to delete state")
	}

	return nil, nil
}

//iQOS Changes starts---------------------------------------------------------------------
//registerUser to register a user
func (t *SimpleChaincode) startAssemblyLine(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {

if len(args) != 9 {
			return nil, fmt.Errorf("Incorrect number of arguments. Expecting 9. Got: %d.", len(args))
		}

		assemblyId:=args[0]
		serialId:=args[1]
		originalFilamentBatchId:=args[2]
		originalLedBatchId:=args[3]
		originalCircuitBoardBatchId:=args[4]
		originalWireBatchId:=args[5]
		originalCasingBatchId:=args[6]
		originalAdaptorBatchId:=args[7]
		originalStickPodBatchId:=args[8]
		assemblyStatus:= "InProgress"

		// Insert a row
		ok, err := stub.InsertRow("AssemblyLine", shim.Row{
			Columns: []*shim.Column{
				&shim.Column{Value: &shim.Column_String_{String_: assemblyId}},
				&shim.Column{Value: &shim.Column_String_{String_: serialId}},
				&shim.Column{Value: &shim.Column_String_{String_: originalFilamentBatchId}},
				&shim.Column{Value: &shim.Column_String_{String_: originalLedBatchId}},
				&shim.Column{Value: &shim.Column_String_{String_: originalCircuitBoardBatchId}},
				&shim.Column{Value: &shim.Column_String_{String_: originalWireBatchId}},
				&shim.Column{Value: &shim.Column_String_{String_: originalCasingBatchId}},
				&shim.Column{Value: &shim.Column_String_{String_: originalAdaptorBatchId}},
				&shim.Column{Value: &shim.Column_String_{String_: originalStickPodBatchId}},
				&shim.Column{Value: &shim.Column_String_{String_: assemblyStatus}},
			}})

		if err != nil {
			return nil, err
		}
		if !ok && err == nil {
			return nil, errors.New("Row already exists.")
		}

		return nil, nil

}
//iQOS Changes ends---------------------------------------------------------------------

// Invoke callback representing the invocation of a chaincode
// This chaincode will manage two accounts A and B and will transfer X units from A to B upon invoke
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Printf("Invoke called, determining function")

	// Handle different functions
	if function == "invoke" {
		// Transaction makes payment of X units from A to B
		fmt.Printf("Function is invoke")
		return t.invoke(stub, args)
	} else if function == "init" {
		fmt.Printf("Function is init")
		return t.Init(stub, function, args)
	} else if function == "invoke2" {
		fmt.Printf("Function is invoke2")
		return t.invoke2(stub, args)
	} else if function == "startAssemblyLine" {
		fmt.Printf("Function is startAssemblyLine")
		return t.startAssemblyLine(stub, args)
	} else if function == "delete" {
		// Deletes an entity from its state
		fmt.Printf("Function is delete")
		return t.delete(stub, args)
	} else if function == "startAssemblyLine" {
		// Deletes an entity from its state
		fmt.Printf("Function is startAssemblyLine")
		return t.startAssemblyLine(stub, args)
	}

	return nil, errors.New("Received unknown function invocation")
}

func (t* SimpleChaincode) Run(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Printf("Run called, passing through to Invoke (same function)")

	// Handle different functions
	if function == "invoke" {
		// Transaction makes payment of X units from A to B
		fmt.Printf("Function is invoke")
		return t.invoke(stub, args)
	} else if function == "invoke2" {
		fmt.Printf("Function is invoke2")
		return t.invoke2(stub, args)
	} else if function == "startAssemblyLine" {
		fmt.Printf("Function is startAssemblyLine")
		return t.startAssemblyLine(stub, args)
	} else if function == "init" {
		fmt.Printf("Function is init")
		return t.Init(stub, function, args)
	} else if function == "delete" {
		// Deletes an entity from its state
		fmt.Printf("Function is delete")
		return t.delete(stub, args)
	}else if function == "startAssemblyLine" {
		// Deletes an entity from its state
		fmt.Printf("Function is startAssemblyLine")
		return t.startAssemblyLine(stub, args)
	}

	return nil, errors.New("Received unknown function invocation")
}

//iQOS Changes starts------------------------------------------------------------------------------------------
// Query to get Value of A/B
func (t *SimpleChaincode) getValue(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {

	var A string // Entities
	var err error

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the person to query")
	}

	A = args[0]

	// Get the state from the ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	if Avalbytes == nil {
		jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)
	return Avalbytes, nil
}

//get the status against the AssemblyID
func (t *SimpleChaincode) getAssemblyLineStatus(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting AssemblyID to query")
	}

	assemblyID := args[0]

	// Get the row pertaining to this assemblyID
	var columns []shim.Column
	col1 := shim.Column{Value: &shim.Column_String_{String_: assemblyID}}
	columns = append(columns, col1)

	row, err := stub.GetRow("AssemblyLine", columns)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get the data for the assemblyID " + assemblyID + "\"}"
		return nil, errors.New(jsonResp)
	}

	// GetRows returns empty message if key does not exist
	if len(row.Columns) == 0 {
		jsonResp := "{\"Error\":\"Failed to get the data for the assemblyID " + assemblyID + "\"}"
		return nil, errors.New(jsonResp)
	}

	res2E := GetAssemblyLineStatus{}

	res2E.AssemblyLineStatus = row.Columns[9].GetString_()

    //mapB, _ := json.Marshal(res2E)
    //fmt.Println(string(mapB))

	//return mapB, nil
	return []byte (res2E.AssemblyLineStatus), nil

}

// query queries the chaincode
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Printf("Query called, determining function")

	if function == "getValue" {
		t := SimpleChaincode{}
		return t.getValue(stub, args)
	} else if function == "getAssemblyLineStatus" {
		t := SimpleChaincode{}
		return t.getAssemblyLineStatus(stub, args)
	}

	return nil, nil
}
//iQOS Changes ends------------------------------------------------------------------------------------------

func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}
<|endoftext|>


<commit_before>package mtr

import (
	"fmt"
	"golang.org/x/net/icmp"
	"golang.org/x/net/ipv4"
	"net"
	"os"
	"syscall"
	"time"
)

func Icmp(localAddr string, dst net.Addr, ttl, pid int, timeout time.Duration) (hop TracerouteReturn, err error) {
	hop.Success = false
	start := time.Now()
	c, err := icmp.ListenPacket("ip4:icmp", localAddr)
	if err != nil {
		return hop, err
	}
	defer c.Close()
	c.IPv4PacketConn().SetTTL(ttl)
	c.SetDeadline(time.Now().Add(timeout))
	wm := icmp.Message{
		Type: ipv4.ICMPTypeEcho, Code: 0,
		Body: &icmp.Echo{
			ID: pid, Seq: 1,
			Data: []byte(""),
		},
	}
	wb, err := wm.Marshal(nil)
	if err != nil {
		return hop, err
	}

	if _, err := c.WriteTo(wb, dst); err != nil {
		return hop, err
	}

	rb := make([]byte, 1500)
	_, peer, err := c.ReadFrom(rb)
	if err != nil {
		return hop, err
	}
	elapsed := time.Since(start)
	hop.Elapsed = elapsed
	hop.Addr = peer.String()
	hop.Success = true
	return hop, err
}

func IcmpWrapper(localAddr, destAddr [4]byte, ttl, port int, tv syscall.Timeval, p []byte) (hop TracerouteReturn, err error) {
	ipAddr := net.IPAddr{IP: net.ParseIP(AddressString(destAddr))}
	timeout := time.Duration(tv.Nano()/(1000*1000)) * time.Millisecond
	pid := os.Getpid() & 0xffff
	return Icmp(AddressString(localAddr), &ipAddr, ttl, pid, timeout)
}
<commit_msg>remove fmt<commit_after>package mtr

import (
	"golang.org/x/net/icmp"
	"golang.org/x/net/ipv4"
	"net"
	"os"
	"syscall"
	"time"
)

func Icmp(localAddr string, dst net.Addr, ttl, pid int, timeout time.Duration) (hop TracerouteReturn, err error) {
	hop.Success = false
	start := time.Now()
	c, err := icmp.ListenPacket("ip4:icmp", localAddr)
	if err != nil {
		return hop, err
	}
	defer c.Close()
	c.IPv4PacketConn().SetTTL(ttl)
	c.SetDeadline(time.Now().Add(timeout))
	wm := icmp.Message{
		Type: ipv4.ICMPTypeEcho, Code: 0,
		Body: &icmp.Echo{
			ID: pid, Seq: 1,
			Data: []byte(""),
		},
	}
	wb, err := wm.Marshal(nil)
	if err != nil {
		return hop, err
	}

	if _, err := c.WriteTo(wb, dst); err != nil {
		return hop, err
	}

	rb := make([]byte, 1500)
	_, peer, err := c.ReadFrom(rb)
	if err != nil {
		return hop, err
	}
	elapsed := time.Since(start)
	hop.Elapsed = elapsed
	hop.Addr = peer.String()
	hop.Success = true
	return hop, err
}

func IcmpWrapper(localAddr, destAddr [4]byte, ttl, port int, tv syscall.Timeval, p []byte) (hop TracerouteReturn, err error) {
	ipAddr := net.IPAddr{IP: net.ParseIP(AddressString(destAddr))}
	timeout := time.Duration(tv.Nano()/(1000*1000)) * time.Millisecond
	pid := os.Getpid() & 0xffff
	return Icmp(AddressString(localAddr), &ipAddr, ttl, pid, timeout)
}
<|endoftext|>


<commit_before>/* vim: set sw=4 sts=4 et foldmethod=syntax : */

/*
 * Copyright (c) 2011 Alexander Færøy <ahf@0x90.dk>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package main

import (
    "bufio"
    "fmt"
    "net"
    "strconv"
    "strings"
)

type Client struct {
    input chan string // Raw Input.
    output chan string // Raw Output.
    messages chan *Message // Parsed IRC Messages.

    output_quit chan bool // Leave the Output Handler.
    message_handler_quit chan bool // Leave the Message Handler.
    protocol_handler_quit chan bool // Leave the (Un)registered protocol handler.

    nickname string // The Nickname of the client.
    username string // The Username of the client.
    realname string // The Realname/Gecos of the client.
    hostname string // The hostname of the client (after we have done a reverse DNS lookup).

    address string // The IP address of the client.
    port int // The port.

    connection net.Conn // The connection.
    readwriter *bufio.ReadWriter // The buffered reader/writer.

    ircd *Ircd // Pointer to our IRCd.

    // Housekeeping (FIXME: Needs refactoring).
    isRegistered bool
}

func NewClient(ircd *Ircd, connection net.Conn, remoteAddr string) {
    client := new(Client)

    // The IRCd.
    client.ircd = ircd

    // Channels.
    client.input = make(chan string)
    client.output = make(chan string)
    client.messages = make(chan *Message)

    // Quit Channels.  These are being used to signal to each of our client
    // processes that it's time to exit.
    client.output_quit = make(chan bool)
    client.message_handler_quit = make(chan bool)
    client.protocol_handler_quit = make(chan bool)

    // RemoteAddr is on the form "IP:Port". Split it.
    address, portStr, error := net.SplitHostPort(remoteAddr)

    if error != nil {
        panic("Bug: Unable to split host/port.")
    }

    // Convert it to an integer.
    port, error := strconv.Atoi(portStr)

    if error != nil {
        panic("Bug: Unable to convert port to an int.")
    }

    // Set address and port.
    client.address = address
    client.port = port

    // Start background job for looking up the hostname.
    hostnameCh := LookupAddress(address)

    // Set initial values.
    client.nickname = "*"
    client.username = "*"
    client.realname = "*"

    // Use the IP for now.
    client.hostname = address

    // Set connection and create readwriter.
    client.connection = connection
    client.readwriter = bufio.NewReadWriter(bufio.NewReader(connection), bufio.NewWriter(connection))

    // Used for synchronisation once we are done looking up rDNS and do identd
    // check.
    sync := make(chan bool)

    // Socket Output Handler.
    go client.OutputHandler()

    // Socket Input Handler.
    go client.InputHandler()

    // Message Handler.  Takes a raw input string and converts it into a parsed
    // Message and sends it on to the ProtocolHandler (Either registered or
    // unregistered).
    go client.MessageHandler()

    // Unregistered Protocol Handler.  The Unregistered Protocol Handler only
    // accepts either the NICK or USER command. Once the client has been
    // registered, the UnregisteredProtocolHandler() will die and the
    // RegisteredProtocolHandler() will take over.
    go client.UnregisteredProtocolHandler(sync)

    // Start sending IRC messages to the client.
    client.WriteStringF("NOTICE AUTH :*** Processing connection to %s ...", ircd.Me())
    client.WriteString("NOTICE AUTH :*** Looking up your hostname ...")

    // Get result from rDNS lookup.
    host := <-hostnameCh
    client.WriteStringF("NOTICE AUTH :*** Found your hostname (%s) ...", host)
    client.hostname = host

    // Let the UnregisteredProtocolHandler() know that it's okay to exit and
    // let the RegisteredProtocolHandler() take over now.
    sync<-true
}

func (this *Client) InputHandler() {
    this.Printf("Entering Socket Input Handler")
    defer this.Printf("Leaving Socket Input Handler")

    rw := this.readwriter

    for {
        // Read until a newline.
        s, error := rw.ReadString('\n')

        if error != nil {
            // Read Error (Usually happens when the connection is closed by the
            // client).
            // FIXME: Should probably check for non-EOF errors.
            this.Printf("Read Error: %s", error)

            // Start a chain of Quit-messages to the various client processes
            // to ensure that they are all shutdown gracefully. The goal of
            // this is to avoid any dangling processes.
            this.output_quit<-true

            // Exit.
            return
        }

        // Trim "\r\n".
        line := strings.TrimRight(s, "\r\n")

        // Skip "empty" lines.
        if len(Strip(line)) == 0 {
            continue
        }

        // Pass on to the ProtocolHandler (Either Registered or Unregistered).
        this.input<-line
    }
}

func (this *Client) OutputHandler() {
    this.Printf("Entering Socket Output Handler")
    defer this.Printf("Leaving Socket Output Handler")

    defer func () {
        this.Printf("Sending Quit-message to the Message Handler")
        this.message_handler_quit<-true
    }()

    rw := this.readwriter

    for {
        select {
            case <-this.output_quit:
                // We were told to exit. Notice the above defer statements
                // where we chain the quit message on to the message handler
                // process.
                return

            case s, ok := <-this.output:
                if ! ok {
                    // The client is dead.
                    // FIXME: Shouldn't happen.
                    return
                }

                // Ignore the byte-count for now.  Go sets error to non-nil if
                // bytes != len(input).
                _, error := rw.WriteString(s + "\r\n")

                if error != nil {
                    this.Printf("Write Error: %s", error)

                    // Unlikely, but we'll quit.
                    return
                }

                this.Printf("<- '%s'", s)

                // Flush the buffer.
                rw.Flush()
        }
    }
}

func (this *Client) MessageHandler() {
    this.Printf("Entering Message Handler")
    defer this.Printf("Leaving Message Handler")

    defer func () {
        this.Printf("Sending Quit-message to the Protocol Handler")
        this.protocol_handler_quit<-true
    }()

    for {
        select {
            case line, ok := <-this.input:
                if ! ok {
                    // The client is dead.
                    // FIXME: Shouldn't happen.
                    return
                }

                message := Parse(line)

                // Most ASCII strings are valid IRC commands, but in the
                // unlikely case that Parse() returns nil, we'll simply skip
                // it.
                if message != nil {
                    this.Printf("-> '%s'", message)

                    // Pass on to the Protocol Handler.
                    this.messages<-message
                }

            case <-this.message_handler_quit:
                // We are done.
                // Notify the Protocol Handler that we quit.
                return
        }
    }
}

func (this *Client) UnregisteredProtocolHandler(sync chan bool) {
    this.Printf("Entering Unregistered Client Protocol Handler")
    defer this.Printf("Leaving Unregistered Client Protocol Handler")

    // The IRCd.
    ircd := this.ircd

    // Housekeeping.
    got_nickname := false
    got_username := false

    // Temporaries.
    var nickname string
    var username string
    var realname string

    for {
        select {
            case message, ok := <-this.messages:
                if ! ok {
                    // This client is dead.
                    // FIXME: Shouldn't happen.
                    return
                }

                cmd := message.Command()
                args := message.Arguments()

                switch cmd {
                    case "NICK":
                        // Missing nickname.
                        if len(args) < 1 {
                            this.SendNumeric(ERR_NONICKNAMEGIVEN, ircd.Me(), "*")
                            continue
                        }

                        n := args[0]

                        // Check if the nickname is valid.
                        if ! IsValidNickname(n) {
                            this.SendNumeric(ERR_ERRONEUSNICKNAME, ircd.Me(), "*", n)
                            continue
                        }

                        // Check if the nickname is already registered.
                        if this.ircd.FindClient(n) != nil {
                            this.SendNumeric(ERR_NICKNAMEINUSE, ircd.Me(), "*", n)
                            continue
                        }

                        got_nickname = true
                        nickname = n

                    case "USER":
                        // Missing parameters.
                        if len(args) < 4 {
                            this.SendNumeric(ERR_NEEDMOREPARAMS, ircd.Me(), "*", cmd)
                            continue
                        }

                        u := args[0]
                        r := args[3]

                        // Check if the username is valid.
                        if ! IsValidUsername(u) {
                            // FIXME: Handle ...
                        }

                        got_username = true

                        // FIXME: We Check Identd later.
                        username = "~" + u
                        realname = r
                }

                if got_nickname && got_username {
                    // Update the client information.  NOTE: It's important to
                    // do this *before* any attempts to register using
                    // this.Register() since otherwise it'll try to register
                    // using the "default" nickname, which is "*", and weird
                    // things may or may not happen.
                    this.nickname = nickname
                    this.username = username
                    this.realname = realname

                    // Try doing a registration.
                    // Check if the nickname has already been registered, just
                    // in case someone else connected whilst we were connecting
                    // and stole our nickname.
                    if ! this.Register() {
                        this.SendNumeric(ERR_NICKNAMEINUSE, ircd.Me(), "*", nickname)
                        continue
                    }

                    // Wait for the synchronisation signal.  We have to do rDNS
                    // lookup and identd check before we proceed to the
                    // registered protocol handler.
                    this.Printf("Waiting for synchronisation")
                    <-sync
                    this.Printf("Synchronisation done")

                    // Let the full IRC protocol handler take over now.
                    go this.RegisteredProtocolHandler()
                    return
                }

            case <-this.protocol_handler_quit:
                // We were told to quit.
                return
        }
    }
}

func (this *Client) RegisteredProtocolHandler() {
    this.Printf("Entering Registered Client Protocol Handler!")
    defer this.Printf("Leaving Registered Client Protocol Handler!")

    // The IRCd.
    ircd := this.ircd

    // Welcome the client.
    this.SendNumeric(RPL_WELCOME, ircd.Me(), this.Nickname(), ircd.Description(), this.Nickname())
    this.SendNumeric(RPL_YOURHOST, ircd.Me(), this.Nickname(), "FIXME", VersionFull)

    // Send MOTD, if any.
    this.SendMotd()

    for {
        select {
            case message, ok := <-this.messages:
                if ! ok {
                    // The client is dead.
                    // FIXME: Shouldn't happen.
                    return
                }

                // Handle the message.
                HandleMessage(this, message)

            case <-this.protocol_handler_quit:
                // We were told to quit.
                return
        }
    }
}

func (this *Client) WriteString(s string) {
    this.output<-s
}

func (this *Client) WriteStringF(format string, a...interface{}) {
    this.WriteString(fmt.Sprintf(format, a...))
}

func (this *Client) SendNumeric(n Numeric, a...interface{}) {
    this.WriteString(Format(n, a...))
}

func (this *Client) Unregister() {
    this.Printf("Unregistering client")

    if this.isRegistered {
        this.ircd.UnregisterClient(this)
    }
}

func (this *Client) Register() bool {
    this.Printf("Trying to register client")

    if this.isRegistered {
        panic("Bug: Trying to register an already registered client.")
    }

    b := this.ircd.RegisterClient(this)

    this.isRegistered = b
    return b
}

func (this *Client) SendMotd() {
    ircd := this.ircd
    motd := ircd.Motd()

    if motd == nil {
        this.SendNumeric(ERR_NOMOTD, ircd.Me(), this.Nickname())
        return
    }

    lines := *motd

    this.SendNumeric(RPL_MOTDSTART, ircd.Me(), this.Nickname(), ircd.Me())

    for i := range lines {
        this.SendNumeric(RPL_MOTD, ircd.Me(), this.Nickname(), lines[i])
    }

    this.SendNumeric(RPL_ENDOFMOTD, ircd.Me(), this.Nickname())
}

func (this *Client) Quit(message string) {
    this.WriteStringF(":%s QUIT :%s", this, message)

    // The Socket Input Handler will start the chain that kills the other
    // processes.
    this.Close()
}

func (this *Client) Pong(message string) {
    this.WriteStringF("PONG :%s", message)
}

func (this *Client) Close() {
    this.Printf("Closing")
    defer this.Printf("Finished Closing")

    // Unregister the client.
    this.Unregister()

    // Cleanup.
    this.connection.Close()
}

func (this *Client) Printf(format string, a...interface{}) {
    this.ircd.Printf(this.String() + ": " + format, a...)
}

func (this *Client) RemotePort() int {
    return this.port
}

func (this *Client) RemoteAddress() string {
    return this.address
}

func (this *Client) Nickname() string {
    return this.nickname
}

func (this *Client) Username() string {
    return this.username
}

func (this *Client) Hostname() string {
    return this.hostname
}

func (this *Client) Realname() string {
    return this.realname
}

// FIXME: Should die in a refactoring session. Only needed by the
// CommandRegistry.
func (this *Client) Ircd() *Ircd {
    return this.ircd
}

func (this *Client) String() string {
    return fmt.Sprintf("%s!%s@%s", this.Nickname(), this.Username(), this.Hostname())
}
<commit_msg>Kill MessageHandler().<commit_after>/* vim: set sw=4 sts=4 et foldmethod=syntax : */

/*
 * Copyright (c) 2011 Alexander Færøy <ahf@0x90.dk>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package main

import (
    "bufio"
    "fmt"
    "net"
    "strconv"
    "strings"
)

type Client struct {
    input chan *Message // Parsed IRC messages.
    output chan string // Output.

    output_quit chan bool // Leave the Output Handler.
    protocol_handler_quit chan bool // Leave the (Un)registered protocol handler.

    nickname string // The Nickname of the client.
    username string // The Username of the client.
    realname string // The Realname/Gecos of the client.
    hostname string // The hostname of the client (after we have done a reverse DNS lookup).

    address string // The IP address of the client.
    port int // The port.

    connection net.Conn // The connection.
    readwriter *bufio.ReadWriter // The buffered reader/writer.

    ircd *Ircd // Pointer to our IRCd.

    // Housekeeping (FIXME: Needs refactoring).
    isRegistered bool
}

func NewClient(ircd *Ircd, connection net.Conn, remoteAddr string) {
    client := new(Client)

    // The IRCd.
    client.ircd = ircd

    // Channels.
    client.input = make(chan *Message)
    client.output = make(chan string)

    // Quit Channels.  These are being used to signal to each of our client
    // processes that it's time to exit.
    client.output_quit = make(chan bool)
    client.protocol_handler_quit = make(chan bool)

    // RemoteAddr is on the form "IP:Port". Split it.
    address, portStr, error := net.SplitHostPort(remoteAddr)

    if error != nil {
        panic("Bug: Unable to split host/port.")
    }

    // Convert it to an integer.
    port, error := strconv.Atoi(portStr)

    if error != nil {
        panic("Bug: Unable to convert port to an int.")
    }

    // Set address and port.
    client.address = address
    client.port = port

    // Start background job for looking up the hostname.
    hostnameCh := LookupAddress(address)

    // Set initial values.
    client.nickname = "*"
    client.username = "*"
    client.realname = "*"

    // Use the IP for now.
    client.hostname = address

    // Set connection and create readwriter.
    client.connection = connection
    client.readwriter = bufio.NewReadWriter(bufio.NewReader(connection), bufio.NewWriter(connection))

    // Used for synchronisation once we are done looking up rDNS and do identd
    // check.
    sync := make(chan bool)

    // Socket Output Handler.
    go client.OutputHandler()

    // Socket Input Handler.
    go client.InputHandler()

    // Unregistered Protocol Handler.  The Unregistered Protocol Handler only
    // accepts either the NICK or USER command. Once the client has been
    // registered, the UnregisteredProtocolHandler() will die and the
    // RegisteredProtocolHandler() will take over.
    go client.UnregisteredProtocolHandler(sync)

    // Start sending IRC messages to the client.
    client.WriteStringF("NOTICE AUTH :*** Processing connection to %s ...", ircd.Me())
    client.WriteString("NOTICE AUTH :*** Looking up your hostname ...")

    // Get result from rDNS lookup.
    host := <-hostnameCh
    client.WriteStringF("NOTICE AUTH :*** Found your hostname (%s) ...", host)
    client.hostname = host

    // Let the UnregisteredProtocolHandler() know that it's okay to exit and
    // let the RegisteredProtocolHandler() take over now.
    sync<-true
}

func (this *Client) InputHandler() {
    this.Printf("Entering Socket Input Handler")
    defer this.Printf("Leaving Socket Input Handler")

    rw := this.readwriter

    for {
        // Read until a newline.
        s, error := rw.ReadString('\n')

        if error != nil {
            // Read Error (Usually happens when the connection is closed by the
            // client).
            // FIXME: Should probably check for non-EOF errors.
            this.Printf("Read Error: %s", error)

            // Start a chain of Quit-messages to the various client processes
            // to ensure that they are all shutdown gracefully. The goal of
            // this is to avoid any dangling processes.
            this.output_quit<-true

            // Exit.
            return
        }

        // Trim "\r\n".
        line := strings.TrimRight(s, "\r\n")

        // Skip "empty" lines.
        if len(Strip(line)) == 0 {
            continue
        }

        // Parse.
        message := Parse(line)

        // Most ASCII strings are valid IRC commands, but in the
        // unlikely case that Parse() returns nil, we'll simply skip
        // it.
        if message != nil {
            this.Printf("-> '%s'", message)

            // Pass on to the ProtocolHandler (Either Registered or Unregistered).
            this.input<-message
        }
    }
}

func (this *Client) OutputHandler() {
    this.Printf("Entering Socket Output Handler")
    defer this.Printf("Leaving Socket Output Handler")

    defer func () {
        this.Printf("Sending Quit-message to the Protocol Handler")
        this.protocol_handler_quit<-true
    }()

    rw := this.readwriter

    for {
        select {
            case <-this.output_quit:
                // We were told to exit. Notice the above defer statements
                // where we chain the quit message on to the message handler
                // process.
                return

            case s, ok := <-this.output:
                if ! ok {
                    // The client is dead.
                    // FIXME: Shouldn't happen.
                    return
                }

                // Ignore the byte-count for now.  Go sets error to non-nil if
                // bytes != len(input).
                _, error := rw.WriteString(s + "\r\n")

                if error != nil {
                    this.Printf("Write Error: %s", error)

                    // Unlikely, but we'll quit.
                    return
                }

                this.Printf("<- '%s'", s)

                // Flush the buffer.
                rw.Flush()
        }
    }
}

func (this *Client) UnregisteredProtocolHandler(sync chan bool) {
    this.Printf("Entering Unregistered Client Protocol Handler")
    defer this.Printf("Leaving Unregistered Client Protocol Handler")

    // The IRCd.
    ircd := this.ircd

    // Housekeeping.
    got_nickname := false
    got_username := false

    // Temporaries.
    var nickname string
    var username string
    var realname string

    for {
        select {
            case message, ok := <-this.input:
                if ! ok {
                    // This client is dead.
                    // FIXME: Shouldn't happen.
                    return
                }

                cmd := message.Command()
                args := message.Arguments()

                switch cmd {
                    case "NICK":
                        // Missing nickname.
                        if len(args) < 1 {
                            this.SendNumeric(ERR_NONICKNAMEGIVEN, ircd.Me(), "*")
                            continue
                        }

                        n := args[0]

                        // Check if the nickname is valid.
                        if ! IsValidNickname(n) {
                            this.SendNumeric(ERR_ERRONEUSNICKNAME, ircd.Me(), "*", n)
                            continue
                        }

                        // Check if the nickname is already registered.
                        if this.ircd.FindClient(n) != nil {
                            this.SendNumeric(ERR_NICKNAMEINUSE, ircd.Me(), "*", n)
                            continue
                        }

                        got_nickname = true
                        nickname = n

                    case "USER":
                        // Missing parameters.
                        if len(args) < 4 {
                            this.SendNumeric(ERR_NEEDMOREPARAMS, ircd.Me(), "*", cmd)
                            continue
                        }

                        u := args[0]
                        r := args[3]

                        // Check if the username is valid.
                        if ! IsValidUsername(u) {
                            // FIXME: Handle ...
                        }

                        got_username = true

                        // FIXME: We Check Identd later.
                        username = "~" + u
                        realname = r
                }

                if got_nickname && got_username {
                    // Update the client information.  NOTE: It's important to
                    // do this *before* any attempts to register using
                    // this.Register() since otherwise it'll try to register
                    // using the "default" nickname, which is "*", and weird
                    // things may or may not happen.
                    this.nickname = nickname
                    this.username = username
                    this.realname = realname

                    // Try doing a registration.
                    // Check if the nickname has already been registered, just
                    // in case someone else connected whilst we were connecting
                    // and stole our nickname.
                    if ! this.Register() {
                        this.SendNumeric(ERR_NICKNAMEINUSE, ircd.Me(), "*", nickname)
                        continue
                    }

                    // Wait for the synchronisation signal.  We have to do rDNS
                    // lookup and identd check before we proceed to the
                    // registered protocol handler.
                    this.Printf("Waiting for synchronisation")
                    <-sync
                    this.Printf("Synchronisation done")

                    // Let the full IRC protocol handler take over now.
                    go this.RegisteredProtocolHandler()
                    return
                }

            case <-this.protocol_handler_quit:
                // We were told to quit.
                return
        }
    }
}

func (this *Client) RegisteredProtocolHandler() {
    this.Printf("Entering Registered Client Protocol Handler!")
    defer this.Printf("Leaving Registered Client Protocol Handler!")

    // The IRCd.
    ircd := this.ircd

    // Welcome the client.
    this.SendNumeric(RPL_WELCOME, ircd.Me(), this.Nickname(), ircd.Description(), this.Nickname())
    this.SendNumeric(RPL_YOURHOST, ircd.Me(), this.Nickname(), "FIXME", VersionFull)

    // Send MOTD, if any.
    this.SendMotd()

    for {
        select {
            case message, ok := <-this.input:
                if ! ok {
                    // The client is dead.
                    // FIXME: Shouldn't happen.
                    return
                }

                // Handle the message.
                HandleMessage(this, message)

            case <-this.protocol_handler_quit:
                // We were told to quit.
                return
        }
    }
}

func (this *Client) WriteString(s string) {
    this.output<-s
}

func (this *Client) WriteStringF(format string, a...interface{}) {
    this.WriteString(fmt.Sprintf(format, a...))
}

func (this *Client) SendNumeric(n Numeric, a...interface{}) {
    this.WriteString(Format(n, a...))
}

func (this *Client) Unregister() {
    this.Printf("Unregistering client")

    if this.isRegistered {
        this.ircd.UnregisterClient(this)
    }
}

func (this *Client) Register() bool {
    this.Printf("Trying to register client")

    if this.isRegistered {
        panic("Bug: Trying to register an already registered client.")
    }

    b := this.ircd.RegisterClient(this)

    this.isRegistered = b
    return b
}

func (this *Client) SendMotd() {
    ircd := this.ircd
    motd := ircd.Motd()

    if motd == nil {
        this.SendNumeric(ERR_NOMOTD, ircd.Me(), this.Nickname())
        return
    }

    lines := *motd

    this.SendNumeric(RPL_MOTDSTART, ircd.Me(), this.Nickname(), ircd.Me())

    for i := range lines {
        this.SendNumeric(RPL_MOTD, ircd.Me(), this.Nickname(), lines[i])
    }

    this.SendNumeric(RPL_ENDOFMOTD, ircd.Me(), this.Nickname())
}

func (this *Client) Quit(message string) {
    this.WriteStringF(":%s QUIT :%s", this, message)

    // The Socket Input Handler will start the chain that kills the other
    // processes.
    this.Close()
}

func (this *Client) Pong(message string) {
    this.WriteStringF("PONG :%s", message)
}

func (this *Client) Close() {
    this.Printf("Closing")
    defer this.Printf("Finished Closing")

    // Unregister the client.
    this.Unregister()

    // Cleanup.
    this.connection.Close()
}

func (this *Client) Printf(format string, a...interface{}) {
    this.ircd.Printf(this.String() + ": " + format, a...)
}

func (this *Client) RemotePort() int {
    return this.port
}

func (this *Client) RemoteAddress() string {
    return this.address
}

func (this *Client) Nickname() string {
    return this.nickname
}

func (this *Client) Username() string {
    return this.username
}

func (this *Client) Hostname() string {
    return this.hostname
}

func (this *Client) Realname() string {
    return this.realname
}

// FIXME: Should die in a refactoring session. Only needed by the
// CommandRegistry.
func (this *Client) Ircd() *Ircd {
    return this.ircd
}

func (this *Client) String() string {
    return fmt.Sprintf("%s!%s@%s", this.Nickname(), this.Username(), this.Hostname())
}
<|endoftext|>


<commit_before>package microservicecore

// MicroserviceInfo - Represents information about this microservice.
type MicroserviceInfo struct {
	ServiceName    string  `json:"service_name"`
	ServiceType    string  `json:"service_type"`
	ServiceScope   string  `json:"service_scope"`
	ServiceVersion string  `json:"service_version"`
	Endpoints      []Route `json:"endpoints"`
}

// GetMicroserviceInfo - Get the information about this microservice.
//
// Return:
//     *MicroserviceInfo - Object representing this microservice.
func GetMicroserviceInfo() *MicroserviceInfo {
	return &MicroserviceInfo{
		ServiceName:    GetEnvOrFail("SERVICE_NAME"),
		ServiceType:    GetEnvOrFail("SERVICE_TYPE"),
		ServiceScope:   GetEnvOrFail("SERVICE_SCOPE"),
		ServiceVersion: GetEnvOrFail("SERVICE_VERSION"),
	}
}
<commit_msg>Fixed import path for Route struct in the info.go file.<commit_after>package microservicecore

import "github.com/LUSHDigital/microservice-core-golang/routes"

// MicroserviceInfo - Represents information about this microservice.
type MicroserviceInfo struct {
	ServiceName    string         `json:"service_name"`
	ServiceType    string         `json:"service_type"`
	ServiceScope   string         `json:"service_scope"`
	ServiceVersion string         `json:"service_version"`
	Endpoints      []routes.Route `json:"endpoints"`
}

// GetMicroserviceInfo - Get the information about this microservice.
//
// Return:
//     *MicroserviceInfo - Object representing this microservice.
func GetMicroserviceInfo() *MicroserviceInfo {
	return &MicroserviceInfo{
		ServiceName:    GetEnvOrFail("SERVICE_NAME"),
		ServiceType:    GetEnvOrFail("SERVICE_TYPE"),
		ServiceScope:   GetEnvOrFail("SERVICE_SCOPE"),
		ServiceVersion: GetEnvOrFail("SERVICE_VERSION"),
	}
}
<|endoftext|>


<commit_before>package chainlib

import (
	"flag"
	"fmt"
	"log"
	"strings"
)

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

// Convenience function for writing utilities which use Bernstein chaining to
// pass environment variables. Function f should perform logic to retrieve data
// to be serialized to environment variables and return them as a map of strings,
// or error if something went wrong.
func Main(prefix string, f func() (map[string]string, error)) {
	var upcase bool
	var rprefix string
	flag.StringVar(&rprefix, "prefix", prefix, "Prefix")
	flag.BoolVar(&upcase, "upcase", true, "Upcase variables")
	flag.Parse()

	env, err := f()
	assert(err)
	var menv []string
	for k, v := range env {
		key := SafeEnv(k)
		if upcase {
			key = strings.ToUpper(key)
		}
		menv = append(menv, fmt.Sprintf("%s_%s=%s", rprefix, key, v))
	}
	assert(Exec(flag.Args(), menv))
}
<commit_msg>Avoid log.Fatal, let whatever is reading our stdout/stderr add datetimes if necessary<commit_after>package chainlib

import (
	"flag"
	"fmt"
	"os"
	"strings"
)

func assert(err error) {
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

// Convenience function for writing utilities which use Bernstein chaining to
// pass environment variables. Function f should perform logic to retrieve data
// to be serialized to environment variables and return them as a map of strings,
// or error if something went wrong.
func Main(prefix string, f func() (map[string]string, error)) {
	var upcase bool
	var rprefix string
	flag.StringVar(&rprefix, "prefix", prefix, "Prefix")
	flag.BoolVar(&upcase, "upcase", true, "Upcase variables")
	flag.Parse()

	env, err := f()
	assert(err)
	var menv []string
	for k, v := range env {
		key := SafeEnv(k)
		if upcase {
			key = strings.ToUpper(key)
		}
		menv = append(menv, fmt.Sprintf("%s_%s=%s", rprefix, key, v))
	}
	assert(Exec(flag.Args(), menv))
}
<|endoftext|>


<commit_before>package oraclebmc_sdk

import (
	"crypto/sha256"
	"encoding/json"
	"fmt"
	"github.com/99designs/httpsignatures-go"
	"io/ioutil"
	"net/http"
	"time"
)

type oracle_config struct {
	user                         string
	tenancy                      string
	fingerprint                  string
	private_key                  string
	core_endpoint                string
	endpoint_blockstorage_api    string
	endpoint_identity_api        string
	endpoint_compute_api         string
	endpoint_virtual_network_api string
	endpoint_object_storage_api  string
	verify_ssl                   bool
	log_requests                 bool
	additional_user_agent        string
}

func NewConfig(user string, tenancy string, fingerprint string, signing_key string) *oracle_config {
	core_endpoint := "https://iaas.us-phoenix-1.oraclecloud.com/20160918"
	obj_endpoint := "https://objectstorage.us-phoenix-1.oraclecloud.com"
	endpoint_identity_api := "https://identity.us-phoenix-1.oraclecloud.com/20160918"
	return &oracle_config{
		user:                         user,
		tenancy:                      tenancy,
		fingerprint:                  fingerprint,
		private_key:                  signing_key,
		core_endpoint:                core_endpoint,
		endpoint_blockstorage_api:    core_endpoint,
		endpoint_compute_api:         core_endpoint,
		endpoint_virtual_network_api: core_endpoint,
		endpoint_object_storage_api:  obj_endpoint,
		endpoint_identity_api:        endpoint_identity_api}
}

func (config *oracle_config) getKey() string {
	return fmt.Sprintf("%s/%s/%s", config.tenancy, config.user, config.fingerprint)
}

type ComputeApi struct {
	Config *oracle_config
}

type Image struct {
	BaseImageId            string
	CompartmentId          string
	CreateImageAllowed     string
	DisplayName            string
	Id                     string
	LifeCycleState         string
	OperatingSystemVersion string
	TimeCreated            time.Time
}

type instancesList []Instance

type Instance struct {
	AvailabilityDomain string
	CompartmentId      string
	DisplayName        string
	Id                 string
	ImageId            string
	LifecycleState     string
	Metadata           map[string]string
	Region             string
	Shape              string
	TimeCreated        time.Time
}

func (computeApi *ComputeApi) GetInstance(instanceId string) (*Instance, error) {
	suffix := fmt.Sprintf("/instances/%s", instanceId)

	req, err := http.NewRequest("GET", computeApi.Config.core_endpoint+suffix, nil)
	if err != nil {
		return nil, err
	}
	inject_headers(computeApi.Config, req)

	client := &http.Client{}
	resp, err := client.Do(req)
	decoder := json.NewDecoder(resp.Body)
	var instance Instance
	err = decoder.Decode(&instance)
	return &instance, nil
}

func (computeApi *ComputeApi) ListImages(compartment_id string) (*[]*Image, error) {
	suffix := "/images"
	req, err := http.NewRequest("GET", computeApi.Config.core_endpoint+suffix, nil)
	if err != nil {
		return nil, err
	}
	url := req.URL
	q := url.Query()
	q.Set("compartmentId", compartment_id)
	url.RawQuery = q.Encode()

	inject_headers(computeApi.Config, req)

	client := &http.Client{}
	resp, err := client.Do(req)

	decoder := json.NewDecoder(resp.Body)
	var images []Instance
	err = decoder.Decode(&images)

	return images, nil
}

func inject_headers(oracleConfig *oracle_config, request *http.Request) {
	var required_headers []string
	request.Header.Set("host", request.URL.Host)
	if request.Method == "POST" || request.Method == "PUT" {

		required_headers = []string{
			httpsignatures.RequestTarget,
			"date",
			"host",
			"x-content-sha256",
			"content-type",
			"content-length"}

		body, _ := ioutil.ReadAll(request.Body)
		hash := sha256.New()
		hash.Write([]byte(body))
		content_body := hash.Sum(nil)

		request.Header.Set("x-content-sha256", string(content_body))
		request.Header.Set("content-length", string(len(body)))
		request.Header.Set("content-type", "application/json")
	} else {
		required_headers = []string{httpsignatures.RequestTarget, "date", "host"}
	}
	signer := httpsignatures.NewSigner(httpsignatures.AlgorithmRsaSha256, required_headers...)
	signer.AuthRequest(oracleConfig.getKey(), oracleConfig.private_key, request)
}
<commit_msg>refactor<commit_after>package oraclebmc_sdk

import (
	"crypto/sha256"
	"encoding/json"
	"fmt"
	"github.com/99designs/httpsignatures-go"
	"io/ioutil"
	"net/http"
	"time"
	"io"
	"bytes"
)

type oracle_config struct {
	user                         string
	tenancy                      string
	fingerprint                  string
	private_key                  string
	core_endpoint                string
	endpoint_blockstorage_api    string
	endpoint_identity_api        string
	endpoint_compute_api         string
	endpoint_virtual_network_api string
	endpoint_object_storage_api  string
	verify_ssl                   bool
	log_requests                 bool
	additional_user_agent        string
}

func NewConfig(user string, tenancy string, fingerprint string, signing_key string) *oracle_config {
	core_endpoint := "https://iaas.us-phoenix-1.oraclecloud.com/20160918"
	obj_endpoint := "https://objectstorage.us-phoenix-1.oraclecloud.com"
	endpoint_identity_api := "https://identity.us-phoenix-1.oraclecloud.com/20160918"
	return &oracle_config{
		user:                         user,
		tenancy:                      tenancy,
		fingerprint:                  fingerprint,
		private_key:                  signing_key,
		core_endpoint:                core_endpoint,
		endpoint_blockstorage_api:    core_endpoint,
		endpoint_compute_api:         core_endpoint,
		endpoint_virtual_network_api: core_endpoint,
		endpoint_object_storage_api:  obj_endpoint,
		endpoint_identity_api:        endpoint_identity_api}
}

func (config *oracle_config) getKey() string {
	return fmt.Sprintf("%s/%s/%s", config.tenancy, config.user, config.fingerprint)
}

type ComputeApi struct {
	Config *oracle_config
}

type Image struct {
	BaseImageId            string
	CompartmentId          string
	CreateImageAllowed     string
	DisplayName            string
	Id                     string
	LifeCycleState         string
	OperatingSystemVersion string
	TimeCreated            time.Time
}

type instancesList []Instance

type Instance struct {
	AvailabilityDomain string
	CompartmentId      string
	DisplayName        string
	Id                 string
	ImageId            string
	LifecycleState     string
	Region             string
	Shape              string
	TimeCreated        time.Time
	Metadata           map[string]string
}

type oracleRequest struct {
	Url          string
	Suffix       string
	Method       string
	OracleConfig *oracle_config
	Output       interface{}
	Params       map[string]string
}

func (orReq *oracleRequest) doReq() (interface{}, error) {
	var body io.Reader
	if orReq.Params != nil && len(orReq.Params) > 0 {
		val, err := json.Marshal(orReq.Params)
		if err != nil {
			return nil, err
		}
		body = bytes.NewBuffer(val)
	} else {
		body = nil
	}
	req, err := http.NewRequest(orReq.Method, orReq.Url + orReq.Suffix, body)
	if body == nil {
		url := req.URL
		q := url.Query()
		for key, val := range orReq.Params {
			q.Set(key, val)
		}
		url.RawQuery = q.Encode()

	}
	if err != nil {
		return nil, err
	}
	inject_headers(orReq.OracleConfig, req)
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	decoder := json.NewDecoder(resp.Body)
	err = decoder.Decode(orReq.Output)
	return orReq.Output, nil
}

func (computeApi *ComputeApi) GetInstance(instanceId string) (*Instance, error) {
	suffix := fmt.Sprintf("/instances/%s", instanceId)
	var instance Instance
	output := &instance
	orReq := oracleRequest{Url: computeApi.Config.core_endpoint, Suffix: suffix, Method: "GET", OracleConfig: computeApi.Config, Params: nil, Output:output}
	body, err := orReq.doReq()
	if err != nil {
		return nil, err
	}
	return (body.(*Instance)), nil
}

//func (computeApi *ComputeApi) ListImages(compartment_id string) (*[]*Image, error) {
//	suffix := "/images"
//	req, err := http.NewRequest("GET", computeApi.Config.core_endpoint + suffix, nil)
//	if err != nil {
//		return nil, err
//	}
//	url := req.URL
//	q := url.Query()
//	q.Set("compartmentId", compartment_id)
//	url.RawQuery = q.Encode()
//
//	inject_headers(computeApi.Config, req)
//
//	client := &http.Client{}
//	resp, err := client.Do(req)
//
//	decoder := json.NewDecoder(resp.Body)
//	var images []*Instance
//	err = decoder.Decode(&images)
//
//	return *images, nil
//}

func inject_headers(oracleConfig *oracle_config, request *http.Request) {
	var required_headers []string
	request.Header.Set("host", request.URL.Host)
	if request.Method == "POST" || request.Method == "PUT" {

		required_headers = []string{
			httpsignatures.RequestTarget,
			"date",
			"host",
			"x-content-sha256",
			"content-type",
			"content-length"}

		body, _ := ioutil.ReadAll(request.Body)
		hash := sha256.New()
		hash.Write([]byte(body))
		content_body := hash.Sum(nil)

		request.Header.Set("x-content-sha256", string(content_body))
		request.Header.Set("content-length", string(len(body)))
		request.Header.Set("content-type", "application/json")
	} else {
		required_headers = []string{httpsignatures.RequestTarget, "date", "host"}
	}
	signer := httpsignatures.NewSigner(httpsignatures.AlgorithmRsaSha256, required_headers...)
	signer.AuthRequest(oracleConfig.getKey(), oracleConfig.private_key, request)
}
<|endoftext|>


<commit_before>// Copyright 2017 Google 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 apidApigeeSync

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"time"

	"github.com/apid/apid-core"
	"github.com/apid/apid-core/util"
)

const (
	configPollInterval        = "apigeesync_poll_interval"
	configProxyServerBaseURI  = "apigeesync_proxy_server_base"
	configSnapServerBaseURI   = "apigeesync_snapshot_server_base"
	configChangeServerBaseURI = "apigeesync_change_server_base"
	configConsumerKey         = "apigeesync_consumer_key"
	configConsumerSecret      = "apigeesync_consumer_secret"
	configApidClusterId       = "apigeesync_cluster_id"
	configSnapshotProtocol    = "apigeesync_snapshot_proto"
	configName                = "apigeesync_instance_name"
	configDiagnosticMode      = "apigeesync_diagnostic_mode"
	// special value - set by ApigeeSync, not taken from configuration
	configApidInstanceID = "apigeesync_apid_instance_id"
	// This will not be needed once we have plugin handling tokens.
	configBearerToken = "apigeesync_bearer_token"
)

const (
	ApigeeSyncEventSelector = "ApigeeSync"
)

var (
	/* All set during plugin initialization */
	log                 apid.LogService
	config              apid.ConfigService
	dataService         apid.DataService
	events              apid.EventsService
	apidInfo            apidInstanceInfo
	newInstanceID       bool
	apidTokenManager    tokenManager
	apidChangeManager   changeManager
	apidSnapshotManager snapShotManager
	httpclient          *http.Client
	isOfflineMode       bool

	/* Set during post plugin initialization
	 * set this as a default, so that it's guaranteed to be valid even if postInitPlugins isn't called
	 */
	apidPluginDetails string = `[{"name":"apidApigeeSync","schemaVer":"1.0"}]`
)

type apidInstanceInfo struct {
	InstanceID, InstanceName, ClusterID, LastSnapshot string
}

type pluginDetail struct {
	Name          string `json:"name"`
	SchemaVersion string `json:"schemaVer"`
}

func init() {
	apid.RegisterPlugin(initPlugin, pluginData)
}

func initConfigDefaults() {
	config.SetDefault(configPollInterval, 120*time.Second)
	config.SetDefault(configSnapshotProtocol, "sqlite")
	config.SetDefault(configDiagnosticMode, false)
	name, errh := os.Hostname()
	if (errh != nil) && (len(config.GetString(configName)) == 0) {
		log.Errorf("Not able to get hostname for kernel. Please set '%s' property in config", configName)
		name = "Undefined"
	}
	config.SetDefault(configName, name)
	log.Debugf("Using %s as display name", config.GetString(configName))
}

func initVariables() error {

	var tr *http.Transport

	tr = util.Transport(config.GetString(util.ConfigfwdProxyPortURL))
	tr.MaxIdleConnsPerHost = maxIdleConnsPerHost

	httpclient = &http.Client{
		Transport: tr,
		Timeout:   httpTimeout,
		CheckRedirect: func(req *http.Request, _ []*http.Request) error {
			req.Header.Set("Authorization", "Bearer "+apidTokenManager.getBearerToken())
			return nil
		},
	}

	// set up default database
	db, err := dataService.DB()
	if err != nil {
		return fmt.Errorf("Unable to access DB: %v", err)
	}
	err = initDB(db)
	if err != nil {
		return fmt.Errorf("Unable to access DB: %v", err)
	}
	setDB(db)

	apidInfo, err = getApidInstanceInfo()
	if err != nil {
		return fmt.Errorf("Unable to get apid instance info: %v", err)
	}

	if config.IsSet(configApidInstanceID) {
		log.Warnf("ApigeeSync plugin overriding %s.", configApidInstanceID)
	}
	config.Set(configApidInstanceID, apidInfo.InstanceID)

	return nil
}

func createManagers() {
	if isOfflineMode {
		apidSnapshotManager = &offlineSnapshotManager{}
		apidChangeManager = &offlineChangeManager{}
	} else {
		apidSnapshotManager = createSnapShotManager()
		apidChangeManager = createChangeManager()
	}

	apidTokenManager = createSimpleTokenManager()
}

func checkForRequiredValues() error {
	required := []string{configProxyServerBaseURI, configConsumerKey, configConsumerSecret}
	if !isOfflineMode {
		required = append(required, configSnapServerBaseURI, configChangeServerBaseURI)
	}
	// check for required values
	for _, key := range required {
		if !config.IsSet(key) {
			return fmt.Errorf("Missing required config value: %s", key)
		}
	}
	proto := config.GetString(configSnapshotProtocol)
	if proto != "sqlite" {
		return fmt.Errorf("Illegal value for %s. Only currently supported snashot protocol is sqlite", configSnapshotProtocol)
	}

	return nil
}

func SetLogger(logger apid.LogService) {
	log = logger
}

/* initialization */
func _initPlugin(services apid.Services) error {
	log.Debug("start init")

	config = services.Config()
	initConfigDefaults()

	if config.GetBool(configDiagnosticMode) {
		log.Warn("Diagnostic mode: will not download changelist and snapshots!")
		isOfflineMode = true
	}

	if val, ok := os.LookupEnv(configConsumerKey); ok {
		config.Set(configConsumerKey, val)
		log.Debug("Got consumer key from env vars")
	}
	if val, ok := os.LookupEnv(configConsumerSecret); ok {
		config.Set(configConsumerSecret, val)
		log.Debug("Got consumer secret from env vars")
	}

	err := checkForRequiredValues()
	if err != nil {
		return err
	}

	err = initVariables()
	if err != nil {
		return err
	}

	return nil
}

func initPlugin(services apid.Services) (apid.PluginData, error) {
	SetLogger(services.Log().ForModule("apigeeSync"))
	dataService = services.Data()
	events = services.Events()

	err := _initPlugin(services)
	if err != nil {
		return pluginData, err
	}

	createManagers()

	/* This callback function will get called once all the plugins are
	 * initialized (not just this plugin). This is needed because,
	 * downloadSnapshots/changes etc have to begin to be processed only
	 * after all the plugins are initialized
	 */
	events.ListenOnceFunc(apid.SystemEventsSelector, postInitPlugins)

	InitAPI(services)
	log.Debug("end init")

	return pluginData, nil
}

// Plugins have all initialized, gather their info and start the ApigeeSync downloads
func postInitPlugins(event apid.Event) {
	var plinfoDetails []pluginDetail
	if pie, ok := event.(apid.PluginsInitializedEvent); ok {
		/*
		 * Store the plugin details in the heap. Needed during
		 * Bearer token generation request.
		 */
		for _, plugin := range pie.Plugins {
			name := plugin.Name
			version := plugin.Version
			if schemaVersion, ok := plugin.ExtraData["schemaVersion"].(string); ok {
				inf := pluginDetail{
					Name:          name,
					SchemaVersion: schemaVersion}
				plinfoDetails = append(plinfoDetails, inf)
				log.Debugf("plugin %s is version %s, schemaVersion: %s", name, version, schemaVersion)
			}
		}
		if plinfoDetails == nil {
			log.Panicf("No Plugins registered!")
		}

		pgInfo, err := json.Marshal(plinfoDetails)
		if err != nil {
			log.Panicf("Unable to marshal plugin data: %v", err)
		}
		apidPluginDetails = string(pgInfo[:])

		log.Debug("start post plugin init")

		apidTokenManager.start()
		go bootstrap()

		log.Debug("Done post plugin init")
	}
}
<commit_msg>Revert "Issue 67308179: add support for getting credentials from env vars (#73)" (#74)<commit_after>// Copyright 2017 Google 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 apidApigeeSync

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"time"

	"github.com/apid/apid-core"
	"github.com/apid/apid-core/util"
)

const (
	configPollInterval        = "apigeesync_poll_interval"
	configProxyServerBaseURI  = "apigeesync_proxy_server_base"
	configSnapServerBaseURI   = "apigeesync_snapshot_server_base"
	configChangeServerBaseURI = "apigeesync_change_server_base"
	configConsumerKey         = "apigeesync_consumer_key"
	configConsumerSecret      = "apigeesync_consumer_secret"
	configApidClusterId       = "apigeesync_cluster_id"
	configSnapshotProtocol    = "apigeesync_snapshot_proto"
	configName                = "apigeesync_instance_name"
	configDiagnosticMode      = "apigeesync_diagnostic_mode"
	// special value - set by ApigeeSync, not taken from configuration
	configApidInstanceID = "apigeesync_apid_instance_id"
	// This will not be needed once we have plugin handling tokens.
	configBearerToken = "apigeesync_bearer_token"
)

const (
	ApigeeSyncEventSelector = "ApigeeSync"
)

var (
	/* All set during plugin initialization */
	log                 apid.LogService
	config              apid.ConfigService
	dataService         apid.DataService
	events              apid.EventsService
	apidInfo            apidInstanceInfo
	newInstanceID       bool
	apidTokenManager    tokenManager
	apidChangeManager   changeManager
	apidSnapshotManager snapShotManager
	httpclient          *http.Client
	isOfflineMode       bool

	/* Set during post plugin initialization
	 * set this as a default, so that it's guaranteed to be valid even if postInitPlugins isn't called
	 */
	apidPluginDetails string = `[{"name":"apidApigeeSync","schemaVer":"1.0"}]`
)

type apidInstanceInfo struct {
	InstanceID, InstanceName, ClusterID, LastSnapshot string
}

type pluginDetail struct {
	Name          string `json:"name"`
	SchemaVersion string `json:"schemaVer"`
}

func init() {
	apid.RegisterPlugin(initPlugin, pluginData)
}

func initConfigDefaults() {
	config.SetDefault(configPollInterval, 120*time.Second)
	config.SetDefault(configSnapshotProtocol, "sqlite")
	config.SetDefault(configDiagnosticMode, false)

	name, errh := os.Hostname()
	if (errh != nil) && (len(config.GetString(configName)) == 0) {
		log.Errorf("Not able to get hostname for kernel. Please set '%s' property in config", configName)
		name = "Undefined"
	}
	config.SetDefault(configName, name)
	log.Debugf("Using %s as display name", config.GetString(configName))
}

func initVariables() error {

	var tr *http.Transport

	tr = util.Transport(config.GetString(util.ConfigfwdProxyPortURL))
	tr.MaxIdleConnsPerHost = maxIdleConnsPerHost

	httpclient = &http.Client{
		Transport: tr,
		Timeout:   httpTimeout,
		CheckRedirect: func(req *http.Request, _ []*http.Request) error {
			req.Header.Set("Authorization", "Bearer "+apidTokenManager.getBearerToken())
			return nil
		},
	}

	// set up default database
	db, err := dataService.DB()
	if err != nil {
		return fmt.Errorf("Unable to access DB: %v", err)
	}
	err = initDB(db)
	if err != nil {
		return fmt.Errorf("Unable to access DB: %v", err)
	}
	setDB(db)

	apidInfo, err = getApidInstanceInfo()
	if err != nil {
		return fmt.Errorf("Unable to get apid instance info: %v", err)
	}

	if config.IsSet(configApidInstanceID) {
		log.Warnf("ApigeeSync plugin overriding %s.", configApidInstanceID)
	}
	config.Set(configApidInstanceID, apidInfo.InstanceID)

	return nil
}

func createManagers() {
	if isOfflineMode {
		apidSnapshotManager = &offlineSnapshotManager{}
		apidChangeManager = &offlineChangeManager{}
	} else {
		apidSnapshotManager = createSnapShotManager()
		apidChangeManager = createChangeManager()
	}

	apidTokenManager = createSimpleTokenManager()
}

func checkForRequiredValues() error {
	required := []string{configProxyServerBaseURI, configConsumerKey, configConsumerSecret}
	if !isOfflineMode {
		required = append(required, configSnapServerBaseURI, configChangeServerBaseURI)
	}
	// check for required values
	for _, key := range required {
		if !config.IsSet(key) {
			return fmt.Errorf("Missing required config value: %s", key)
		}
	}
	proto := config.GetString(configSnapshotProtocol)
	if proto != "sqlite" {
		return fmt.Errorf("Illegal value for %s. Only currently supported snashot protocol is sqlite", configSnapshotProtocol)
	}

	return nil
}

func SetLogger(logger apid.LogService) {
	log = logger
}

/* initialization */
func _initPlugin(services apid.Services) error {
	log.Debug("start init")

	config = services.Config()
	initConfigDefaults()

	if config.GetBool(configDiagnosticMode) {
		log.Warn("Diagnostic mode: will not download changelist and snapshots!")
		isOfflineMode = true
	}

	err := checkForRequiredValues()
	if err != nil {
		return err
	}

	err = initVariables()
	if err != nil {
		return err
	}

	return nil
}

func initPlugin(services apid.Services) (apid.PluginData, error) {
	SetLogger(services.Log().ForModule("apigeeSync"))
	dataService = services.Data()
	events = services.Events()

	err := _initPlugin(services)
	if err != nil {
		return pluginData, err
	}

	createManagers()

	/* This callback function will get called once all the plugins are
	 * initialized (not just this plugin). This is needed because,
	 * downloadSnapshots/changes etc have to begin to be processed only
	 * after all the plugins are initialized
	 */
	events.ListenOnceFunc(apid.SystemEventsSelector, postInitPlugins)

	InitAPI(services)
	log.Debug("end init")

	return pluginData, nil
}

// Plugins have all initialized, gather their info and start the ApigeeSync downloads
func postInitPlugins(event apid.Event) {
	var plinfoDetails []pluginDetail
	if pie, ok := event.(apid.PluginsInitializedEvent); ok {
		/*
		 * Store the plugin details in the heap. Needed during
		 * Bearer token generation request.
		 */
		for _, plugin := range pie.Plugins {
			name := plugin.Name
			version := plugin.Version
			if schemaVersion, ok := plugin.ExtraData["schemaVersion"].(string); ok {
				inf := pluginDetail{
					Name:          name,
					SchemaVersion: schemaVersion}
				plinfoDetails = append(plinfoDetails, inf)
				log.Debugf("plugin %s is version %s, schemaVersion: %s", name, version, schemaVersion)
			}
		}
		if plinfoDetails == nil {
			log.Panicf("No Plugins registered!")
		}

		pgInfo, err := json.Marshal(plinfoDetails)
		if err != nil {
			log.Panicf("Unable to marshal plugin data: %v", err)
		}
		apidPluginDetails = string(pgInfo[:])

		log.Debug("start post plugin init")

		apidTokenManager.start()
		go bootstrap()

		log.Debug("Done post plugin init")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"github.com/thoj/go-ircevent"
	"log"
	"net/url"
	"regexp"
	"strings"
)

var url_re = regexp.MustCompile(`\bhttps?://[^\s]+\b`)

func logprivmsgs(event *irc.Event) {
	log.Print(event.Nick+": ", event.Arguments)
}

func writeurltitle(event *irc.Event) {
	var urls []string = FindURLs(event.Arguments[1])
        var err error

        // URL valid?
        for _, oneurl := range urls {
                _, err = url.Parse(oneurl)
                if err != nil {
                        continue
                }
                log.Print(oneurl)
        }
}

func FindURLs(input string) []string {
	return url_re.FindAllString(input, 5)
}

func main() {
	var myircbot *irc.Connection
	var botname *string
	var serveraddress *string
	var rawchannellist *string
	var channellist []string
	var channelname string
	var err error

	botname = flag.String("botname", "justanotherbot", "Name of the bot")
	serveraddress = flag.String("server-address", "irc.freenode.org:6667", "Server Address")
	rawchannellist = flag.String("channels", "#ancient-solutions", "List of channels")
	flag.Parse()

	channellist = strings.Split(*rawchannellist, ",")

	myircbot = irc.IRC(*botname, *botname)
	if err = myircbot.Connect(*serveraddress); err != nil {
		log.Fatal("Error connecting to server: ", err)
	}

	//Join all channels.
	for _, channelname = range channellist {
		myircbot.Join(channelname)
	}

	//Event handling
	myircbot.AddCallback("PRIVMSG", logprivmsgs)
	myircbot.AddCallback("PRIVMSG", writeurltitle)

	myircbot.Loop()
}
<commit_msg>Now we've got slices filled with the bodies of the given URLs.<commit_after>package main

import (
	"flag"
	"github.com/thoj/go-ircevent"
	"log"
	"net/url"
	"regexp"
	"strings"
        "net/http"
        "io/ioutil"
//        "code.google.com/p/go.net/html"
)

var url_re = regexp.MustCompile(`\bhttps?://[^\s]+\b`)

func logprivmsgs(event *irc.Event) {
	log.Print(event.Nick+": ", event.Arguments)
}

func writeurltitle(event *irc.Event) {
	var urls []string = FindURLs(event.Arguments[1])
        var err error
        var resp *http.Response
        var contentType string
        var respbody []byte

        // URL valid?
        for _, oneurl := range urls {
                _, err = url.Parse(oneurl)
                if err != nil {
                        continue
                }
                resp, err = http.Head(oneurl)
                if err != nil {
                        log.Print("Error getting Head: ", err)
                        continue
                }

                // No HTML?
                contentType = resp.Header.Get("Content-Type")
                if contentType != "text/html" && contentType != "application/xhtml+xml" {
                        continue
                }

                // Get the Body
                resp, err = http.Get(oneurl)
                if err != nil {
                        log.Print("Error during HTTP GET: ", err)
                        continue
                }
                // Close later
                defer resp.Body.Close()

                // Create a slice of bytes from the body.
                respbody, err = ioutil.ReadAll(resp.Body)
                if err != nil {
                        log.Print("Error reading the body: ", err)
                        continue
                }
                log.Print(respbody[0], "1. Byte vom Body")
        }
}

func FindURLs(input string) []string {
	return url_re.FindAllString(input, 5)
}

func main() {
	var myircbot *irc.Connection
	var botname *string
	var serveraddress *string
	var rawchannellist *string
	var channellist []string
	var channelname string
	var err error

	botname = flag.String("botname", "justanotherbot", "Name of the bot")
	serveraddress = flag.String("server-address", "irc.freenode.org:6667", "Server Address")
	rawchannellist = flag.String("channels", "#ancient-solutions", "List of channels")
	flag.Parse()

	channellist = strings.Split(*rawchannellist, ",")

	myircbot = irc.IRC(*botname, *botname)
	if err = myircbot.Connect(*serveraddress); err != nil {
		log.Fatal("Error connecting to server: ", err)
	}

	//Join all channels.
	for _, channelname = range channellist {
		myircbot.Join(channelname)
	}

	//Event handling
	myircbot.AddCallback("PRIVMSG", logprivmsgs)
	myircbot.AddCallback("PRIVMSG", writeurltitle)

	myircbot.Loop()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"html"
	"log"
	"net/http"
	"strings"
)

var bot *tgbotapi.BotAPI

func botRun() error {
	var err error
	bot, err = tgbotapi.NewBotAPI(cfg.Bot.Token)
	if err != nil {
		log.Fatal(err)
	}

	bot.Debug = cfg.Bot.Debug

	log.Println("Authorized on account:", bot.Self.UserName)

	_, err = bot.SetWebhook(tgbotapi.NewWebhookWithCert(fmt.Sprintf("%s%s/%s", cfg.HTTP.Host, cfg.HTTP.Port, cfg.Bot.Token), cfg.HTTP.PublicKey))
	if err != nil {
		log.Fatal(err)
	}

	updates := bot.ListenForWebhook(fmt.Sprintf("/%s", bot.Token))
	go func() {
		if err := http.ListenAndServeTLS(cfg.HTTP.Port, cfg.HTTP.PublicKey, cfg.HTTP.PrivateKey, nil); err != nil {
			log.Fatal(err)
		}
	}()

	for update := range updates {
		msgRouter(update)
	}
	return nil
}

func msgRouter(update tgbotapi.Update) error {
	switch {
	case update.InlineQuery != nil:
		return isInline(update)
	case update.Message != nil && update.Message.IsCommand():
		return isCommand(update)
	case update.Message != nil && (update.Message.Chat.IsPrivate() || bot.IsMessageToMe(*update.Message)):
		return isSearch(update)
	default:
		log.Printf("unsupport message:%#v\n", update)
	}
	return nil
}

func isCommand(update tgbotapi.Update) error {
	switch update.Message.Command() {
	case "s":
		return isSearch(update)
	case "daily":
		return isDaily(update)
	default:
		return sendMsg(update, HelpMsg)
	}
	return nil
}

func isSearch(update tgbotapi.Update) error {
	var msg string
	if update.Message.IsCommand() {
		msg = update.Message.CommandArguments()
	} else {
		msg = update.Message.Text
	}
	msg = strings.Trim(msg, " ")
	if msg == "" {
		return sendMsg(update, HelpMsg)
	}

	results, err := search(msg, cfg.Zhihu.SearchResultNum)
	if err != nil {
		return err
	}

	msg = ""
	for _, result := range results {
		msg = fmt.Sprintf(`%s<a href="%s">%s</a>%s%s <a href="%s">...显示全部</a>%s%s`,
			msg, result.QuestionLink, result.Title, Warp, result.Summary, result.AnswerLink, Warp, Warp)
	}
	return sendMsg(update, msg)
}

func isInline(update tgbotapi.Update) error {
	msg := update.InlineQuery.Query
	results, err := search(msg, cfg.Zhihu.InlineResultNum)
	if err != nil {
		return err
	}
	var answers []interface{}
	for _, result := range results {
		content := html.EscapeString(result.Content)
		if len(content) > 2000 {
			content = Substr(content, 2000)
		}
		msg = fmt.Sprintf(`<a href="%s">%s</a>%s%s <a href="%s">...显示全部</a>%s%s`,
			result.QuestionLink, result.Title, Warp, content, result.AnswerLink, Warp, Warp)
		answer := tgbotapi.NewInlineQueryResultArticleHTML(result.ID, result.Title, msg)
		answer.Description = html.EscapeString(result.Summary)
		inputTextMessageContent := answer.InputMessageContent.(tgbotapi.InputTextMessageContent)
		inputTextMessageContent.DisableWebPagePreview = true
		answer.InputMessageContent = inputTextMessageContent
		answers = append(answers, &answer)
	}
	return answerInlineQuery(update, answers)
}

func isDaily(update tgbotapi.Update) error {
	txt, err := daily()
	if err != nil {
		return err
	}
	return sendMsg(update, txt)
}

func sendMsg(update tgbotapi.Update, txt string) error {
	msg := tgbotapi.NewMessage(update.Message.Chat.ID, txt)
	msg.ParseMode = "HTML"
	msg.DisableWebPagePreview = true
	if resp, err := bot.Send(msg); err != nil {
		log.Println("bot.Send:", err, resp)
		return err
	}
	return nil
}

func answerInlineQuery(update tgbotapi.Update, results []interface{}) error {
	answer := tgbotapi.InlineConfig{
		InlineQueryID: update.InlineQuery.ID,
		CacheTime:     3600,
		Results:       results,
	}
	if resp, err := bot.AnswerInlineQuery(answer); err != nil {
		log.Println("bot.answerInlineQuery:", err, resp)
		return err
	}
	return nil
}
<commit_msg>update<commit_after>package main

import (
	"fmt"
	"html"
	"log"
	"net/http"
	"strings"

	"github.com/go-telegram-bot-api/telegram-bot-api"
)

var bot *tgbotapi.BotAPI

func botRun() error {
	var err error
	bot, err = tgbotapi.NewBotAPI(cfg.Bot.Token)
	if err != nil {
		log.Fatal(err)
	}

	bot.Debug = cfg.Bot.Debug

	log.Println("Authorized on account:", bot.Self.UserName)

	_, err = bot.SetWebhook(tgbotapi.NewWebhookWithCert(fmt.Sprintf("%s%s/%s", cfg.HTTP.Host, cfg.HTTP.Port, cfg.Bot.Token), cfg.HTTP.PublicKey))
	if err != nil {
		log.Fatal(err)
	}

	updates := bot.ListenForWebhook(fmt.Sprintf("/%s", bot.Token))
	go func() {
		if err := http.ListenAndServeTLS(cfg.HTTP.Port, cfg.HTTP.PublicKey, cfg.HTTP.PrivateKey, nil); err != nil {
			log.Fatal(err)
		}
	}()

	for update := range updates {
		msgRouter(update)
	}
	return nil
}

func msgRouter(update tgbotapi.Update) error {
	switch {
	case update.InlineQuery != nil:
		return isInline(update)
	case update.Message != nil && update.Message.IsCommand():
		return isCommand(update)
	case update.Message != nil && (update.Message.Chat.IsPrivate() || bot.IsMessageToMe(*update.Message)):
		return isSearch(update)
	default:
		log.Printf("unsupport message:%#v\n", update)
	}
	return nil
}

func isCommand(update tgbotapi.Update) error {
	switch update.Message.Command() {
	case "s":
		return isSearch(update)
	case "daily":
		return isDaily(update)
	default:
		return sendMsg(update, HelpMsg)
	}
	return nil
}

func isSearch(update tgbotapi.Update) error {
	var msg string
	if update.Message.IsCommand() {
		msg = update.Message.CommandArguments()
	} else {
		msg = update.Message.Text
	}
	msg = strings.Trim(msg, " ")
	if msg == "" {
		return sendMsg(update, HelpMsg)
	}

	results, err := search(msg, cfg.Zhihu.SearchResultNum)
	if err != nil {
		return err
	}

	msg = ""
	for _, result := range results {
		msg = fmt.Sprintf(`%s<a href="%s">%s</a>%s%s <a href="%s">...显示全部</a>%s%s`,
			msg, result.QuestionLink, result.Title, Warp, result.Summary, result.AnswerLink, Warp, Warp)
	}
	return sendMsg(update, msg)
}

func isInline(update tgbotapi.Update) error {
	msg := update.InlineQuery.Query
	results, err := search(msg, cfg.Zhihu.InlineResultNum)
	if err != nil {
		return err
	}
	var answers []interface{}
	for _, result := range results {
		content := html.EscapeString(result.Content)
		if len(content) > 2000 {
			content = Substr(content, 2000)
		}
		msg = fmt.Sprintf(`<a href="%s">%s</a>%s%s <a href="%s">...显示全部</a>%s%s`,
			result.QuestionLink, result.Title, Warp, content, result.AnswerLink, Warp, Warp)
		answer := tgbotapi.NewInlineQueryResultArticleHTML(result.ID, result.Title, msg)
		answer.Description = html.EscapeString(result.Summary)
		inputTextMessageContent := answer.InputMessageContent.(tgbotapi.InputTextMessageContent)
		inputTextMessageContent.DisableWebPagePreview = true
		answer.InputMessageContent = inputTextMessageContent
		answers = append(answers, &answer)
	}
	return answerInlineQuery(update, answers)
}

func isDaily(update tgbotapi.Update) error {
	txt, err := daily()
	if err != nil {
		return err
	}
	return sendMsg(update, txt)
}

func sendMsg(update tgbotapi.Update, txt string) error {
	msg := tgbotapi.NewMessage(update.Message.Chat.ID, txt)
	msg.ParseMode = "HTML"
	msg.DisableWebPagePreview = true
	if resp, err := bot.Send(msg); err != nil {
		log.Println("bot.Send:", err, resp)
		return err
	}
	return nil
}

func answerInlineQuery(update tgbotapi.Update, results []interface{}) error {
	answer := tgbotapi.InlineConfig{
		InlineQueryID: update.InlineQuery.ID,
		CacheTime:     3600,
		Results:       results,
	}
	if resp, err := bot.AnswerInlineQuery(answer); err != nil {
		log.Println("bot.answerInlineQuery:", err, resp)
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"

	"github.com/codegangsta/cli"
	"github.com/mikebeyer/clc-cli/aa"
	"github.com/mikebeyer/clc-cli/alert"
	"github.com/mikebeyer/clc-cli/group"
	"github.com/mikebeyer/clc-cli/lb"
	"github.com/mikebeyer/clc-cli/server"
	"github.com/mikebeyer/clc-cli/status"
	"github.com/mikebeyer/clc-sdk"
	"github.com/mikebeyer/clc-sdk/api"
)

func main() {

	app := cli.NewApp()
	app.Name = "clc"
	app.Usage = "clc v2 api cli"
	app.Version = "0.0.1"
	app.Authors = []cli.Author{
		cli.Author{
			Name:  "Mike Beyer",
			Email: "michael.beyer@ctl.io",
		},
	}
	app.Flags = []cli.Flag{
		cli.BoolFlag{Name: "default-config", Usage: "create template configuration file"},
	}
	app.Action = func(c *cli.Context) {
		if c.Bool("default-config") {

			conf := api.NewConfig("USERNAME", "PASSWORD", "DEFAULT-ALIAS")
			b, err := json.MarshalIndent(conf, "", "  ")
			if err != nil {
				fmt.Printf("unable to generate config template.")
			}

			err = ioutil.WriteFile("./clc.json", b, 0666)
			if err != nil {
				fmt.Printf("unable to generate config template.")
			}
			fmt.Printf("config template written to clc.json")
			return
		} else if !c.Args().Present() {
			cli.ShowAppHelp(c)
		}
	}
	var config api.Config
	config, err := api.FileConfig("./clc.json")
	if err != nil {
		config = api.EnvConfig()
	}

	client := clc.New(config)
	app.Commands = []cli.Command{
		server.Commands(client),
		status.Commands(client),
		aa.Commands(client),
		alert.Commands(client),
		lb.Commands(client),
		group.Commands(client),
	}
	app.Run(os.Args)
}
<commit_msg>added ability to reference config<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"

	"github.com/codegangsta/cli"
	"github.com/mikebeyer/clc-cli/aa"
	"github.com/mikebeyer/clc-cli/alert"
	"github.com/mikebeyer/clc-cli/group"
	"github.com/mikebeyer/clc-cli/lb"
	"github.com/mikebeyer/clc-cli/server"
	"github.com/mikebeyer/clc-cli/status"
	"github.com/mikebeyer/clc-sdk"
	"github.com/mikebeyer/clc-sdk/api"
)

func main() {

	app := cli.NewApp()
	app.Name = "clc"
	app.Usage = "clc v2 api cli"
	app.Version = "0.0.1"
	app.Authors = []cli.Author{
		cli.Author{
			Name:  "Mike Beyer",
			Email: "michael.beyer@ctl.io",
		},
	}
	app.Flags = []cli.Flag{
		cli.BoolFlag{Name: "default-config", Usage: "create template configuration file"},
	}
	var config api.Config
	var configErr error
	app.Action = func(c *cli.Context) {
		fmt.Println("here")
		if c.Bool("default-config") {

			conf := api.NewConfig("USERNAME", "PASSWORD", "DEFAULT-ALIAS")
			b, err := json.MarshalIndent(conf, "", "  ")
			if err != nil {
				fmt.Printf("unable to generate config template.")
			}

			err = ioutil.WriteFile("./clc.json", b, 0666)
			if err != nil {
				fmt.Printf("unable to generate config template.")
			}
			fmt.Printf("config template written to clc.json")
			return
		} else if c.String("config") != "" {
			config, configErr = api.FileConfig(c.String("config"))
			if configErr != nil {
				fmt.Printf("unable to find/parse config: %s", c.String("config"))
			}
		} else if !c.Args().Present() {
			cli.ShowAppHelp(c)
		}
	}

	if config.User.Username == "" {
		config, configErr = api.FileConfig("./clc.json")
		if configErr != nil {
			config = api.EnvConfig()
		}
	}

	client := clc.New(config)
	app.Commands = []cli.Command{
		server.Commands(client),
		status.Commands(client),
		aa.Commands(client),
		alert.Commands(client),
		lb.Commands(client),
		group.Commands(client),
	}
	app.Run(os.Args)
}
<|endoftext|>