1/*++
2/* NAME
3/*	biff_notify 3
4/* SUMMARY
5/*	send biff notification
6/* SYNOPSIS
7/*	#include <biff_notify.h>
8/*
9/*	void	biff_notify(text, len)
10/*	const char *text;
11/*	ssize_t	len;
12/* DESCRIPTION
13/*	biff_notify() sends a \fBBIFF\fR notification request to the
14/*	\fBcomsat\fR daemon.
15/*
16/*	Arguments:
17/* .IP text
18/*	Null-terminated text (username@mailbox-offset).
19/* .IP len
20/*	Length of text, including null terminator.
21/* BUGS
22/*	The \fBBIFF\fR "service" can be a noticeable load for
23/*	systems that have many logged-in users.
24/* LICENSE
25/* .ad
26/* .fi
27/*	The Secure Mailer license must be distributed with this software.
28/* AUTHOR(S)
29/*	Wietse Venema
30/*	IBM T.J. Watson Research
31/*	P.O. Box 704
32/*	Yorktown Heights, NY 10598, USA
33/*--*/
34
35/* System library. */
36
37#include "sys_defs.h"
38#include <sys/socket.h>
39#include <netinet/in.h>
40#include <netdb.h>
41#include <string.h>
42
43/* Utility library. */
44
45#include <msg.h>
46#include <iostuff.h>
47
48/* Application-specific. */
49
50#include <biff_notify.h>
51
52/* biff_notify - notify recipient via the biff "protocol" */
53
54void    biff_notify(const char *text, ssize_t len)
55{
56    static struct sockaddr_in sin;
57    static int sock = -1;
58    struct hostent *hp;
59    struct servent *sp;
60
61    /*
62     * Initialize a socket address structure, or re-use an existing one.
63     */
64    if (sin.sin_family == 0) {
65	if ((sp = getservbyname("biff", "udp")) == 0) {
66	    msg_warn("service not found: biff/udp");
67	    return;
68	}
69	if ((hp = gethostbyname("localhost")) == 0) {
70	    msg_warn("host not found: localhost");
71	    return;
72	}
73	if ((int) hp->h_length > (int) sizeof(sin.sin_addr)) {
74	    msg_warn("bad address size %d for localhost", hp->h_length);
75	    return;
76	}
77	sin.sin_family = hp->h_addrtype;
78	sin.sin_port = sp->s_port;
79	memcpy((char *) &sin.sin_addr, hp->h_addr_list[0], hp->h_length);
80    }
81
82    /*
83     * Open a socket, or re-use an existing one.
84     */
85    if (sock < 0) {
86	if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
87	    msg_warn("socket: %m");
88	    return;
89	}
90	close_on_exec(sock, CLOSE_ON_EXEC);
91    }
92
93    /*
94     * Biff!
95     */
96    if (sendto(sock, text, len, 0, (struct sockaddr *) & sin, sizeof(sin)) != len)
97	msg_warn("biff_notify: %m");
98}
99