Files
mostlymatter/vendor/github.com/mattermost/rsc/google/main.go
Christopher Speller 38ee83e45b Moving to glide
2016-05-12 23:56:07 -04:00

182 строки
3.4 KiB
Go

// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// TODO: Something about redialing.
package google
import (
// "flag"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net"
"net/rpc"
"os"
"os/exec"
"syscall"
"time"
)
func Dir() string {
dir := os.Getenv("HOME") + "/.goog"
st, err := os.Stat(dir)
if err != nil {
if err := os.Mkdir(dir, 0700); err != nil {
log.Fatal(err)
}
st, err = os.Stat(dir)
if err != nil {
log.Fatal(err)
}
}
if !st.IsDir() {
log.Fatalf("%s exists but is not a directory", dir)
}
if st.Mode()&0077 != 0 {
log.Fatalf("%s exists but allows group or other permissions: %#o", dir, st.Mode()&0777)
}
return dir
}
func Dial() (*Client, error) {
socket := Dir() + "/socket"
c, err := net.Dial("unix", socket)
if err == nil {
return &Client{rpc.NewClient(c)}, nil
}
log.Print("starting server")
os.Remove(socket)
runServer()
for i := 0; i < 50; i++ {
c, err = net.Dial("unix", socket)
if err == nil {
return &Client{rpc.NewClient(c)}, nil
}
time.Sleep(200e6)
if i == 0 {
log.Print("waiting for server...")
}
}
return nil, err
}
type Client struct {
client *rpc.Client
}
type Empty struct{}
func (g *Client) Ping() error {
return g.client.Call("goog.Ping", &Empty{}, &Empty{})
}
func (g *Client) Accounts() ([]string, error) {
var out []string
if err := g.client.Call("goog.Accounts", &Empty{}, &out); err != nil {
return nil, err
}
return out, nil
}
func runServer() {
cmd := exec.Command("googleserver", "serve")
cmd.SysProcAttr = &syscall.SysProcAttr{}
if err := cmd.Start(); err != nil {
log.Fatal(err)
}
}
type Config struct {
Account []*Account
}
type Account struct {
Email string
Password string
Nick string
}
func (cfg *Config) AccountByEmail(email string) *Account {
for _, a := range cfg.Account {
if a.Email == email {
return a
}
}
return nil
}
var Cfg Config
func ReadConfig() {
file := Dir() + "/config"
st, err := os.Stat(file)
if err != nil {
return
}
if st.Mode()&0077 != 0 {
log.Fatalf("%s exists but allows group or other permissions: %#o", file, st.Mode()&0777)
}
data, err := ioutil.ReadFile(file)
if err != nil {
log.Fatal(err)
}
Cfg = Config{}
if err := json.Unmarshal(data, &Cfg); err != nil {
log.Fatal(err)
}
}
func WriteConfig() {
file := Dir() + "/config"
st, err := os.Stat(file)
if err != nil {
if err := ioutil.WriteFile(file, nil, 0600); err != nil {
log.Fatal(err)
}
st, err = os.Stat(file)
if err != nil {
log.Fatal(err)
}
}
if st.Mode()&0077 != 0 {
log.Fatalf("%s exists but allows group or other permissions: %#o", file, st.Mode()&0777)
}
data, err := json.MarshalIndent(&Cfg, "", "\t")
if err != nil {
log.Fatal(err)
}
if err := ioutil.WriteFile(file, data, 0600); err != nil {
log.Fatal(err)
}
st, err = os.Stat(file)
if err != nil {
log.Fatal(err)
}
if st.Mode()&0077 != 0 {
log.Fatalf("%s allows group or other permissions after writing: %#o", file, st.Mode()&0777)
}
}
func Acct(name string) Account {
ReadConfig()
if name == "" {
if len(Cfg.Account) == 0 {
fmt.Fprintf(os.Stderr, "no accounts configured\n")
os.Exit(2)
}
return *Cfg.Account[0]
}
for _, a := range Cfg.Account {
if a.Email == name || a.Nick == name {
return *a
}
}
fmt.Fprintf(os.Stderr, "cannot find account %#q", name)
os.Exit(2)
panic("not reached")
}