Commit 43cec6d

Richard Luby <richluby@gmail.com>
2016-10-28 08:17:44
reorganized to create a single binary
package now compiles into a single binary. compilation and install are simpler. default behavior executes the client
1 parent 084fdcb
client.go
@@ -14,8 +14,8 @@ import (
 	"strings"
 )
 
-// CONFIG determines how the client is configured
-type CONFIG struct {
+// CLIENT_CONFIG determines how the client is configured
+type CLIENT_CONFIG struct {
 	// SERVER is the IP or domain address of the server
 	SERVER string
 	// PORT is the port on which to connect
@@ -26,21 +26,21 @@ type CONFIG struct {
 	USER string
 }
 
-var config CONFIG
+var clientConfig CLIENT_CONFIG
 
 // loadClientConfiguration loads the configuration for the client using the given string
-func loadClientConfiguration(cfgFile string) CONFIG {
+func loadClientConfiguration(cfgFile string) CLIENT_CONFIG {
 	log.Printf("Loading configuration from %s.", cfgFile)
-	_, err := toml.DecodeFile(cfgFile, &config)
+	_, err := toml.DecodeFile(cfgFile, &clientConfig)
 	if err != nil {
 		log.Fatalf("Could not read configuration file: %+v\n", err.Error())
 		os.Exit(EXIT_CODE.FILE_IO_ERROR)
 	}
-	return config
+	return clientConfig
 }
 
 // getRecordFromServer retrieves a record from the server
-func getRecordFromServer(client *http.Client, config CONFIG, numQuestions int) ([]Record, error) {
+func getRecordFromServer(client *http.Client, config CLIENT_CONFIG, numQuestions int) ([]Record, error) {
 	var serverURL string
 	// allows adding configuration for port specific (ie HTTPS) requests
 	switch config.PORT {
@@ -91,15 +91,15 @@ func initUserSession() {
 }
 
 // initializes the client and handles the user interaction
-func main() {
-	config.SERVER = "127.0.0.1"
-	config.PORT = 80
-	config.USE_HTTPS = false
+func ExecuteClient() {
+	clientConfig.SERVER = "127.0.0.1"
+	clientConfig.PORT = 80
+	clientConfig.USE_HTTPS = false
 	filePath := flag.String("file", "", "defines a path to the configuration file")
 	flag.Parse()
 	if strings.Compare(*filePath, "") != 0 {
-		config = loadClientConfiguration(*filePath)
+		clientConfig = loadClientConfiguration(*filePath)
 	}
-	log.Printf("Configuration: %+v", config)
+	log.Printf("Configuration: %+v", clientConfig)
 	initUserSession()
 }
command.go
@@ -58,7 +58,7 @@ var commandArray = []Command{
 			} else if len(args) < 2 {
 				return fmt.Errorf("Could not set the user due to the lack of a user token.")
 			}
-			config.USER = args[0]
+			clientConfig.USER = args[0]
 			return nil
 		}}}
 
@@ -95,7 +95,7 @@ func executeTest(args []string) error {
 			return fmt.Errorf("Error while converting to number: %+v", err)
 		}
 	}
-	recordArray, err = getRecordFromServer(client, config, questions)
+	recordArray, err = getRecordFromServer(client, clientConfig, questions)
 	if err != nil {
 		return fmt.Errorf("Error while request from server: %+v", err)
 	}
questioner.go
@@ -2,97 +2,23 @@
 package main
 
 import (
-	"flag"
-	"github.com/BurntSushi/toml"
-	"io/ioutil"
-	"log"
-	"math/rand"
-	"net/http"
+	"fmt"
 	"os"
-	"path/filepath"
-	"strconv"
-	"time"
 )
 
-// CONFIG defines default for the server
-type CONFIG struct {
-	// LISTEN_ADDRESS defines the local address on which to listen
-	LISTEN_ADDRESS string
-	//LISTEN_PORT defines the the port on which to listen
-	LISTEN_PORT int
-	// PERMIT_BLANK_PASSWORD determines if a password should be provided with the user names
-	PERMIT_BLANK_PASSWORD bool
-	// PRIVATE_KEY defines the path to the server's private key for signing https connections
-	PRIVATE_KEY string
-	// USE_HTTPS determines if the server should use HTTPS
-	USE_HTTPS bool
-	// QUESTIONS contains the path to the questions directory
-	QUESTIONS string
-}
-
-// defaultConfig is used when no configuration file is given
-const defaultConfig = `
-LISTEN_ADDRESS = "127.0.0.1"
-LISTEN_PORT = 80
-PERMIT_BLANK_PASSWORD = true
-USE_HTTPS = false
-PRIVATE_KEY = "~/.ssh/question.priv"
-QUESTIONS = "/path/to/questions"
-`
-
-// Contains the questions from which to pull
-var records []Record
-
-//loadServerConfiguration loads the configuration file
-// cfgFile : the file that contains the configuration
-func loadServerConfiguration(cfgFile string) CONFIG {
-	var contents string
-	var config CONFIG
-	if cfgFile == "" {
-		contents = defaultConfig
-	} else {
-		buffer, err := ioutil.ReadFile(cfgFile)
-		if err != nil {
-			log.Fatalf("Could not read configuration file: %+v\n", err.Error())
-			os.Exit(EXIT_CODE.FILE_IO_ERROR)
-		}
-		contents = string(buffer)
-	}
-	if _, err := toml.Decode(contents, &config); err != nil {
-		log.Fatalf("Could not parse configuration: %+v\n", err.Error())
-		os.Exit(EXIT_CODE.BAD_CONFIG)
-	}
-	return config
-}
-
-// Listen binds the listening server and starts the listening loop
-// serverConfig : contains the configuration to be used
-func Listen(serverConfig CONFIG) {
-	// register the server handlers
-	for _, handler := range handlers {
-		http.HandleFunc(handler.Request, handler.HandleFunction)
-	}
-	log.Fatal(http.ListenAndServe(
-		serverConfig.LISTEN_ADDRESS+":"+
-			strconv.Itoa(serverConfig.LISTEN_PORT),
-		nil))
-}
-
-// main handles starting the listening server
-// the server reads the questions file before establishing a listener
+// main handles starting the application
+// the default behavior prints a usage statement
 func main() {
-	var confFile string
-	var err error
-	flag.StringVar(&confFile, "file", "", "define a specific configuration file to read")
-	flag.StringVar(&confFile, "f", "", "define a specific configuration file to read")
-	flag.Parse()
-	config := loadServerConfiguration(confFile)
-	if err = filepath.Walk(config.QUESTIONS, loadRecords); err != nil {
-		log.Printf("Failed to load questions due to error: %+v", err)
-		os.Exit(EXIT_CODE.FILE_IO_ERROR)
+	if len(os.Args) < 1 {
+		ExecuteClient()
+	}
+	switch os.Args[len(os.Args)-1] {
+	case "server":
+		ExecuteServer()
+	case "client":
+		ExecuteClient()
+	default:
+		fmt.Printf("Usage: %s [options] [client | server]\n", os.Args[0])
+		ExecuteClient()
 	}
-	log.Printf("Loaded %d questions from %s.", len(records), config.QUESTIONS)
-	log.Printf("Configuration: %+v\n", config)
-	rand.Seed(time.Now().Unix())
-	Listen(config)
 }
server.go
@@ -0,0 +1,96 @@
+package main
+
+import (
+	"flag"
+	"github.com/BurntSushi/toml"
+	"io/ioutil"
+	"log"
+	"math/rand"
+	"net/http"
+	"os"
+	"path/filepath"
+	"strconv"
+	"time"
+)
+
+// SERVER_CONFIG defines default for the server
+type SERVER_CONFIG struct {
+	// LISTEN_ADDRESS defines the local address on which to listen
+	LISTEN_ADDRESS string
+	//LISTEN_PORT defines the the port on which to listen
+	LISTEN_PORT int
+	// PERMIT_BLANK_PASSWORD determines if a password should be provided with the user names
+	PERMIT_BLANK_PASSWORD bool
+	// PRIVATE_KEY defines the path to the server's private key for signing https connections
+	PRIVATE_KEY string
+	// USE_HTTPS determines if the server should use HTTPS
+	USE_HTTPS bool
+	// QUESTIONS contains the path to the questions directory
+	QUESTIONS string
+}
+
+// defaultSERVER_CONFIG is used when no SERVER_CONFIGuration file is given
+const defaultServerConfig = `
+LISTEN_ADDRESS = "127.0.0.1"
+LISTEN_PORT = 80
+PERMIT_BLANK_PASSWORD = true
+USE_HTTPS = false
+PRIVATE_KEY = "~/.ssh/question.priv"
+QUESTIONS = "/path/to/questions"
+`
+
+// Contains the questions from which to pull
+var records []Record
+
+//loadServerConfiguration loads the configuration file
+// cfgFile : the file that contains the configuration
+func loadServerConfiguration(cfgFile string) SERVER_CONFIG {
+	var contents string
+	var config SERVER_CONFIG
+	if cfgFile == "" {
+		contents = defaultServerConfig
+	} else {
+		buffer, err := ioutil.ReadFile(cfgFile)
+		if err != nil {
+			log.Fatalf("Could not read configuration file: %+v\n", err.Error())
+			os.Exit(EXIT_CODE.FILE_IO_ERROR)
+		}
+		contents = string(buffer)
+	}
+	if _, err := toml.Decode(contents, &config); err != nil {
+		log.Fatalf("Could not parse configuration: %+v\n", err.Error())
+		os.Exit(EXIT_CODE.BAD_CONFIG)
+	}
+	return config
+}
+
+// Listen binds the listening server and starts the listening loop
+// serverConfig : contains the configuration to be used
+func Listen(serverConfig SERVER_CONFIG) {
+	// register the server handlers
+	for _, handler := range handlers {
+		http.HandleFunc(handler.Request, handler.HandleFunction)
+	}
+	log.Fatal(http.ListenAndServe(
+		serverConfig.LISTEN_ADDRESS+":"+
+			strconv.Itoa(serverConfig.LISTEN_PORT),
+		nil))
+}
+
+func ExecuteServer() {
+	var confFile string
+	var err error
+	flag.StringVar(&confFile, "file", "", "define a specific configuration file to read")
+	flag.StringVar(&confFile, "f", "", "define a specific configuration file to read")
+	flag.Parse()
+	log.Printf("Configuration: %+v\n", flag.Args())
+	serverConfig := loadServerConfiguration(confFile)
+	log.Printf("Configuration: %+v\n", serverConfig)
+	if err = filepath.Walk(serverConfig.QUESTIONS, loadRecords); err != nil {
+		log.Printf("Failed to load questions due to error: %+v", err)
+		os.Exit(EXIT_CODE.FILE_IO_ERROR)
+	}
+	log.Printf("Loaded %d questions from %s.", len(records), serverConfig.QUESTIONS)
+	rand.Seed(time.Now().Unix())
+	Listen(serverConfig)
+}