2015-02-14 08:21:20 +00:00
|
|
|
package hostess
|
|
|
|
|
|
|
|
import (
|
2015-02-14 11:01:13 +00:00
|
|
|
"fmt"
|
|
|
|
"github.com/codegangsta/cli"
|
|
|
|
"os"
|
2015-02-14 11:40:31 +00:00
|
|
|
"strings"
|
2015-02-14 08:21:20 +00:00
|
|
|
)
|
|
|
|
|
2015-02-14 13:01:43 +00:00
|
|
|
// MaybeErrorln will print an error message unless -s is passed
|
2015-02-14 11:01:13 +00:00
|
|
|
func MaybeErrorln(c *cli.Context, message string) {
|
2015-02-14 13:01:43 +00:00
|
|
|
if !c.Bool("s") {
|
2015-02-14 11:07:29 +00:00
|
|
|
os.Stderr.WriteString(fmt.Sprintf("%s: %s\n", c.Command.Name, message))
|
2015-02-14 08:21:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-14 13:01:43 +00:00
|
|
|
// MaybeError will print an error message unless -s is passed and then exit
|
2015-02-14 11:01:13 +00:00
|
|
|
func MaybeError(c *cli.Context, message string) {
|
2015-02-14 11:07:29 +00:00
|
|
|
MaybeErrorln(c, message)
|
2015-02-14 11:01:13 +00:00
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
2015-02-14 13:01:43 +00:00
|
|
|
// MaybePrintln will print a message unless -q or -s is passed
|
2015-02-14 11:01:13 +00:00
|
|
|
func MaybePrintln(c *cli.Context, message string) {
|
2015-02-14 13:01:43 +00:00
|
|
|
if !c.Bool("q") && !c.Bool("s") {
|
2015-02-14 11:01:13 +00:00
|
|
|
fmt.Println(message)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:33:11 +00:00
|
|
|
// MaybeLoadHostFile will try to load, parse, and return a Hostfile. If we
|
|
|
|
// encounter errors we will terminate, unless -f is passed.
|
2015-02-14 11:01:13 +00:00
|
|
|
func MaybeLoadHostFile(c *cli.Context) *Hostfile {
|
2015-03-21 10:01:41 +00:00
|
|
|
hostsfile, errs := LoadHostfile()
|
2015-02-14 11:01:13 +00:00
|
|
|
if len(errs) > 0 && !c.Bool("f") {
|
|
|
|
for _, err := range errs {
|
|
|
|
MaybeErrorln(c, err.Error())
|
|
|
|
}
|
2015-02-14 12:33:11 +00:00
|
|
|
MaybeError(c, "Errors while parsing hostsfile. Try using fix -f")
|
2015-02-14 11:01:13 +00:00
|
|
|
}
|
|
|
|
return hostsfile
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:33:11 +00:00
|
|
|
// StrPadRight adds spaces to the right of a string until it reaches l length.
|
|
|
|
// If the input string is already that long, do nothing.
|
2015-02-14 11:40:31 +00:00
|
|
|
func StrPadRight(s string, l int) string {
|
|
|
|
return s + strings.Repeat(" ", l-len(s))
|
|
|
|
}
|
|
|
|
|
2015-03-02 08:22:05 +00:00
|
|
|
// Add command parses <hostname> <ip> and adds or updates a hostname in the
|
|
|
|
// hosts file
|
2015-02-14 11:01:13 +00:00
|
|
|
func Add(c *cli.Context) {
|
|
|
|
if len(c.Args()) != 2 {
|
|
|
|
MaybeError(c, "expected <hostname> <ip>")
|
|
|
|
}
|
|
|
|
|
|
|
|
hostsfile := MaybeLoadHostFile(c)
|
2015-02-25 07:04:27 +00:00
|
|
|
hostname := NewHostname(c.Args()[0], c.Args()[1], true)
|
2015-02-24 12:17:31 +00:00
|
|
|
|
2015-02-25 07:04:27 +00:00
|
|
|
var err error
|
2015-03-21 09:40:19 +00:00
|
|
|
if !hostsfile.Hosts.Contains(hostname) {
|
|
|
|
err = hostsfile.Hosts.Add(hostname)
|
2015-02-14 12:33:11 +00:00
|
|
|
}
|
|
|
|
|
2015-02-14 11:01:13 +00:00
|
|
|
if err == nil {
|
|
|
|
if c.Bool("n") {
|
|
|
|
fmt.Println(hostsfile.Format())
|
|
|
|
} else {
|
2015-03-02 08:55:34 +00:00
|
|
|
MaybePrintln(c, fmt.Sprintf("Added %s", hostname.FormatHuman()))
|
2015-02-14 11:01:13 +00:00
|
|
|
hostsfile.Save()
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
MaybeError(c, err.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-02 08:22:05 +00:00
|
|
|
// Del command removes any hostname(s) matching <domain> from the hosts file
|
2015-02-14 12:33:11 +00:00
|
|
|
func Del(c *cli.Context) {
|
|
|
|
if len(c.Args()) != 1 {
|
|
|
|
MaybeError(c, "expected <hostname>")
|
|
|
|
}
|
|
|
|
domain := c.Args()[0]
|
|
|
|
hostsfile := MaybeLoadHostFile(c)
|
|
|
|
|
2015-03-21 09:40:19 +00:00
|
|
|
found := hostsfile.Hosts.ContainsDomain(domain)
|
2015-02-14 12:33:11 +00:00
|
|
|
if found {
|
2015-03-21 09:40:19 +00:00
|
|
|
hostsfile.Hosts.RemoveDomain(domain)
|
2015-02-14 12:33:11 +00:00
|
|
|
if c.Bool("n") {
|
|
|
|
fmt.Println(hostsfile.Format())
|
|
|
|
} else {
|
|
|
|
MaybePrintln(c, fmt.Sprintf("Deleted %s", domain))
|
|
|
|
hostsfile.Save()
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
MaybePrintln(c, fmt.Sprintf("%s not found in %s", domain, GetHostsPath()))
|
|
|
|
}
|
2015-02-14 08:21:20 +00:00
|
|
|
}
|
|
|
|
|
2015-03-02 08:22:05 +00:00
|
|
|
// Has command indicates whether a hostname is present in the hosts file
|
2015-02-14 12:33:11 +00:00
|
|
|
func Has(c *cli.Context) {
|
|
|
|
if len(c.Args()) != 1 {
|
|
|
|
MaybeError(c, "expected <hostname>")
|
|
|
|
}
|
|
|
|
domain := c.Args()[0]
|
|
|
|
hostsfile := MaybeLoadHostFile(c)
|
|
|
|
|
2015-03-21 09:40:19 +00:00
|
|
|
found := hostsfile.Hosts.ContainsDomain(domain)
|
2015-02-14 12:33:11 +00:00
|
|
|
if found {
|
|
|
|
MaybePrintln(c, fmt.Sprintf("Found %s in %s", domain, GetHostsPath()))
|
|
|
|
} else {
|
|
|
|
MaybeError(c, fmt.Sprintf("%s not found in %s", domain, GetHostsPath()))
|
|
|
|
}
|
|
|
|
|
2015-02-14 08:21:20 +00:00
|
|
|
}
|
|
|
|
|
2015-03-02 08:22:05 +00:00
|
|
|
// Off command disables (comments) the specified hostname in the hosts file
|
2015-02-14 12:33:11 +00:00
|
|
|
func Off(c *cli.Context) {
|
|
|
|
if len(c.Args()) != 1 {
|
|
|
|
MaybeError(c, "expected <hostname>")
|
|
|
|
}
|
|
|
|
|
2015-02-14 08:21:20 +00:00
|
|
|
}
|
|
|
|
|
2015-03-02 08:22:05 +00:00
|
|
|
// On command enabled (uncomments) the specified hostname in the hosts file
|
2015-02-14 12:33:11 +00:00
|
|
|
func On(c *cli.Context) {
|
|
|
|
if len(c.Args()) != 1 {
|
|
|
|
MaybeError(c, "expected <hostname>")
|
|
|
|
}
|
2015-02-14 08:21:20 +00:00
|
|
|
}
|
|
|
|
|
2015-03-02 08:22:05 +00:00
|
|
|
// Ls command shows a list of hostnames in the hosts file
|
2015-02-14 11:40:31 +00:00
|
|
|
func Ls(c *cli.Context) {
|
2015-02-14 12:33:11 +00:00
|
|
|
hostsfile := MaybeLoadHostFile(c)
|
2015-02-14 11:40:31 +00:00
|
|
|
maxdomain := 0
|
|
|
|
maxip := 0
|
2015-02-14 12:33:11 +00:00
|
|
|
for _, hostname := range hostsfile.Hosts {
|
2015-02-14 11:40:31 +00:00
|
|
|
dlen := len(hostname.Domain)
|
|
|
|
if dlen > maxdomain {
|
|
|
|
maxdomain = dlen
|
|
|
|
}
|
2015-03-02 08:55:34 +00:00
|
|
|
ilen := len(hostname.IP)
|
2015-02-14 11:40:31 +00:00
|
|
|
if ilen > maxip {
|
|
|
|
maxip = ilen
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-25 10:33:18 +00:00
|
|
|
// for _, domain := range hostsfile.ListDomains() {
|
|
|
|
// hostname := hostsfile.Hosts[domain]
|
|
|
|
// fmt.Printf("%s -> %s %s\n",
|
|
|
|
// StrPadRight(hostname.Domain, maxdomain),
|
|
|
|
// StrPadRight(hostname.Ip.String(), maxip),
|
|
|
|
// ShowEnabled(hostname.Enabled))
|
|
|
|
// }
|
2015-02-14 08:21:20 +00:00
|
|
|
}
|
|
|
|
|
2015-03-02 09:46:12 +00:00
|
|
|
const fixHelp = `Programmatically rewrite your hostsfile.
|
2015-02-14 11:01:13 +00:00
|
|
|
|
|
|
|
Domains pointing to the same IP will be consolidated, sorted, and extra
|
|
|
|
whitespace and comments will be removed.
|
|
|
|
|
|
|
|
hostess fix Rewrite the hostsfile
|
|
|
|
hostess fix -n Show the new hostsfile. Don't write it
|
|
|
|
`
|
|
|
|
|
2015-03-02 08:22:05 +00:00
|
|
|
// Fix command removes duplicates and conflicts from the hosts file
|
2015-02-14 11:01:13 +00:00
|
|
|
func Fix(c *cli.Context) {
|
2015-02-14 12:33:11 +00:00
|
|
|
hostsfile := MaybeLoadHostFile(c)
|
2015-02-14 11:01:13 +00:00
|
|
|
if c.Bool("n") {
|
2015-02-14 12:33:11 +00:00
|
|
|
fmt.Println(hostsfile.Format())
|
2015-02-14 11:01:13 +00:00
|
|
|
} else {
|
2015-02-14 12:33:11 +00:00
|
|
|
hostsfile.Save()
|
2015-02-14 11:01:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-02 08:22:05 +00:00
|
|
|
// Dump command outputs hosts file contents as JSON
|
2015-02-14 12:33:11 +00:00
|
|
|
func Dump(c *cli.Context) {
|
|
|
|
|
2015-02-14 08:21:20 +00:00
|
|
|
}
|
|
|
|
|
2015-03-02 08:22:05 +00:00
|
|
|
// Apply command adds hostnames to the hosts file from JSON
|
2015-02-14 12:33:11 +00:00
|
|
|
func Apply(c *cli.Context) {
|
|
|
|
|
2015-02-14 08:21:20 +00:00
|
|
|
}
|