2

I have a script which runs on multiple servers. Some servers are using sSMTP and some are using postfix.

I want to find which version of sendmail my server is running in runtime, because -t is not supported in sSMTP but is mandatory in Postfix

Now the challenge begins.

sendmail -V on sSMTP variant outputs sSMTP 2.64 (Not sendmail at all) but the postfix variant doesn't have the -V option for displaying the version.

I managed to accomplish it with the following snippet.

VER=$(sendmail -V 2>/dev/null)
if [[ "sSMTP" == $VER* ]]; then
        echo $BODY | sendmail $EMAIL #sSMTP
else
        echo $BODY | sendmail -t $EMAIL #postfix
fi

Is there a more efficient method to achieve this?

I want to find what variant of sendmail is in my server. Not just postfix or sSMTP.

tripleee
  • 175,061
  • 34
  • 275
  • 318
Sibidharan
  • 2,717
  • 2
  • 26
  • 54
  • Can't you ask the package manager, e.g., `apt list`, what is installed? – Robert Oct 11 '16 at 15:42
  • Why do you think `ssmtp` doesn't support `sendmail -t`? Mine does. See the [man page](https://linux.die.net/man/8/ssmtp) – tripleee Oct 11 '16 at 17:35
  • sendmail instance if ssmtp? @tripleee I don't think so! – Sibidharan Oct 11 '16 at 17:36
  • I don't really understand your comment. The man page I linked to shows that `ssmtp` does indeed ship a `/usr/lib/sendmail` which accepts the `-t` option with its (de facto) standard semantics. Or are you talking about a different `ssmtp` than the one available in Debian under this name? – tripleee Oct 11 '16 at 18:01
  • And [`-t` is optional with Postfix](http://www.postfix.org/mailq.1.html) just like with every other MTA which supplies a [`sendmail`](http://www.sendmail.org/~ca/email/man/sendmail.html) compatibility wrapper. This optional option *(sic)* specifies that the recipient is specified in the headers of the message on standard input, so that you don't need to supply an (otherwise mandatory) explicit recipient address on the command line. – tripleee Oct 11 '16 at 20:18
  • Oh I see! @tripleee Thanks – Sibidharan Oct 12 '16 at 06:53

3 Answers3

3

How about this?

type -p sendmail |
xargs dpkg -S

Some packages put it in /usr/lib, others in /usr/sbin, etc. This obviously requires them to be on your PATH.

dpkg -S tells you the name of the package which installed a file, and type -p is used to find sendmail on your PATH so we can pass that to dpkg -S. This obviously requires a Debian-based distro (Ubuntu, Mint, what have you).

On an ssmpt system, with /usr/lib on the PATH, the output is

ssmtp: /usr/lib/sendmail

On a Postfix system with a slightly different PATH,

postfix: /usr/sbin/sendmail

I don't think I have an Exim or Qmail system where I can try this, but they should be predictably similar.

As an aside, if you want to pass a multi-line string such as an email message to sendmail by way of a pipe from echo, you will need to quote the multi-line variable in order for it to work.

echo "$body" | sendmail -t

If you want to use sendmail -t, the "$body" should contain the To: header for sendmail to parse -- this is what the -t option does, so I don't think you want a variable with a recipient address in this scenario.

Also, don't use uppercase for your private variable names; uppercase variable names are reserved for system use.

Finally, as already commented elsewhere, I believe both SSMTP and Postfix support sendmail -t, as does practically every other Sendmail implementation I have seen. So in the end, I don't think you actually need this code to achieve that goal.

tripleee
  • 175,061
  • 34
  • 275
  • 318
2

Is there a more efficient method to achieve this?

Yes; don't try to find the sendmail version, and use a standard way of sending mail...

You should use the mail (or mailx) command for better compatibility

MAILCMD=$(type -p mail || type -p mailx)
echo "$BODY" | "$MAILCMD" "$EMAIL"
tripleee
  • 175,061
  • 34
  • 275
  • 318
Adam
  • 17,838
  • 32
  • 54
  • I'm not the downvoter, but if the intent is to use `sendmail -t` where available, I don't think `mail` or `mailx` exposes that (and you sort of just move the target of the problem here; what if neither of those is available?) – tripleee Oct 11 '16 at 18:15
  • @tripleee he only needed to use `sendmail -t` because according to his statement, it was mandatory on some postfix versions. I edited my post to reflect the reason of my answer. – Adam Oct 11 '16 at 20:03
  • 1
    Thanks for highlighting that. I sort of agree that using a user-level utility is a reasonable fix for that, but `mail` and its derivatives is even less portable than `sendmail` because there are so many diverse implementations with different features. Of course, if you can assume Debian, like I do in my answer, you don't have that uncertainty. – tripleee Oct 11 '16 at 20:23
1

How about:

Postfix:

$ /usr/sbin/sendmail -C sdfsf
sendmail: fatal: open sdfsf/main.cf: No such file or directory
$ echo $?
75

sSMTP:

$ /usr/sbin/sendmail -C sdfsf
sendmail: No recipients supplied - mail will not be sent
$ echo $?
0

In your script you execute /usr/sbin/sendmail -C sdfsf >/dev/null 2>&1 and test the return value, which is different depending on the MTA.

/usr/sbin/sendmail -C sdfsf >/dev/null 2>&1
if [ $? -eq 0 ]; then   # return code 75 would mean Postfix
    echo sSMTP
else 
    echo Postfix
fi
sSMTP

In Postfix -C identifies the config file and if non-existent causes the sendmail to fail with an return code (75). sSMTP if run with or without the -C switch exits with a zero and message sendmail: No recipients supplied - mail will not be sent. Test the return value ($?) for identification.

James Brown
  • 36,089
  • 7
  • 43
  • 59
  • 1
    My question is not just about ssmp or postfix! It's about all the kinda instances.. Even the original send mail.. How to do that!? – Sibidharan Oct 11 '16 at 17:38
  • It is not unfathomable that you could diagnose each individual SMTP server by probing its failure modes, but that's going to be a lot of work, and if all you really care about is whether or not it supports the `-t` option, maybe just probe for that. Like I remarked elsewhere already, it is portable to every `sendmail` I have tried, including `ssmtp` and (IIRC) `qmail`. – tripleee Oct 11 '16 at 18:10