Compare commits
10 commits
bfec14ce4d
...
046dcc441f
Author | SHA1 | Date | |
---|---|---|---|
046dcc441f | |||
b5d42f082d | |||
c4e68581da | |||
deb1226bfe | |||
2eae8fa5ed | |||
52dab0fb91 | |||
3f6315e706 | |||
4f3fe35990 | |||
e9d4bbcdca | |||
ef2be37e23 |
6 changed files with 168 additions and 73 deletions
32
COPYING
32
COPYING
|
@ -1,25 +1,13 @@
|
||||||
Copyright (c) 2024 Jeremy Baxter. All rights reserved.
|
Copyright (c) 2024 Jeremy Baxter. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
modification, are permitted provided that the following conditions
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
are met:
|
copyright notice and this permission notice appear in all copies.
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. Neither the name of the copyright holder nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
|
1
Makefile
1
Makefile
|
@ -20,5 +20,6 @@ clean:
|
||||||
|
|
||||||
install:
|
install:
|
||||||
install -Dm755 mal "${DESTDIR}${PREFIX}"/bin/mal
|
install -Dm755 mal "${DESTDIR}${PREFIX}"/bin/mal
|
||||||
|
install -Dm644 mal.1 "${DESTDIR}${PREFIX}"/share/man/man1/mal.1
|
||||||
|
|
||||||
.PHONY: all clean install
|
.PHONY: all clean install
|
||||||
|
|
13
README
Normal file
13
README
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
mal sends mail to one or more recipients, through information passed
|
||||||
|
on its command line. Read COPYING for information on redistribution.
|
||||||
|
|
||||||
|
* Building
|
||||||
|
|
||||||
|
With ldc and libcurl installed, run:
|
||||||
|
|
||||||
|
$ make
|
||||||
|
# make install # to install
|
||||||
|
|
||||||
|
Documentation is provided in the man page.
|
||||||
|
|
||||||
|
Written by Jeremy Baxter <jeremy@reformers.dev>
|
45
README.md
45
README.md
|
@ -1,45 +0,0 @@
|
||||||
mal sends an email to one or more recipients, through information passed
|
|
||||||
on its command line. Read COPYING for information on redistribution.
|
|
||||||
|
|
||||||
## compilation
|
|
||||||
|
|
||||||
Install ldc and curl, and run make. To install the binary systemwide,
|
|
||||||
run make install after compiling.
|
|
||||||
|
|
||||||
## usage
|
|
||||||
|
|
||||||
Send an email from you@example.org to joe@example.org
|
|
||||||
with the message body "hello!":
|
|
||||||
|
|
||||||
mal -m 'hello!' -t joe@example.org -P password123 you@example.org
|
|
||||||
|
|
||||||
Read the message body from a file instead:
|
|
||||||
|
|
||||||
mal -M mesgfile -t joe@example.org -P password123 you@example.org
|
|
||||||
|
|
||||||
Send the message to multiple recipients:
|
|
||||||
|
|
||||||
mal -M mesgfile -t joe@example.org -t jane@example.org -P password123 \
|
|
||||||
you@example.org
|
|
||||||
|
|
||||||
If SSL is not working properly, use an insecure connection with -k:
|
|
||||||
|
|
||||||
mal -k -m 'hello!' -t joe@example.org -P password123 \
|
|
||||||
you@example.org
|
|
||||||
|
|
||||||
To send a message from an address with a plus in it, manually specify
|
|
||||||
the username with -u:
|
|
||||||
|
|
||||||
mal -m 'hello!' -t joe@example.org -u you -P password123 \
|
|
||||||
you+malbot@example.org
|
|
||||||
|
|
||||||
CC john@example.org:
|
|
||||||
|
|
||||||
mal -m 'hello!' -t joe@example.org -H 'Cc: <john@example.org>' -P password123 \
|
|
||||||
you@example.org
|
|
||||||
|
|
||||||
Read a quick usage example:
|
|
||||||
|
|
||||||
mal
|
|
||||||
|
|
||||||
Man pages hopefully coming soon.
|
|
134
mal.1
Normal file
134
mal.1
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
.Dd $Mdocdate: June 17 2024 $
|
||||||
|
.Dt MAL 1
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm mal
|
||||||
|
.Nd send mail
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm mal
|
||||||
|
.Bk -words
|
||||||
|
.Op Fl ksV
|
||||||
|
.Op Fl a Ar server
|
||||||
|
.Op Fl F Ar fqdn
|
||||||
|
.Op Fl H Ar header
|
||||||
|
.Op Fl n Ar name
|
||||||
|
.Op Fl P Ar passphrase
|
||||||
|
.Op Fl p Ar port
|
||||||
|
.Op Fl S Ar subject
|
||||||
|
.Op Fl t Ar toaddress
|
||||||
|
.Op Fl u Ar user
|
||||||
|
.No { Ns Fl M Ar file | Fl m Ar message Ns }
|
||||||
|
.Ar fromaddress
|
||||||
|
.Ek
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
.Nm
|
||||||
|
sends mail to one or more recipients,
|
||||||
|
whose addresses are specified by the
|
||||||
|
.Fl t
|
||||||
|
option.
|
||||||
|
The mail is sent from the address specified by
|
||||||
|
.Ar fromaddress ,
|
||||||
|
and if
|
||||||
|
.Fl t
|
||||||
|
is not given, mail will be sent back to the sender's address.
|
||||||
|
The
|
||||||
|
.Fl P
|
||||||
|
option specifies a passphrase.
|
||||||
|
.Pp
|
||||||
|
The options are as follows:
|
||||||
|
.Bl -tag -width 123456
|
||||||
|
.It Fl a Ar server
|
||||||
|
Specify the address of the SMTP server to connect to.
|
||||||
|
By default this is the domain segment of
|
||||||
|
.Ar fromaddress .
|
||||||
|
.It Fl F Ar fqdn
|
||||||
|
Specify the FQDN to pass to the SMTP server.
|
||||||
|
By default this is set to the system's hostname with
|
||||||
|
.Dq .local
|
||||||
|
appended to the end.
|
||||||
|
.It Fl H Ar header
|
||||||
|
Add a header to the request.
|
||||||
|
This is necessary if you would like to, for instance
|
||||||
|
CC someone in your mail.
|
||||||
|
See the
|
||||||
|
.Sx EXAMPLES
|
||||||
|
section below for an example using this option.
|
||||||
|
.It Fl k
|
||||||
|
Use an insecure SMTP connection.
|
||||||
|
By default
|
||||||
|
.Nm mal
|
||||||
|
will attempt to connect with secure SMTPS,
|
||||||
|
but if your server doesn't support this you should use
|
||||||
|
.Fl k .
|
||||||
|
See also
|
||||||
|
.Fl s
|
||||||
|
for forcing a secure connection.
|
||||||
|
.It Fl M Ar file
|
||||||
|
Specify a file which contains the message's contents.
|
||||||
|
.It Fl m Ar message
|
||||||
|
Specify a message on the command line.
|
||||||
|
.It Fl n Ar name
|
||||||
|
Specify a real name to identify the sender of the mail.
|
||||||
|
.It Fl P Ar passphrase
|
||||||
|
Specify a passphrase to use to authenticate the SMTP user.
|
||||||
|
Without this option no authentication will be used.
|
||||||
|
.It Fl p Ar port
|
||||||
|
Override the SMTP server port.
|
||||||
|
By default this will be
|
||||||
|
465 for SMTPS servers
|
||||||
|
or 587 for plain SMTP servers.
|
||||||
|
See also the
|
||||||
|
.Fl k
|
||||||
|
flag.
|
||||||
|
.It Fl S Ar subject
|
||||||
|
Specify the subject line of the mail.
|
||||||
|
.It Fl s
|
||||||
|
Force a secure SMTPS connection.
|
||||||
|
This is the default and only required if you want to override
|
||||||
|
a previous
|
||||||
|
.Fl k
|
||||||
|
flag.
|
||||||
|
.It Fl t Ar toaddress
|
||||||
|
Specify a recipient for the mail.
|
||||||
|
If you would like to CC someone instead,
|
||||||
|
see the
|
||||||
|
.Fl H
|
||||||
|
option.
|
||||||
|
If this option is not given,
|
||||||
|
the mail will be sent to the sender's address.
|
||||||
|
This option can be specified multiple times
|
||||||
|
to send email to multiple recipients.
|
||||||
|
.It Fl u Ar user
|
||||||
|
Specify the SMTP user.
|
||||||
|
By default this is the sender's address.
|
||||||
|
.It Fl V
|
||||||
|
Print the version number and exit.
|
||||||
|
.El
|
||||||
|
.Sh EXAMPLES
|
||||||
|
Send an email to
|
||||||
|
.Mt joe@example.org
|
||||||
|
with the message
|
||||||
|
.Dq Hello :
|
||||||
|
.Pp
|
||||||
|
.Dl mal -m Hello -t joe@example.org -P mypasswd you@example.org
|
||||||
|
.Pp
|
||||||
|
Read the message from the file
|
||||||
|
.Dq mesg
|
||||||
|
instead:
|
||||||
|
.Pp
|
||||||
|
.Dl mal -M mesg -t joe@example.org -P mypasswd you@example.org
|
||||||
|
.Pp
|
||||||
|
CC
|
||||||
|
.Mt jane@example.org :
|
||||||
|
.Pp
|
||||||
|
.Dl mal -M mesg -t joe@example.org -H 'Cc: <jane@example.org>' -P mypasswd you@example.org
|
||||||
|
.Pp
|
||||||
|
.Sh AUTHORS
|
||||||
|
.An Jeremy Baxter Aq Mt jeremy@baxters.nz
|
||||||
|
.Sh BUGS
|
||||||
|
.Pp
|
||||||
|
Currently known bugs or issues can be found at the tracker:
|
||||||
|
.Lk https://todo.sr.ht/~jeremy/mal
|
||||||
|
.Pp
|
||||||
|
If you happen to find a bug,
|
||||||
|
please report it to me using my address above.
|
16
mal.d
16
mal.d
|
@ -71,10 +71,9 @@ main(string[] args)
|
||||||
|
|
||||||
fqdn = hostName() ~ ".local";
|
fqdn = hostName() ~ ".local";
|
||||||
mailHeaders = toAddrs = [];
|
mailHeaders = toAddrs = [];
|
||||||
subject = "";
|
|
||||||
useSmtps = true;
|
useSmtps = true;
|
||||||
authUser = message = messageFile = passPhrase =
|
authUser = message = messageFile = passPhrase =
|
||||||
realName = serverAddr = serverPort = null;
|
realName = serverAddr = serverPort = subject = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
import std.getopt : config;
|
import std.getopt : config;
|
||||||
|
@ -120,7 +119,7 @@ main(string[] args)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showVersion) {
|
if (showVersion) {
|
||||||
writeln("mal version 0.0.0");
|
writeln("mal version 1.0");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,12 +127,12 @@ main(string[] args)
|
||||||
stderr.writeln(
|
stderr.writeln(
|
||||||
`usage: mal [-ksV] [-a server] [-F fqdn] [-H header] [-n name]
|
`usage: mal [-ksV] [-a server] [-F fqdn] [-H header] [-n name]
|
||||||
[-P passphrase] [-p port] [-S subject] [-t toaddress]
|
[-P passphrase] [-p port] [-S subject] [-t toaddress]
|
||||||
[-u username] {-M messagefile | -m message} fromaddress`);
|
[-u user] {-M file | -m message} fromaddress`);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
enforceDie(message || messageFile,
|
enforceDie(message || messageFile,
|
||||||
"email messsage has to be provided through -M or -m");
|
"a message has to be provided with -M or -m");
|
||||||
enforceDie(!(message && messageFile),
|
enforceDie(!(message && messageFile),
|
||||||
"flags -M and -m cannot both be supplied in one invocation");
|
"flags -M and -m cannot both be supplied in one invocation");
|
||||||
|
|
||||||
|
@ -153,7 +152,8 @@ main(string[] args)
|
||||||
addr = "<" ~ addr ~ ">";
|
addr = "<" ~ addr ~ ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
authUser = authUser ? authUser : fromStatus.localPart;
|
/* https://todo.sr.ht/~jeremy/mal/2 */
|
||||||
|
authUser = authUser ? authUser : fromAddr;
|
||||||
protocol = useSmtps ? "smtps" : "smtp";
|
protocol = useSmtps ? "smtps" : "smtp";
|
||||||
serverAddr = serverAddr ? serverAddr : fromStatus.domainPart;
|
serverAddr = serverAddr ? serverAddr : fromStatus.domainPart;
|
||||||
serverPort = serverPort ? serverPort : useSmtps ? "465" : "587";
|
serverPort = serverPort ? serverPort : useSmtps ? "465" : "587";
|
||||||
|
@ -162,6 +162,10 @@ main(string[] args)
|
||||||
warn("warning: -P not supplied, using empty passphrase");
|
warn("warning: -P not supplied, using empty passphrase");
|
||||||
passPhrase = "";
|
passPhrase = "";
|
||||||
}
|
}
|
||||||
|
if (!subject) {
|
||||||
|
warn("warning: -S not supplied, using empty subject line");
|
||||||
|
subject = "";
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
messageBuf =
|
messageBuf =
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue