mirror of
https://blitiri.com.ar/repos/chasquid
synced 2025-12-17 14:37:02 +00:00
queue: Support sending to pipes
With the introduction of aliases, the queue may now be delivering mail to pipes. This patch implements pipe delivery. It uses a fixed 30s timeout for now, as these commands should really not take much time, and we don't want to overly complicate the configuration for now.
This commit is contained in:
@@ -6,14 +6,19 @@ package queue
|
||||
//go:generate protoc --go_out=. -I=${GOPATH}/src -I. queue.proto
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"bytes"
|
||||
|
||||
"blitiri.com.ar/go/chasquid/internal/courier"
|
||||
"blitiri.com.ar/go/chasquid/internal/envelope"
|
||||
"blitiri.com.ar/go/chasquid/internal/protoio"
|
||||
@@ -248,20 +253,10 @@ func (item *Item) SendLoop(q *Queue) {
|
||||
wg.Add(1)
|
||||
go func(rcpt *Recipient, oldStatus Recipient_Status) {
|
||||
defer wg.Done()
|
||||
// TODO: Different types of recipients.
|
||||
to := rcpt.Address
|
||||
|
||||
tr.LazyPrintf("%s sending", to)
|
||||
|
||||
var err error
|
||||
// TODO: If this is all the difference we end up having
|
||||
// between the two couriers, consider going back to using a
|
||||
// routing courier.
|
||||
if envelope.DomainIn(to, q.localDomains) {
|
||||
err = q.localC.Deliver(item.From, to, item.Data)
|
||||
} else {
|
||||
err = q.remoteC.Deliver(item.From, to, item.Data)
|
||||
}
|
||||
err := item.deliver(q, rcpt)
|
||||
|
||||
if err != nil {
|
||||
// TODO: Local deliveries should not be retried, if they
|
||||
@@ -322,6 +317,26 @@ func (item *Item) SendLoop(q *Queue) {
|
||||
// remove item from the queue, and remove from disk.
|
||||
}
|
||||
|
||||
func (item *Item) deliver(q *Queue, rcpt *Recipient) error {
|
||||
if rcpt.Type == Recipient_PIPE {
|
||||
c := strings.Fields(rcpt.Address)
|
||||
if len(c) == 0 {
|
||||
return fmt.Errorf("empty pipe")
|
||||
}
|
||||
ctx, _ := context.WithDeadline(context.Background(),
|
||||
time.Now().Add(30*time.Second))
|
||||
cmd := exec.CommandContext(ctx, c[0], c[1:]...)
|
||||
cmd.Stdin = bytes.NewReader(item.Data)
|
||||
return cmd.Run()
|
||||
} else {
|
||||
if envelope.DomainIn(rcpt.Address, q.localDomains) {
|
||||
return q.localC.Deliver(item.From, rcpt.Address, item.Data)
|
||||
} else {
|
||||
return q.remoteC.Deliver(item.From, rcpt.Address, item.Data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func nextDelay(last time.Duration) time.Duration {
|
||||
switch {
|
||||
case last < 1*time.Minute:
|
||||
|
||||
Reference in New Issue
Block a user