Esempio n. 1
0
func startWallet(msgDB *msgdb.MsgDB, offline bool) (*client.Client, error) {
	// get wallet key
	wk, err := msgDB.GetValue(msgdb.WalletKey)
	if err != nil {
		return nil, err
	}
	walletKey, err := decodeWalletKey(wk)
	if err != nil {
		return nil, err
	}

	// create wallet
	client, err := trivial.New(msgDB.DB(), walletKey, def.CACert)
	if err != nil {
		return nil, err
	}
	if !offline {
		client.GoOnline()
		err = client.GetVerifyKeys()
		if err != nil {
			return nil, err
		}
	}

	return client, nil
}
Esempio n. 2
0
func (ce *CtrlEngine) upkeepFetchconf(
	msgDB *msgdb.MsgDB,
	homedir string,
	show bool,
	outfp, statfp io.Writer,
) error {
	netDomain, pubkeyStr, configURL := def.ConfigParams()
	log.Infof("fetch config for '%s'", netDomain)
	fmt.Fprintf(statfp, "fetch config for '%s'\n", netDomain)
	publicKey, err := hex.DecodeString(pubkeyStr)
	if err != nil {
		log.Error(err)
	}
	ce.config.PublicKey = publicKey
	ce.config.URLList = "10," + configURL
	ce.config.Timeout = 0 // use default timeout
	if err := ce.config.Update(); err != nil {
		return log.Error(err)
	}
	jsn, err := json.Marshal(ce.config)
	if err != nil {
		return log.Error(err)
	}
	if err := msgDB.AddValue(netDomain, string(jsn)); err != nil {
		return err
	}
	err = msgDB.AddValue("time."+netDomain, strconv.FormatInt(times.Now(), 10))
	if err != nil {
		return err
	}
	// apply new configuration
	if err := def.InitMute(&ce.config); err != nil {
		return err
	}
	// format configuration nicely
	jsn, err = json.MarshalIndent(ce.config, "", "  ")
	if err != nil {
		return log.Error(err)
	}
	// write new configuration file
	if err := writeConfigFile(homedir, netDomain, jsn); err != nil {
		return err
	}
	// show new configuration
	if show {
		fmt.Fprintf(outfp, string(jsn)+"\n")
	}
	return nil
}
Esempio n. 3
0
func muteprotoFetch(
	myID, contactID string,
	msgDB *msgdb.MsgDB,
	c *cli.Context,
	privkey, server string,
	lastMessageTime int64,
) (newMessageTime int64, err error) {
	log.Debug("muteprotoFetch()")
	args := []string{
		"--homedir", c.GlobalString("homedir"),
		"--loglevel", c.GlobalString("loglevel"),
		"--logdir", c.GlobalString("logdir"),
		"fetch",
		"--server", server,
		"--last-message-time", strconv.FormatInt(lastMessageTime, 10),
	}
	cmd := exec.Command("muteproto", args...)
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return 0, err
	}
	stderr, err := cmd.StderrPipe()
	if err != nil {
		return 0, err
	}
	ppR, ppW, err := os.Pipe()
	if err != nil {
		return 0, err
	}
	defer ppR.Close()
	ppW.Write([]byte(privkey))
	ppW.Close()
	cmd.ExtraFiles = append(cmd.ExtraFiles, ppR)
	cmdR, cmdW, err := os.Pipe()
	if err != nil {
		return 0, err
	}
	defer cmdR.Close()
	defer cmdW.Close()
	cmd.ExtraFiles = append(cmd.ExtraFiles, cmdR)
	if err := cmd.Start(); err != nil {
		return 0, err
	}
	var outbuf bytes.Buffer
	status := bufio.NewReader(stderr)
	input := make(chan []byte)
	go func() {
		for {
			buf := make([]byte, 4096)
			n, err := stdout.Read(buf)
			if n > 0 {
				input <- buf[:n]
			}
			if err != nil {
				if err == io.EOF {
					return
				}
				log.Error(err)
				return
			}
		}
	}()
	firstMessage := true
	cache, err := msgDB.GetMessageIDCache(myID, contactID)
	if err != nil {
		return 0, err
	}
	for {
		// read status output
		line, err := status.ReadString('\n')
		if err != nil {
			return 0, log.Error(err)
		}
		line = strings.TrimSpace(line)
		if line == "NONE" {
			log.Debug("read: NONE")
			break
		}
		if strings.HasSuffix(line, "accountdb: nothing found") {
			log.Info("account has no messages")
			return 0, nil
		}
		parts := strings.Split(line, "\t")
		if len(parts) != 2 || parts[0] != "MESSAGEID:" {
			return 0, log.Errorf("ctrlengine: MESSAGEID line expected from muteproto, got: %s", line)
		}
		messageID := parts[1]
		log.Debugf("read: MESSAGEID:\t%s", messageID)
		if cache[messageID] {
			// message known -> abort fetching messages and remove old IDs from cache
			log.Debug("write: QUIT")
			fmt.Fprintln(cmdW, "QUIT")
			err := msgDB.RemoveMessageIDCache(myID, contactID, messageID)
			if err != nil {
				return 0, log.Error(err)
			}
			break
		} else {
			// message unknown -> fetch it and add messageID to cache
			log.Debug("write: NEXT")
			fmt.Fprintln(cmdW, "NEXT")
			err := msgDB.AddMessageIDCache(myID, contactID, messageID)
			if err != nil {
				return 0, log.Error(err)
			}
		}
		// read message
		stop := make(chan uint64)
		done := make(chan bool)
		go func() {
			for {
				select {
				case buf := <-input:
					outbuf.Write(buf)
				case length := <-stop:
					for uint64(outbuf.Len()) < length {
						buf := <-input
						outbuf.Write(buf)
					}
					done <- true
					return
				}
			}
		}()
		// read LENGTH
		line, err = status.ReadString('\n')
		if err != nil {
			return 0, log.Error(err)
		}
		parts = strings.Split(strings.TrimRight(line, "\n"), "\t")
		if len(parts) != 2 || parts[0] != "LENGTH:" {
			return 0, log.Errorf("ctrlengine: LENGTH line expected from muteproto, got: %s", line)
		}
		length, err := strconv.ParseUint(parts[1], 10, 64)
		if err != nil {
			return 0, log.Error(err)
		}
		log.Debugf("read: LENGTH:\t%d", length)
		// read RECEIVETIME
		line, err = status.ReadString('\n')
		if err != nil {
			return 0, log.Error(err)
		}
		parts = strings.Split(strings.TrimRight(line, "\n"), "\t")
		if len(parts) != 2 || parts[0] != "RECEIVETIME:" {
			return 0, log.Errorf("ctrlengine: RECEIVETIME line expected from muteproto, got: %s", line)
		}
		receiveTime, err := strconv.ParseInt(parts[1], 10, 64)
		if err != nil {
			return 0, log.Error(err)
		}
		log.Debugf("read: RECEIVETIME:\t%d", receiveTime)

		stop <- length
		<-done
		err = msgDB.AddInQueue(myID, contactID, receiveTime, outbuf.String())
		if err != nil {
			return 0, err
		}
		if firstMessage {
			newMessageTime = receiveTime
			firstMessage = false
		}
		outbuf.Reset()
	}
	if err := cmd.Wait(); err != nil {
		return 0, err
	}
	return
}