Exemple #1
0
func TestImap(t *testing.T) {
	var user, pw string
	if mock {
		testDial = fakeDial
		user = "******"
		pw = "password"
	} else {
		acct := google.Acct("*****@*****.**")
		user = acct.Email
		pw = acct.Password
	}
	c, err := NewClient(TLS, "imap.gmail.com", user, pw, "")
	if err != nil {
		t.Fatal(err)
	}

	inbox := c.Inbox()
	msgs := inbox.Msgs()

	for _, m := range msgs {
		if m.UID == 611764547<<32|57046 {
			//			c.io.lock()
			//			c.cmd(c.boxByName[`[Gmail]/All Mail`], `UID SEARCH X-GM-RAW "label:[email protected] in:inbox in:unread -in:muted"`)
			//			c.cmd(c.inbox, `UID SEARCH X-GM-RAW "label:[email protected] in:inbox in:unread -in:muted"`)
			//			c.cmd(c.boxByName[`To Read`], `UID SEARCH X-GM-RAW "label:[email protected] in:inbox in:unread -in:muted"`)
			//			c.cmd(c.boxByName[`[Gmail]/All Mail`], `UID SEARCH X-GM-RAW "label:[email protected] in:inbox in:unread -in:muted"`)
			//			c.fetch(m.Root.Child[0], "")
			//			c.io.unlock()
			fmt.Println("--")
			fmt.Println("From:", m.Hdr.From)
			fmt.Println("To:", m.Hdr.To)
			fmt.Println("Subject:", m.Hdr.Subject)
			fmt.Println("M-Date:", time.Unix(m.Date, 0))
			fmt.Println("Date:", m.Hdr.Date)
			fmt.Println()
			fmt.Println(string(m.Root.Child[0].Text()))
			fmt.Println("--")
		}
	}
	c.Close()
}
Exemple #2
0
func main() {
	flag.BoolVar(&imap.Debug, "imapdebug", false, "imap debugging trace")
	flag.Parse()

	acct = google.Acct(*acctName)

	if args := flag.Args(); len(args) > 0 {
		for i := range args {
			args[i] = "-to=" + args[i]
		}
		cmd := exec.Command("gmailsend", append([]string{"-a", acct.Email, "-i"}, args...)...)
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		if err := cmd.Run(); err != nil {
			fmt.Fprintf(os.Stderr, "!%s\n", err)
			os.Exit(1)
		}
		return
	}

	c, err := imap.NewClient(imap.TLS, "imap.gmail.com", acct.Email, acct.Password, "")
	if err != nil {
		log.Fatal(err)
	}
	isGmail = c.IsGmail()
	threaded = isGmail

	inbox = c.Inbox()
	if err := inbox.Check(); err != nil {
		log.Fatal(err)
	}

	msgs = inbox.Msgs()
	maxfrom = 12
	for i, m := range msgs {
		msgNum[m] = i
		if n := len(from(m.Hdr)); n > maxfrom {
			maxfrom = n
		}
	}
	if maxfrom > 20 {
		maxfrom = 20
	}
	subjlen = 80 - maxfrom

	rethread()

	go func() {
		for sig := range signal.Incoming {
			if sig == os.SIGINT {
				fmt.Fprintf(os.Stderr, "!interrupt\n")
				interrupted = true
				continue
			}
			if sig == os.SIGCHLD || sig == os.SIGWINCH {
				continue
			}
			fmt.Fprintf(os.Stderr, "!%s\n", sig)
		}
	}()

	for {
		if dot != nil {
			fmt.Fprintf(bout, "%d", msgNum[dot.Msg]+1)
			if dot != &dot.Msg.Root {
				fmt.Fprintf(bout, ".%s", dot.ID)
			}
		}
		fmt.Fprintf(bout, ": ")
		bout.Flush()

		line, err := bin.ReadString('\n')
		if err != nil {
			break
		}

		cmd, err := parsecmd(line)
		if err != nil {
			fmt.Fprintf(bout, "!%s\n", err)
			continue
		}

		if cmd.Targ != nil || cmd.Targs == nil && cmd.A2 == 0 {
			x := cmd.F(cmd, cmd.Targ)
			if x != nil {
				dot = x
			}
		} else {
			targs := cmd.Targs
			if targs == nil {
				delta := +1
				if cmd.A1 > cmd.A2 {
					delta = -1
				}
				for i := cmd.A1; i <= cmd.A2; i += delta {
					if i < 1 || i > len(msgs) {
						continue
					}
					targs = append(targs, msgs[i-1])
				}
			}
			if cmd.Thread {
				if !isGmail {
					fmt.Fprintf(bout, "!need gmail for threaded command\n")
					continue
				}
				byThread := make(map[uint64][]*imap.Msg)
				for _, m := range msgs {
					t := m.GmailThread
					byThread[t] = append(byThread[t], m)
				}
				for _, m := range targs {
					t := m.GmailThread
					if byThread[t] != nil {
						if cmd.TF != nil {
							if x := cmd.TF(cmd, byThread[t]); x != nil {
								dot = x
							}
						} else {
							for _, mm := range byThread[t] {
								x := cmd.F(cmd, &mm.Root)
								if x != nil {
									dot = x
								}
							}
						}
					}
					delete(byThread, t)
				}
				continue
			}
			for _, m := range targs {
				if cmd.Delete {
					dcmd(cmd, &m.Root)
					if cmd.Name == "p" {
						// dp is a special case: it advances to the next message before the p.
						next := nextMsg(m)
						if next == nil {
							fmt.Fprintf(bout, "!address\n")
							dot = &m.Root
							break
						}
						m = next
					}
				}
				x := cmd.F(cmd, &m.Root)
				if x != nil {
					dot = x
				}
				// TODO: Break loop on interrupt.
			}
		}
	}
	qcmd(nil, nil)
}
Exemple #3
0
func main() {
	flag.Usage = usage
	flag.Parse()

	acct = google.Acct(*acctName)

	aw, err := acme.New()
	if err != nil {
		log.Fatal(err)
	}
	aw.Name("Chat/" + acct.Nick + "/")

	client, err = xmpp.NewClient("talk.google.com:443", acct.Email, acct.Password)
	if err != nil {
		log.Fatal(err)
	}

	w := &Window{Win: aw, typ: "main", name: "Chat/" + acct.Nick + "/"}
	data, err := ioutil.ReadFile(google.Dir() + "/chat." + acct.Nick)
	if err != nil {
		log.Fatal(err)
	}
	if err == nil {
		w.Write("body", data)
	}
	mainWin = w
	active[w.name] = w
	go w.readAcme()
	client.Roster()
	setStatus(status)
	go w.readChat()
	lastActivity = time.Now()

	tick := time.Tick(0.5e9)
Loop:
	for len(active) > 0 {
		select {
		case w := <-acmeChan:
			if w == nil {
				// Sync with reader.
				continue
			}
			if w.err != nil {
				if active[w.name] == nil {
					continue
				}
				log.Fatal(w.err)
			}
			if *acmeDebug {
				fmt.Fprintf(os.Stderr, "%s %c%c %d,%d %q\n", w.name, w.C1, w.C2, w.Q0, w.Q1, w.Text)
			}
			if w.C1 == 'M' || w.C1 == 'K' {
				lastActivity = time.Now()
				if status != xmpp.Available {
					setStatus(xmpp.Available)
				}
			}
			if (w.C2 == 'x' || w.C2 == 'X') && string(w.Text) == "Del" {
				// TODO: Hangup connection for w.typ == "acct"?
				delete(active, w.name)
				w.Del(true)
				continue Loop
			}

			switch w.typ {
			case "main":
				switch w.C2 {
				case 'L': // Button 3 in body: load chat window for contact.
					w.expand()
					fallthrough
				case 'l': // Button 3 in tag
					arg := string(w.Text)
					showContact(arg)
					continue Loop
				}
			case "chat":
				if w.C1 == 'F' && w.C2 == 'I' {
					continue Loop
				}
				if w.C1 != 'M' && w.C1 != 'K' {
					break
				}
				if w.blinky {
					w.blinky = false
					w.Fprintf("ctl", "dirty\n")
				}
				switch w.C2 {
				case 'X', 'x':
					if string(w.Text) == "Ack" {
						w.Fprintf("ctl", "clean\n")
					}
				case 'I':
					w.sendMsg()
					continue Loop
				}
			}
			w.WriteEvent(w.Event)

		case msg := <-msgChan:
			w := msg.w
			if msg.err != nil {
				w.Fprintf("body", "ERROR: %s\n", msg.err)
				continue Loop
			}
			you := msg.Remote
			if i := strings.Index(you, "/"); i >= 0 {
				you = you[:i]
			}
			switch msg.Type {
			case "chat":
				w := showContact(you)
				text := strings.TrimSpace(msg.Text)
				if text == "" {
					// Probably a composing notification.
					continue
				}
				w.message("> %s\n", text)
				w.blinky = true
				w.dirty = true

			case "presence":
				pr := msg.Presence
				pr, new := savePresence(pr, you)
				if !new {
					continue
				}
				w := lookContact(you)
				if w != nil {
					w.status(pr)
				}
				mainStatus(pr, you)
			}

		case t := <-tick:
			switch status {
			case xmpp.Available:
				if t.Sub(lastActivity) > awayTime {
					setStatus(xmpp.Away)
				}
			case xmpp.Away:
				if t.Sub(lastActivity) > extendedAwayTime {
					setStatus(xmpp.ExtendedAway)
				}
			}
			for _, w := range active {
				if w.blinky {
					w.dirty = !w.dirty
					if w.dirty {
						w.Fprintf("ctl", "dirty\n")
					} else {
						w.Fprintf("ctl", "clean\n")
					}
				}
			}
		}
	}
}
Exemple #4
0
func main() {
	flag.StringVar(&inReplyTo, "in-reply-to", "", "In-Reply-To")
	flag.StringVar(&subject, "s", "", "Subject")
	flag.Var(&from, "from", "From (can repeat)")
	flag.Var(&to, "to", "To (can repeat)")
	flag.Var(&cc, "cc", "CC (can repeat)")
	flag.Var(&bcc, "bcc", "BCC (can repeat)")
	flag.Var(&replyTo, "replyTo", "Reply-To (can repeat)")

	flag.Parse()
	if flag.NArg() != 0 && !*inputHeader {
		flag.Usage()
	}

	var body bytes.Buffer
	input := bufio.NewReader(os.Stdin)
	if *inputHeader {
		holdmode()
	Loop:
		for {
			s, err := input.ReadString('\n')
			if err != nil {
				if err == io.EOF {
					break Loop
				}
				fmt.Fprintf(os.Stderr, "reading stdin: %s\n", err)
				os.Exit(2)
			}
			var arg string
			switch {
			default:
				if ok, _ := regexp.MatchString(`^\S+:`, s); ok {
					fmt.Fprintf(os.Stderr, "unknown header line: %s", s)
					os.Exit(2)
				}
				body.WriteString(s)
				break Loop
			case match(s, "from:", &arg):
				from.parseLine(arg)
			case match(s, "to:", &arg):
				to.parseLine(arg)
			case match(s, "cc:", &arg):
				cc.parseLine(arg)
			case match(s, "bcc:", &arg):
				bcc.parseLine(arg)
			case match(s, "reply-to:", &arg):
				replyTo.parseLine(arg)
			case match(s, "subject:", &arg):
				subject = arg
			case match(s, "in-reply-to:", &arg):
				inReplyTo = arg
			}
		}
	}

	acct = google.Acct(*acctName)
	from.fixDomain()
	to.fixDomain()
	cc.fixDomain()
	bcc.fixDomain()
	replyTo.fixDomain()

	smtpTo := append(append(to, cc...), bcc...)

	if len(from) == 0 {
		// TODO: Much better
		name := ""
		email := acct.Email
		if email == "*****@*****.**" || email == "*****@*****.**" {
			name = "Russ Cox"
		}
		if email == "*****@*****.**" && (smtpTo.has("*****@*****.**") || smtpTo.has("*****@*****.**") || smtpTo.has("*****@*****.**")) {
			from = append(from, Addr{name, "*****@*****.**"})
		} else {
			from = append(from, Addr{name, email})
		}
	}

	if len(from) > 1 {
		fmt.Fprintf(os.Stderr, "missing -from\n")
		os.Exit(2)
	}

	if len(to)+len(cc)+len(bcc) == 0 {
		fmt.Fprintf(os.Stderr, "missing destinations\n")
		os.Exit(2)
	}

	if !*inputHeader {
		holdmode()
	}
	_, err := io.Copy(&body, input)
	if err != nil {
		fmt.Fprintf(os.Stderr, "reading stdin: %s\n", err)
		os.Exit(2)
	}

	if *appendFile != "" {
		f, err := os.Open(*appendFile)
		if err != nil {
			fmt.Fprintf(os.Stderr, "append: %s\n", err)
			os.Exit(2)
		}
		_, err = io.Copy(&body, f)
		f.Close()
		if err != nil {
			fmt.Fprintf(os.Stderr, "append: %s\n", err)
			os.Exit(2)
		}
	}

	var msg bytes.Buffer
	fmt.Fprintf(&msg, "MIME-Version: 1.0\n")
	if len(from) > 0 {
		fmt.Fprintf(&msg, "From: ")
		for i, a := range from {
			if i > 0 {
				fmt.Fprintf(&msg, ", ")
			}
			fmt.Fprintf(&msg, "%s", a.enc())
		}
		fmt.Fprintf(&msg, "\n")
	}
	if len(to) > 0 {
		fmt.Fprintf(&msg, "To: ")
		for i, a := range to {
			if i > 0 {
				fmt.Fprintf(&msg, ", ")
			}
			fmt.Fprintf(&msg, "%s", a.enc())
		}
		fmt.Fprintf(&msg, "\n")
	}
	if len(cc) > 0 {
		fmt.Fprintf(&msg, "CC: ")
		for i, a := range cc {
			if i > 0 {
				fmt.Fprintf(&msg, ", ")
			}
			fmt.Fprintf(&msg, "%s", a.enc())
		}
		fmt.Fprintf(&msg, "\n")
	}
	if len(replyTo) > 0 {
		fmt.Fprintf(&msg, "Reply-To: ")
		for i, a := range replyTo {
			if i > 0 {
				fmt.Fprintf(&msg, ", ")
			}
			fmt.Fprintf(&msg, "%s", a.enc())
		}
		fmt.Fprintf(&msg, "\n")
	}
	if inReplyTo != "" {
		fmt.Fprintf(&msg, "In-Reply-To: %s\n", inReplyTo)
	}
	if subject != "" {
		fmt.Fprintf(&msg, "Subject: %s\n", enc(subject))
	}
	fmt.Fprintf(&msg, "Date: xxx\n")
	fmt.Fprintf(&msg, "Content-Type: text/plain; charset=\"utf-8\"\n")
	fmt.Fprintf(&msg, "Content-Transfer-Encoding: base64\n")
	fmt.Fprintf(&msg, "\n")
	enc64 := base64.StdEncoding.EncodeToString(body.Bytes())
	for len(enc64) > 72 {
		fmt.Fprintf(&msg, "%s\n", enc64[:72])
		enc64 = enc64[72:]
	}
	fmt.Fprintf(&msg, "%s\n\n", enc64)

	auth := smtp.PlainAuth(
		"",
		acct.Email,
		acct.Password,
		"smtp.gmail.com",
	)
	var smtpToEmail []string
	for _, a := range smtpTo {
		if a.Email != "" {
			smtpToEmail = append(smtpToEmail, a.Email)
		}
	}

	if err := sendMail("smtp.gmail.com:587", auth, from[0].Email, smtpToEmail, msg.Bytes()); err != nil {
		fmt.Fprintf(os.Stderr, "sending mail: %s\n", err)
		os.Exit(2)
	}
}