]>
git.proxmox.com Git - pmg-api.git/blob - PMG/SMTP.pm
13 my($this, $sock) = @_;
15 my $class = ref($this) || $this;
17 die("undefined socket: ERROR") if !defined($sock);
20 $self->{sock
} = $sock;
21 $self->{lmtp
} = undef;
26 $self->reply ("220 Proxmox SMTP Ready.");
33 $self->{from
} = undef;
35 $self->{queue
} = undef;
36 delete $self->{smtputf8
};
37 delete $self->{xforward
};
38 delete $self->{status
};
42 shift-
>{sock
}->close();
46 print {shift-
>{sock
}} @_, "\r\n";;
51 my ($self, $func, $data, $maxcount) = @_;
55 my $sock = $self->{sock
};
65 $self->reply ("500 5.5.1 Error: bad syntax");
68 ($cmd, $args) = split(/\s+/, $_, 2);
71 if ($cmd eq 'helo' || $cmd eq 'ehlo' || $cmd eq 'lhlo') {
74 $self->reply ("250-PIPELINING");
75 $self->reply ("250-ENHANCEDSTATUSCODES");
76 $self->reply ("250-8BITMIME");
77 $self->reply ("250-SMTPUTF8");
78 $self->reply ("250-XFORWARD NAME ADDR PROTO HELO");
79 $self->reply ("250 OK.");
80 $self->{lmtp
} = 1 if ($cmd eq 'lhlo');
82 } elsif ($cmd eq 'xforward') {
83 my @tmp = split (/\s+/, $args);
84 foreach my $attr (@tmp) {
85 my ($n, $v) = ($attr =~ /^(.*?)=(.*)$/);
86 $self->{xforward
}->{lc($n)} = $v;
88 $self->reply ("250 2.5.0 OK");
90 } elsif ($cmd eq 'noop') {
91 $self->reply ("250 2.5.0 OK");
93 } elsif ($cmd eq 'quit') {
94 $self->reply ("221 2.2.0 OK");
96 } elsif ($cmd eq 'rset') {
98 $self->reply ("250 2.5.0 OK");
100 } elsif ($cmd eq 'mail') {
101 if ($args =~ m/^from:\s*<([^\s\>]*)>([^>]*)$/i) {
103 my ($from, $opts) = ($1, $2);
104 if ($opts =~ m/\sSMTPUTF8/) {
105 $self->{smtputf8
} = 1;
106 $from = decode
('UTF-8', $from);
108 $self->{from
} = $from;
109 $self->reply ('250 2.5.0 OK');
112 $self->reply ("501 5.5.2 Syntax: MAIL FROM: <address>");
115 } elsif ($cmd eq 'rcpt') {
116 if ($args =~ m/^to:\s*<([^\s\>]+)>[^>]*$/i) {
117 my $to = $self->{smtputf8
} ? decode
('UTF-8', $1) : $1;
118 push @{$self->{to
}} , $to;
119 $self->reply ('250 2.5.0 OK');
122 $self->reply ("501 5.5.2 Syntax: RCPT TO: <address>");
125 } elsif ($cmd eq 'data') {
126 if ($self->save_data ()) {
127 eval { &$func ($data, $self); };
130 syslog
('err', $err);
134 foreach $a (@{$self->{to
}}) {
135 if ($self->{queue
}->{status
}->{$a} eq 'delivered') {
136 $self->reply ("250 2.5.0 OK ($self->{queue}->{logid})");
137 } elsif ($self->{queue
}->{status
}->{$a} eq 'blocked') {
138 $self->reply ("250 2.7.0 BLOCKED ($self->{queue}->{logid})");
139 } elsif ($self->{queue
}->{status
}->{$a} eq 'error') {
140 my $code = $self->{queue
}->{status_code
}->{$a};
141 my $resp = substr($code, 0, 1);
142 my $mess = $self->{queue
}->{status_message
}->{$a};
143 $self->reply ("$code $resp.0.0 $mess");
145 $self->reply ("451 4.4.0 detected undelivered mail to <$a>");
151 foreach $a (@{$self->{to
}}) {
152 if (!($self->{queue
}->{status
}->{$a} eq 'delivered' ||
153 $self->{queue
}->{status
}->{$a} eq 'blocked')) {
158 $self->reply ("250 2.5.0 OK ($self->{queue}->{logid})");
160 $self->reply ("451 4.4.0 detected undelivered mail");
168 last if $count >= $maxcount;
169 last if $data->{errors
}; # abort if we find errors
173 $self->reply ("500 5.5.1 Error: unknown command");
176 $self->{sock
}->close;
184 if(!defined($self->{from
})) {
185 $self->reply ("503 5.5.1 Tell me who you are.");
189 if(!defined($self->{to
})) {
190 $self->reply ("503 5.5.1 Tell me who to send it.");
194 $self->reply ("354 End data with <CR><LF>.<CR><LF>");
196 my $sock = $self->{sock
};
201 $queue = PMG
::MailQueue-
>new ($self->{from
}, $self->{to
});
210 # RFC 2821 compliance.
215 print {$queue->{fh
}} $_;
216 $queue->{bytes
} += length ($_);
219 $queue->{fh
}->flush ();
221 $self->{queue
} = $queue;
224 syslog
('err', $err);
225 $self->reply ("451 4.5.0 Local delivery failed: $err");
228 if(!defined($done)) {
229 $self->reply ("451 4.5.0 Local delivery failed: unfinished data");