1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #pragma ident   "%Z%%M% %I%     %E% SMI"
  28 
  29 #include "rstat.h"
  30 #include "rstat_v2.h"
  31 #include <stdio.h>
  32 #include <stdlib.h> /* getenv, exit */
  33 #include <signal.h>
  34 #include <sys/types.h>
  35 #include <memory.h>
  36 #include <stropts.h>
  37 #include <netconfig.h>
  38 #include <syslog.h>
  39 
  40 #ifdef __STDC__
  41 #define SIG_PF void(*)(int)
  42 #endif
  43 
  44 #ifdef DEBUG
  45 #define RPC_SVC_FG
  46 #endif
  47 
  48 
  49 int _rpcpmstart;                /* Started by a port monitor ? */
  50 int _rpcfdtype;                 /* Whether Stream or Datagram ? */
  51 int _rpcsvcdirty;               /* Still serving ? */
  52 
  53 static void _msgout(/*char *msg*/);
  54 static void closedown();
  55 
  56 extern void rstatprog_4(/*struct svc_req *rqstp, SVCXPRT *transp*/);
  57 extern void rstatprog_3(/*struct svc_req *rqstp, SVCXPRT *transp*/);
  58 extern void rstatprog_2(/*struct svc_req *rqstp, SVCXPRT *transp*/);
  59 
  60 int
  61 main(int argc, char *argv[])
  62 {
  63         pid_t pid;
  64         int i;
  65 
  66         /*
  67          * If stdin looks like a TLI endpoint, we assume
  68          * that we were started by a port monitor. If
  69          * t_getstate fails with TBADF, this is not a
  70          * TLI endpoint.
  71          */
  72         if (t_getstate(0) != -1 || t_errno != TBADF) {
  73                 char *netid;
  74                 struct netconfig *nconf = NULL;
  75                 SVCXPRT *transp;
  76 
  77                 _rpcpmstart = 1;
  78                 openlog("rstatd", LOG_PID, LOG_DAEMON);
  79                 if ((netid = getenv("NLSPROVIDER")) == NULL) {
  80 #ifdef DEBUG
  81                         _msgout("cannot get transport name");
  82 #endif
  83                 } else if ((nconf = getnetconfigent(netid)) == NULL) {
  84 #ifdef DEBUG
  85                         _msgout("cannot get transport info");
  86 #endif
  87                 }
  88                 if ((transp = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {
  89                         _msgout("cannot create server handle");
  90                         exit(1);
  91                 }
  92                 if (nconf)
  93                         freenetconfigent(nconf);
  94                 if (!svc_reg(transp, RSTATPROG, RSTATVERS_VAR, rstatprog_4,
  95                     0)) {
  96                         _msgout("unable to register "
  97                             "(RSTATPROG, RSTATVERS_VAR).");
  98                         exit(1);
  99                 }
 100                 if (!svc_reg(transp, RSTATPROG, RSTATVERS_TIME, rstatprog_3,
 101                     0)) {
 102                         _msgout("unable to register "
 103                             "(RSTATPROG, RSTATVERS_TIME).");
 104                         exit(1);
 105                 }
 106                 if (!svc_reg(transp, RSTATPROG, RSTATVERS_SWTCH, rstatprog_2,
 107                     0)) {
 108                         _msgout("unable to register "
 109                             "(RSTATPROG, RSTATVERS_SWTCH).");
 110                         exit(1);
 111                 }
 112                 svc_run();
 113                 exit(1);
 114                 /* NOTREACHED */
 115         } else {
 116 #ifndef RPC_SVC_FG
 117                 pid = fork();
 118                 if (pid < 0) {
 119                         perror("cannot fork");
 120                         exit(1);
 121                 }
 122                 if (pid)
 123                         exit(0);
 124                 closefrom(0);
 125                 i = open("/dev/console", 2);
 126                 (void) dup2(i, 1);
 127                 (void) dup2(i, 2);
 128                 setsid();
 129                 openlog("rstatd", LOG_PID, LOG_DAEMON);
 130 #endif
 131         }
 132         if (!svc_create(rstatprog_4, RSTATPROG, RSTATVERS_VAR, "datagram_v")) {
 133                 _msgout("unable to create (RSTATPROG, RSTATVERS_VAR) "
 134                     "for datagram_v.");
 135                 exit(1);
 136         }
 137         if (!svc_create(rstatprog_3, RSTATPROG, RSTATVERS_TIME,
 138             "datagram_v")) {
 139                 _msgout("unable to create (RSTATPROG, RSTATVERS_TIME) "
 140                     "for datagram_v.");
 141                 exit(1);
 142         }
 143         if (!svc_create(rstatprog_4, RSTATPROG, RSTATVERS_VAR, "circuit_v")) {
 144                 _msgout("unable to create (RSTATPROG, RSTATVERS_VAR) "
 145                     "for circuit_v.");
 146                 exit(1);
 147         }
 148         if (!svc_create(rstatprog_3, RSTATPROG, RSTATVERS_TIME, "circuit_v")) {
 149                 _msgout("unable to create (RSTATPROG, RSTATVERS_TIME) "
 150                     "for circuit_v.");
 151                 exit(1);
 152         }
 153 
 154         /*
 155          * V2 supported on datagram transports *only*
 156          */
 157         if (!svc_create(rstatprog_2, RSTATPROG, RSTATVERS_SWTCH,
 158             "datagram_v")) {
 159                 _msgout("unable to create (RSTATPROG, RSTATVERS_SWTCH) "
 160                     "for datagram_v.");
 161                 exit(1);
 162         }
 163 
 164         svc_run();
 165         _msgout("svc_run returned");
 166         return (1);
 167 }
 168 
 169 static void
 170 _msgout(msg)
 171         char *msg;
 172 {
 173 #ifdef RPC_SVC_FG
 174         if (_rpcpmstart)
 175                 syslog(LOG_ERR, msg);
 176         else
 177                 (void) fprintf(stderr, "%s\n", msg);
 178 #else
 179         syslog(LOG_ERR, msg);
 180 #endif
 181 }