Compare commits
No commits in common. "046dcc441fb489ade85778d646ebb547cd687a77" and "bfec14ce4d8a288efe7f858a7ee3293a13c6d527" have entirely different histories.
046dcc441f
...
bfec14ce4d
6 changed files with 73 additions and 168 deletions
32
COPYING
32
COPYING
|
@ -1,13 +1,25 @@
|
||||||
Copyright (c) 2024 Jeremy Baxter. All rights reserved.
|
Copyright (c) 2024 Jeremy Baxter. All rights reserved.
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Redistribution and use in source and binary forms, with or without
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
modification, are permitted provided that the following conditions
|
||||||
copyright notice and this permission notice appear in all copies.
|
are met:
|
||||||
|
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.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
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,6 +20,5 @@ 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
13
README
|
@ -1,13 +0,0 @@
|
||||||
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
Normal file
45
README.md
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
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
134
mal.1
|
@ -1,134 +0,0 @@
|
||||||
.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,9 +71,10 @@ 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 = subject = null;
|
realName = serverAddr = serverPort = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
import std.getopt : config;
|
import std.getopt : config;
|
||||||
|
@ -119,7 +120,7 @@ main(string[] args)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showVersion) {
|
if (showVersion) {
|
||||||
writeln("mal version 1.0");
|
writeln("mal version 0.0.0");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,12 +128,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 user] {-M file | -m message} fromaddress`);
|
[-u username] {-M messagefile | -m message} fromaddress`);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
enforceDie(message || messageFile,
|
enforceDie(message || messageFile,
|
||||||
"a message has to be provided with -M or -m");
|
"email messsage has to be provided through -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");
|
||||||
|
|
||||||
|
@ -152,8 +153,7 @@ main(string[] args)
|
||||||
addr = "<" ~ addr ~ ">";
|
addr = "<" ~ addr ~ ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* https://todo.sr.ht/~jeremy/mal/2 */
|
authUser = authUser ? authUser : fromStatus.localPart;
|
||||||
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,10 +162,6 @@ 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