Commit Diff


commit - /dev/null
commit + 1fdf07b79b193a5a1caf7d939f36b824a13086f4
blob - /dev/null
blob + 044b38889b0da1ab6bcf5d50dda1ccb7762c6dcc (mode 644)
--- /dev/null
+++ main.go
@@ -0,0 +1,91 @@
+package main
+
+import (
+	"bufio"
+	"errors"
+	"fmt"
+	"io"
+	"math/rand"
+	"os"
+	"strings"
+	"time"
+)
+
+func randomLine(f *os.File) (string, error)  {
+	fi, err := f.Stat()
+	if err != nil {
+		return "", err
+	}
+	offset := rand.Int63n(fi.Size())
+	offset, err = f.Seek(offset, io.SeekStart)
+	if err != nil {
+		return "", err
+	}
+
+	br := bufio.NewReader(f)
+	for {
+		b, err := br.ReadByte()
+		if b == '\n' {
+			break
+		}
+		if err != nil {
+			return "", err
+		}
+	}
+	line, err := br.ReadString('\n')
+	if errors.Is(err, io.EOF) {
+		// the file ends without a newline - no problem
+	} else if err != nil {
+		return "", err
+	}
+
+	line = strings.TrimSpace(line)
+	if line == "" {
+		// empty line. we're either at the end or hit a blank line. try again
+		return randomLine(f)
+	}
+	return line, nil
+}
+
+func randomAddr(dictpath string, domain string) (string, error) {
+	f, err := os.Open(dictpath)
+	if err != nil {
+		return "", fmt.Errorf("open dictionary: %w", err)
+	}
+	defer f.Close()
+
+	first, err := randomLine(f)
+	if err != nil {
+		return "", fmt.Errorf("first random word: %w", err)
+	}
+	first = strings.ToLower(first)
+	second, err := randomLine(f)
+	if err != nil {
+		return "", fmt.Errorf("second random word: %w", err)
+	}
+	second = strings.ToLower(second)
+
+	return fmt.Sprintf("%s_%s%02d@%s", first, second, rand.Intn(99), domain), nil
+}
+
+func init() {
+	rand.Seed(time.Now().UnixNano())
+}
+
+const usage string = "usage: randomalias target ..."
+
+func main() {
+	if len(os.Args) < 2 {
+		fmt.Println(usage)
+		os.Exit(1)
+	}
+	targets := os.Args[1:]
+	address, err := randomAddr("/usr/share/dict/words", "mailmux.net")
+	if err != nil {
+		fmt.Fprintln(os.Stderr, err)
+		os.Exit(1)
+	}
+	for _, targ := range targets {
+		fmt.Printf("%s: %s\n", address, targ)
+	}
+}