/* lppd.c - lpp listen and dispatch daemon */
static char *rcsid
= "$Header: /f/osi/support/RCS/lppd.c,v 7.6 91/02/22 09:46:51 mrose Interim $";
* $Header: /f/osi/support/RCS/lppd.c,v 7.6 91/02/22 09:46:51 mrose Interim $
* Contributed by The Wollongong Group, Inc.
* Revision 7.6 91/02/22 09:46:51 mrose
* Revision 7.5 90/12/19 09:16:08 mrose
* Revision 7.4 90/12/11 10:52:26 mrose
* Revision 7.3 90/10/29 18:37:23 mrose
* Revision 7.2 90/07/09 14:50:54 mrose
* Revision 7.1 90/02/19 13:09:50 mrose
* Revision 7.0 89/11/23 22:27:39 mrose
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
static int nbits
= FD_SETSIZE
;
"lppd.log", NULLCP
, NULLCP
, LLOG_FATAL
| LLOG_EXCEPTIONS
| LLOG_NOTICE
,
LLOG_FATAL
, -1, LLOGCLS
| LLOGCRT
| LLOGZER
, NOTOK
LLog
*pgm_log
= &_pgm_log
;
static char *myname
= "lppd";
static char myhost
[BUFSIZ
];
#define NTADDRS FD_SETSIZE
static struct TSAPaddr
*tz
;
static struct TSAPaddr tas
[NTADDRS
];
static struct dispatch
*dz
;
static struct dispatch dps
[NTADDRS
];
void adios (), advise ();
register struct NSAPaddr
*na
;
register struct TSAPaddr
*ta
;
register struct dispatch
*dp
;
struct TSAPdisconnect tds
;
register struct TSAPdisconnect
*td
= &tds
;
for (ta
= tas
, dp
= dps
; ta
< tz
; ta
++, dp
++) {
if (na
-> na_stack
!= NA_TCP
)
adios (NULLCP
, "unexpected network type 0x%x", na
-> na_stack
);
if (na
-> na_tset
!= NA_TSET_TCP
)
adios (NULLCP
, "unexpected transport base 0x%x", na
-> na_tset
);
advise (LLOG_NOTICE
, NULLCP
, "listening on %s for \"%s\"",
taddr2str (ta
), dp
-> dp_entity
);
if (TNetListen (ta
, td
) == NOTOK
) {
ts_advise (td
, LLOG_EXCEPTIONS
, "TNetListen failed");
adios (NULLCP
, "no network services selected");
if (TNetAcceptAux (&vecp
, vec
, NULLIP
, ta
, 0, NULLFD
, NULLFD
, NULLFD
,
ts_advise (td
, LLOG_EXCEPTIONS
, "TNetAccept failed");
switch (TNetFork (vecp
, vec
, td
)) {
ll_hdinit (pgm_log
, myname
);
ts_advise (td
, LLOG_EXCEPTIONS
, "TNetFork failed");
static int lppd (vecp
, vec
, ta
)
register u_short port
= ta
-> ta_addrs
[0].na_port
;
register struct dispatch
*dp
;
register struct isoservent
*is
;
for (dp
= dps
; dp
< dz
; dp
++)
if (dp
-> dp_port
== port
)
adios (NULLCP
, "unable to find service associated with local port %d",
if ((is
= getisoserventbyname (dp
-> dp_entity
, "lpp")) == NULL
)
adios (NULLCP
, "unable to find program associated with service %s",
*is
-> is_tail
++ = vec
[1];
*is
-> is_tail
++ = vec
[2];
advise (LLOG_NOTICE
, NULLCP
, "exec \"%s\" for \"%s\"", *is
-> is_vec
,
(void) execv (*is
-> is_vec
, is
-> is_vec
);
adios (*is
-> is_vec
, "unable to exec");
static void ts_advise (td
, code
, event
)
register struct TSAPdisconnect
*td
;
(void) sprintf (buffer
, "[%s] %*.*s",
TErrString (td
-> td_reason
),
td
-> td_cc
, td
-> td_cc
, td
-> td_data
);
(void) sprintf (buffer
, "[%s]", TErrString (td
-> td_reason
));
advise (code
, NULLCP
, "%s: %s", event
, buffer
);
register struct isoservent
*is
;
register struct PSAPaddr
*pa
;
register struct NSAPaddr
*na
;
if (myname
= rindex (*vec
, '/'))
if (myname
== NULL
|| *myname
== NULL
)
ll_hdinit (pgm_log
, myname
);
&& stat (ap
= isodefile ("isoservices", 0), &st
) != NOTOK
adios (NULLCP
, "%s not owned by root", ap
);
(void) strcpy (myhost
, TLocalHostName ());
for (vec
++; ap
= *vec
; vec
++) {
if ((ap
= *++vec
) == NULL
|| *ap
== '-')
adios (NULLCP
, "usage: %s -s service-designator");
(void) strcpy (myhost
, ap
);
adios (NULLCP
, "-%s: unknown switch", ap
);
adios (NULLCP
, "usage: %s [switches]", myname
);
bzero ((char *) tas
, sizeof tas
);
bzero ((char *) dps
, sizeof dps
);
(void) setisoservent (0);
while (is
= getisoservent ())
if (strcmp (is
-> is_provider
, "lpp") == 0
&& access (*is
-> is_vec
, X_OK
) != NOTOK
) {
if ((aei
= str2aei (myhost
, is
-> is_entity
)) == NULLAEI
)
if ((pa
= aei2addr (aei
)) == NULLPA
)
adios (NULLCP
, "address translation failed on %s-%s",
myhost
, is
-> is_entity
);
for (na
= pa
-> pa_addr
.sa_addr
.ta_addrs
,
n
= pa
-> pa_addr
.sa_addr
.ta_naddr
;
if (na
-> na_stack
!= NA_TCP
)
na
-> na_tset
= NA_TSET_TCP
;
if (na
-> na_tset
!= NA_TSET_TCP
)
if (tz
>= tas
+ NTADDRS
) {
advise (LLOG_EXCEPTIONS
, NULLCP
,
"too many services, starting with %s",
bcopy ((char *) na
, (char *) tz
-> ta_addrs
, sizeof *na
);
malloc ((unsigned) (strlen (is
-> is_entity
) + 1)))
adios (NULLCP
, "out of memory");
(void) strcpy (dz
-> dp_entity
, is
-> is_entity
);
dz
-> dp_port
= na
-> na_port
;
nbits
= getdtablesize ();
if (debug
== 0 && !(debug
= isatty (2))) {
for (i
= 0; i
< 5; i
++) {
if ((sd
= open ("/dev/null", O_RDWR
)) == NOTOK
)
adios ("/dev/null", "unable to read");
(void) dup2 (sd
, 0), (void) close (sd
);
advise (LLOG_EXCEPTIONS
, "failed", "setsid");
if ((sd
= open ("/dev/tty", O_RDWR
)) != NOTOK
) {
(void) ioctl (sd
, TIOCNOTTY
, NULLCP
);
(void) signal (SIGINT
, SIG_IGN
);
(void) signal (SIGQUIT
, SIG_IGN
);
ll_dbinit (pgm_log
, myname
);
#ifndef sun /* damn YP... */
for (sd
= 3; sd
< nbits
; sd
++)
if (pgm_log
-> ll_fd
!= sd
)
(void) signal (SIGPIPE
, SIG_IGN
);
ll_hdinit (pgm_log
, myname
);
advise (LLOG_NOTICE
, NULLCP
, "starting");
_ll_log (pgm_log
, LLOG_FATAL
, ap
);
_ll_log (pgm_log
, code
, ap
);
void advise (code
, what
, fmt
)
advise (code
, what
, fmt
);