Exemplo n.º 1
0
int
main(int argc, char *argv[])
{
    int		sts;
    int		nport = 0;
    char	*envstr;

    umask(022);
    __pmGetUsername(&username);
    __pmSetInternalState(PM_STATE_PMCS);
    __pmServerSetFeature(PM_SERVER_FEATURE_DISCOVERY);

    if ((envstr = getenv("PMPROXY_PORT")) != NULL)
	nport = __pmServerAddPorts(envstr);
    ParseOptions(argc, argv, &nport);
    if (nport == 0)
        __pmServerAddPorts(TO_STRING(PROXY_PORT));
    GetProxyHostname();

    __pmServerSetServiceSpec(PM_SERVER_PROXY_SPEC);
    if (run_daemon) {
	fflush(stderr);
	StartDaemon(argc, argv);
	__pmServerCreatePIDFile(PM_SERVER_PROXY_SPEC, 0);
    }

    __pmSetSignalHandler(SIGHUP, SIG_IGN);
    __pmSetSignalHandler(SIGINT, SigIntProc);
    __pmSetSignalHandler(SIGTERM, SigIntProc);
    __pmSetSignalHandler(SIGBUS, SigBad);
    __pmSetSignalHandler(SIGSEGV, SigBad);

    /* Open request ports for client connections */
    if ((sts = __pmServerOpenRequestPorts(&sockFds, MAXPENDING)) < 0)
	DontStart();
    maxReqPortFd = maxSockFd = sts;

    __pmOpenLog(pmProgname, logfile, stderr, &sts);
    /* close old stdout, and force stdout into same stream as stderr */
    fflush(stdout);
    close(fileno(stdout));
    if (dup(fileno(stderr)) == -1) {
	fprintf(stderr, "Warning: dup() failed: %s\n", pmErrStr(-oserror()));
    }

    fprintf(stderr, "pmproxy: PID = %" FMT_PID, getpid());
    fprintf(stderr, ", PDU version = %u\n", PDU_VERSION);
    __pmServerDumpRequestPorts(stderr);
    fflush(stderr);

    /* lose root privileges if we have them */
    __pmSetProcessIdentity(username);

    if (__pmSecureServerSetup(certdb, dbpassfile) < 0)
	DontStart();

    /* all the work is done here */
    ClientLoop();

    Shutdown();
    exit(0);
}
Exemplo n.º 2
0
int
main(int argc, char *argv[])
{
    int		sts;
    int		nport = 0;
    char	*envstr;
#ifdef HAVE_SA_SIGINFO
    static struct sigaction act;
#endif

    umask(022);
    __pmProcessDataSize(NULL);
    __pmGetUsername(&username);
    __pmSetInternalState(PM_STATE_PMCS);
    __pmServerSetFeature(PM_SERVER_FEATURE_DISCOVERY);
    __pmServerSetFeature(PM_SERVER_FEATURE_CONTAINERS);

    if ((envstr = getenv("PMCD_PORT")) != NULL)
	nport = __pmServerAddPorts(envstr);
    ParseOptions(argc, argv, &nport);
    if (nport == 0)
	__pmServerAddPorts(TO_STRING(SERVER_PORT));

    /* Set the local socket path. A message will be generated into the log
     * if this fails, but it is not fatal, since other connection options
     * may exist. 
     */
    __pmServerSetLocalSocket(sockpath);

    /* Set the service spec. This will cause our service to be advertised on
     * the network if that is supported.
     */
    __pmServerSetServiceSpec(PM_SERVER_SERVICE_SPEC);

    if (run_daemon) {
	fflush(stderr);
	StartDaemon(argc, argv);
    }

#ifdef HAVE_SA_SIGINFO
    act.sa_sigaction = SigIntProc;
    act.sa_flags = SA_SIGINFO;
    sigaction(SIGINT, &act, NULL);
    sigaction(SIGTERM, &act, NULL);
#else
    __pmSetSignalHandler(SIGINT, SigIntProc);
    __pmSetSignalHandler(SIGTERM, SigIntProc);
#endif
    __pmSetSignalHandler(SIGHUP, SigHupProc);
    __pmSetSignalHandler(SIGBUS, SigBad);
    __pmSetSignalHandler(SIGSEGV, SigBad);

    if ((sts = __pmServerOpenRequestPorts(&clientFds, MAXPENDING)) < 0)
	DontStart();
    maxReqPortFd = maxClientFd = sts;

    __pmOpenLog(pmProgname, logfile, stderr, &sts);
    /* close old stdout, and force stdout into same stream as stderr */
    fflush(stdout);
    close(fileno(stdout));
    sts = dup(fileno(stderr));
    /* if this fails beware of the sky falling in */
    assert(sts >= 0);

    sts = pmLoadASCIINameSpace(pmnsfile, dupok);
    if (sts < 0) {
	fprintf(stderr, "Error: pmLoadASCIINameSpace(%s, %d): %s\n",
	    (pmnsfile == PM_NS_DEFAULT) ? "DEFAULT" : pmnsfile, dupok, pmErrStr(sts));
	DontStart();
    }

    if (ParseInitAgents(configFileName) < 0) {
	/* error already reported in ParseInitAgents() */
	DontStart();
    }

    if (nAgents <= 0) {
	fprintf(stderr, "Error: No PMDAs found in the configuration file \"%s\"\n",
		configFileName);
	DontStart();
    }

    if (run_daemon) {
	if (__pmServerCreatePIDFile(PM_SERVER_SERVICE_SPEC, PM_FATAL_ERR) < 0)
	    DontStart();
	if (__pmSetProcessIdentity(username) < 0)
	    DontStart();
    }

    if (__pmSecureServerSetup(certdb, dbpassfile) < 0)
	DontStart();

    PrintAgentInfo(stderr);
    __pmAccDumpLists(stderr);
    fprintf(stderr, "\npmcd: PID = %" FMT_PID, getpid());
    fprintf(stderr, ", PDU version = %u\n", PDU_VERSION);
    __pmServerDumpRequestPorts(stderr);
    fflush(stderr);

    /* all the work is done here */
    ClientLoop();

    Shutdown();
    exit(0);
}
Exemplo n.º 3
0
/*
 * Open request ports for client connections.
 * For each request port, open an inet and IPv6 (if supported) socket
 * for clients. Also open a local unix domain socket, if it has been
 * specified
 */
static int
OpenRequestPorts(__pmFdSet *fdset, int backlog)
{
    int i, fd, family, success = 0, maximum = -1;
    int with_ipv6 = strcmp(__pmGetAPIConfig("ipv6"), "true") == 0;

    for (i = 0; i < nReqPorts; i++) {
	ReqPortInfo	*rp = &reqPorts[i];
	int		portsOpened = 0;

	/*
	 * If the spec is NULL or "INADDR_ANY" or "INADDR_LOOPBACK", then
	 * we open one socket for each address family (inet, IPv6).
	 * Otherwise, the address family will be determined by
	 * OpenRequestSocket.  Reporting of all errors is left to
	 * OpenRequestSocket to avoid doubling up.
	 */
	if (rp->address == NULL ||
	    strcmp(rp->address, "INADDR_ANY") == 0 ||
	    strcmp(rp->address, "INADDR_LOOPBACK") == 0) {
	    family = AF_INET;
	    if ((fd = OpenRequestSocket(rp->port, rp->address, &family,
					backlog, fdset, &maximum)) >= 0) {
	        rp->fds[INET_FD] = fd;
		++portsOpened;
		success = 1;
	    }
	    if (with_ipv6) {
		family = AF_INET6;
		if ((fd = OpenRequestSocket(rp->port, rp->address, &family,
					    backlog, fdset, &maximum)) >= 0) {
		    rp->fds[IPV6_FD] = fd;
		    ++portsOpened;
		    success = 1;
		}
	    }
	    else
		rp->fds[IPV6_FD] = -EPROTO;
	}
	else {
	    family = AF_UNSPEC;
	    if ((fd = OpenRequestSocket(rp->port, rp->address, &family,
					backlog, fdset, &maximum)) >= 0) {
	        if (family == AF_INET) {
		    rp->fds[INET_FD] = fd;
		    ++portsOpened;
		    success = 1;
		}
		else if (family == AF_INET6) {
		    rp->fds[IPV6_FD] = fd;
		    ++portsOpened;
		    success = 1;
		}
	    }
	}
	if (portsOpened > 0) {
	    /* Advertise our presence on the network, if requested. */
	    if (serviceSpec != NULL &&
		__pmServerHasFeature(PM_SERVER_FEATURE_DISCOVERY)) {
		rp->presence = __pmServerAdvertisePresence(serviceSpec,
							    rp->port);
	    }
	}
    }

#ifndef IS_MINGW
    /* Open a local unix domain socket, if specified, and supported. */
    if (localSocketPath != NULL) {
#if defined(HAVE_STRUCT_SOCKADDR_UN)
	family = AF_UNIX;
	if ((localSocketFd = OpenRequestSocket(0, localSocketPath, &family,
					       backlog, fdset, &maximum)) >= 0) {
	    __pmServerSetFeature(PM_SERVER_FEATURE_UNIX_DOMAIN);
	    success = 1;
	}
#else
	__pmNotifyErr(LOG_ERR, "%s: unix domain sockets are not supported\n",
		      pmProgname);
#endif
    }
#endif

    if (success)
	return maximum;

    __pmNotifyErr(LOG_ERR, "%s: can't open any request ports, exiting\n",
		pmProgname);
    return -1;
}
Exemplo n.º 4
0
static void
ParseOptions(int argc, char *argv[], int *nports)
{
    int		c;
    int		sts;
    char	*endptr;
    int		usage = 0;
    int		val;

    endptr = pmGetConfig("PCP_PMCDCONF_PATH");
    strncpy(configFileName, endptr, sizeof(configFileName)-1);

    while ((c = pmgetopt_r(argc, argv, &opts)) != EOF) {
	switch (c) {

	    case 'A':	/* disable pmcd service advertising */
		__pmServerClearFeature(PM_SERVER_FEATURE_DISCOVERY);
		break;

	    case 'c':	/* configuration file */
		strncpy(configFileName, opts.optarg, sizeof(configFileName)-1);
		break;

	    case 'C':	/* path to NSS certificate database */
		certdb = opts.optarg;
		break;

	    case 'D':	/* debug flag */
		sts = __pmParseDebug(opts.optarg);
		if (sts < 0) {
		    pmprintf("%s: unrecognized debug flag specification (%s)\n",
			pmProgname, opts.optarg);
		    opts.errors++;
		}
		pmDebug |= sts;
		break;

	    case 'f':
		/* foreground, i.e. do _not_ run as a daemon */
		run_daemon = 0;
		break;

	    case 'i':
		/* one (of possibly several) interfaces for client requests */
		__pmServerAddInterface(opts.optarg);
		break;

	    case 'H':
		/* use the given name as the pmcd.hostname for this host */
		_pmcd_hostname = opts.optarg;
		break;

	    case 'l':
		/* log file name */
		logfile = opts.optarg;
		break;

	    case 'L': /* Maximum size for PDUs from clients */
		val = (int)strtol(opts.optarg, NULL, 0);
		if (val <= 0) {
		    pmprintf("%s: -L requires a positive value\n", pmProgname);
		    opts.errors++;
		} else {
		    __pmSetPDUCeiling(val);
		}
		break;

	    case 'N':
		dupok = 0;
		/*FALLTHROUGH*/
	    case 'n':
	    	/* name space file name */
		pmnsfile = opts.optarg;
		break;

	    case 'p':
		if (__pmServerAddPorts(opts.optarg) < 0) {
		    pmprintf("%s: -p requires a positive numeric argument (%s)\n",
			pmProgname, opts.optarg);
		    opts.errors++;
		} else {
		    *nports += 1;
		}
		break;
		    
	    case 'P':	/* password file for certificate database access */
		dbpassfile = opts.optarg;
		break;

	    case 'q':
		val = (int)strtol(opts.optarg, &endptr, 10);
		if (*endptr != '\0' || val <= 0.0) {
		    pmprintf("%s: -q requires a positive numeric argument\n",
			pmProgname);
		    opts.errors++;
		} else {
		    _creds_timeout = val;
		}
		break;

	    case 's':	/* path to local unix domain socket */
		snprintf(sockpath, sizeof(sockpath), "%s", opts.optarg);
		break;

	    case 'S':	/* only allow authenticated clients */
		__pmServerSetFeature(PM_SERVER_FEATURE_CREDS_REQD);
		break;

	    case 't':
		val = (int)strtol(opts.optarg, &endptr, 10);
		if (*endptr != '\0' || val < 0.0) {
		    pmprintf("%s: -t requires a positive numeric argument\n",
			pmProgname);
		    opts.errors++;
		} else {
		    _pmcd_timeout = val;
		}
		break;

	    case 'T':
		val = (int)strtol(opts.optarg, &endptr, 10);
		if (*endptr != '\0' || val < 0) {
		    pmprintf("%s: -T requires a positive numeric argument\n",
			pmProgname);
		    opts.errors++;
		} else {
		    _pmcd_trace_mask = val;
		}
		break;

	    case 'U':
		username = opts.optarg;
		break;

	    case 'x':
		fatalfile = opts.optarg;
		break;

	    case '?':
		usage = 1;
		break;

	    default:
		opts.errors++;
		break;
	}
    }

    if (usage || opts.errors || opts.optind < argc) {
	pmUsageMessage(&opts);
	if (usage)
	    exit(0);
	DontStart();
    }
}