sacadm.c revision 34e485807cef99a975f8962a04f4b7d1aa3529fe
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <sac.h>
#include "misc.h"
#include "structs.h"
#include "adm.h"
#include "extern.h"
/*
* functions
*/
char *pflags();
char *getfield();
void add_pm();
void cleandirs();
void rem_pm();
void start_pm();
void kill_pm();
void enable_pm();
void disable_pm();
void list_pms();
void read_db();
void sendcmd();
void checkresp();
void single_print();
void catch();
void usage();
/*
* common error messages
*/
# define NOTPRIV "User not privileged for operation"
# define SACERR "Can not contact SAC"
# define BADINP "Embedded newlines not allowed"
int Saferrno; /* internal `errno' for exit */
/*
* main - scan args for sacadm and call appropriate handling code
*/
int
{
int c; /* option letter */
int ret; /* return code from check_version */
int flag = 0; /* flag to record requested operations */
int errflg = 0; /* error indicator */
int count = 0; /* argument to -n */
int badcnt = 0; /* count of bad args to -f */
int sawaflag = 0; /* true if actually saw -a */
int conflag = 0; /* true if output should be in condensed form */
long flags = 0; /* arguments to -f */
register char *p; /* scratch pointer */
if (argc == 1)
switch (c) {
case 'a':
sawaflag = 1;
break;
case 'c':
}
if (*command != '/') {
error("command must be a full pathname");
}
break;
case 'd':
break;
case 'e':
break;
case 'f':
while (*optarg) {
switch (*optarg++) {
case 'd':
break;
case 'x':
break;
default:
break;
}
}
/* null terminate just in case anything is there */
break;
case 'G':
break;
case 'g':
break;
case 'k':
break;
case 'L':
break;
case 'l':
break;
case 'n':
if (count < 0) {
error("restart count can not be negative");
}
break;
case 'p':
}
}
for (p = pmtag; *p; p++) {
if (!isalnum(*p)) {
error("port monitor tag must be alphanumeric");
}
}
break;
case 'r':
break;
case 's':
break;
case 't':
}
}
for (p = type; *p; p++) {
if (!isalnum(*p)) {
error("port monitor type must be alphanumeric");
}
}
break;
case 'v':
if (version < 0) {
error("version number can not be negative");
}
break;
case 'x':
break;
case 'y':
}
break;
case 'z':
}
break;
case '?':
errflg++;
}
}
if (badcnt) {
/* bad flags were given to -f */
"Invalid request, %s are not valid arguments for \"-f\"",
badargs);
}
error("_sactab version number is incorrect");
}
else if (ret == 2) {
}
else if (ret == 3) {
}
switch (flag) {
case ADD:
if (uid) {
}
break;
case REMOVE:
if (uid) {
}
break;
case START:
if (uid) {
}
break;
case KILL:
if (uid) {
}
break;
case ENABLE:
if (uid) {
}
break;
case DISABLE:
if (uid) {
}
break;
case LIST:
conflag = 1;
/* fall through */
case PLIST:
break;
case DBREAD:
if (uid) {
}
break;
case CONFIG:
}
break;
case PCONFIG:
}
error("Could not open _sactab");
}
}
break;
default:
/* we only get here if more than one flag bit was set */
/* NOTREACHED */
}
quit();
/* NOTREACHED */
return (0);
}
/*
* usage - print out a usage message
*
* args: cmdname - the name command was invoked with
*/
void
char *cmdname;
{
(void) fprintf(stderr, "Usage:\t%s -a -p pmtag -t type -c cmd -v ver [ -f dx ] [ -n count ]\n", cmdname);
quit();
}
/*
* add_pm - add a port monitor entry
*
* args: tag - port monitor's tag
* type - port monitor's type
* command - command string to invoke port monitor
* version - version number of port monitor's pmtab
* flags - port monitor flags
* count - restart count
* script - port monitor's configuration script
* comment - comment describing port monitor
*/
void
char *tag;
char *type;
char *command;
int version;
long flags;
int count;
char *script;
char *comment;
{
int fd; /* scratch file descriptor */
register int i; /* scratch variable */
error("Could not open _sactab");
}
}
/*
* create the directories for it if needed and put in initial files
*/
for (i = 0; i < 2; i++) {
/* something is there, find out what it is */
}
}
/* note: this removes the directory too */
}
}
/*
* create the directory
*/
}
}
/*
* put in the config script, if specified
*/
if (script) {
/* do_config put out any messages */
quit();
}
}
/*
* create the communications pipe, but first make sure that the
* permissions we specify are what we get
*/
(void) umask(0);
error("could not create communications pipe");
}
/*
* create the _pid file
*/
error("could not create _pid file");
}
/*
* create the _pmtab file
*/
error("could not create _pmtab file");
}
error("error initializing _pmtab");
}
/*
* isolate the command name, but remember it since strtok() trashes it
*/
/*
* check out the command - let addition succeed if it doesn't exist (assume
* it will be added later); fail anything else
*/
quit();
}
quit();
}
quit();
}
}
else {
}
/*
* add the line
*/
error("Could not open _sactab");
}
/*
* tell the SAC to read _sactab if its there (i.e. single user)
*/
if (sac_home())
return;
}
/*
* cleandirs - remove anything that might have been created (i.e. failed
* addition. Saferrno is set elsewhere; this is strictly an attempt
* to clean up what mess we've left, so don't check to see if the
* cleanup worked.
*
* args: tag - tag of port monitor whose trees should be removed
*/
void
char *tag;
{
}
/*
* rem_pm - remove a port monitor
*
* args: tag - tag of port monitor to be removed
*/
void
char *tag;
{
int line; /* line number entry is on */
char *tname; /* temp file name */
error("Could not open _sactab");
}
}
if (line != 1) {
error("error accessing temp file");
}
}
error("error accessing temp file");
}
error("error closing tempfile");
}
/* note - replace only returns if successful */
/*
* tell the SAC to read _sactab if its there (i.e. single user)
*/
if (sac_home())
return;
}
/*
* start_pm - start a particular port monitor
*
* args: tag - tag of port monitor to be started
*/
void
char *tag;
{
return;
}
/*
* kill_pm - stop a particular port monitor
*
* args: tag - tag of port monitor to be stopped
*/
void
char *tag;
{
return;
}
/*
* enable_pm - enable a particular port monitor
*
* args: tag - tag of port monitor to be enabled
*/
void
char *tag;
{
return;
}
/*
* disable_pm - disable a particular port monitor
*
* args: tag - tag of port monitor to be disabled
*/
void
char *tag;
{
return;
}
/*
* read_db - tell SAC or a port monitor to read its administrative file.
*
* args: tag - tag of port monitor that should read its administrative
* file. If NULL, it means SAC should.
*/
void
char *tag;
{
if (tag)
return;
}
/*
* list_pms - request information about port monitors from SAC and output
* requested info
*
* args: pmtag - tag of port monitor to be listed (may be null)
* pmtype - type of port monitors to be listed (may be null)
* oflag - true if output should be easily parseable
*/
void
char *pmtag;
char *pmtype;
int oflag;
{
int nprint = 0; /* count # of PMs printed */
char *p; /* scratch pointer */
char *tag; /* returned tag */
char *type; /* returned type */
char *flags; /* returned flags */
char *rsmax; /* returned restart count */
char *state; /* returned state */
char *cmd; /* returned command string */
char *comment; /* returned comment string */
/*
* if sac isn't there (single user), provide info direct from _sactab
* note: when this routine returns, the process exits, so there is no
* need to free up any memory
*/
p = NULL;
if (sac_home()) {
}
else {
single_print(&p);
}
/*
* SAC sends back info in condensed form, we have to separate it out
* fields come in ':' separated, records are separated by newlines
*/
while (p && *p) {
/*
* print out if no selectors specified, else check to see if
* a selector matched
*/
if (oflag) {
}
else {
if (nprint == 0) {
(void) printf("PMTAG PMTYPE FLGS RCNT STATUS COMMAND\n");
}
}
nprint++;
}
}
/*
* if we didn't find any valid ones, indicate an error (note: 1 and
* only 1 of the if statements should be true)
*/
if (nprint == 0) {
if (pmtype)
else if (pmtag)
}
return;
}
/*
* getfield - retrieve and return a field from the sac "status" string (input
* argument is modified to point to next field as a side-effect)
*
* args: p - address of remaining portion of string
* sepchar - field terminator character
*/
char *
char **p;
char sepchar;
{
char *savep; /* for saving argument */
savep = *p;
if (*p == NULL) {
return(NULL);
}
**p = '\0';
(*p)++;
return(savep);
}
/*
* single_print - print out _sactab if sac not at home (should only happen
* in single user mode
*
* args: p - address of pointer where formatted data should be
* placed (space allocated here)
*/
void
single_print(p)
char **p;
{
register char *tp1; /* scratch pointer */
register char *tp2; /* scratch pointer */
error("Could not open _sactab");
}
error("could not stat _sactab");
}
/*
* allocate space to build return string, twice file size should be more
* than enough (and make sure it's zero'ed out)
*/
error("could not allocate storage");
}
/*
* read the file and build the string
*/
if (*tp2 == '\0')
continue;
}
error("error reading _sactab");
}
/*
* point at the just-built string
*/
*p = tp1;
return;
}
/*
* openpipe - open up command pipe to SAC
*/
int
openpipe()
{
int fd; /* file descriptor associated with command pipe */
if (fd < 0) {
}
/*
* lock pipe to insure serial access, lock will disappear if process dies
*/
error("unable to lock command pipe");
}
return(fd);
}
/*
* sendcmd - send a command to the SAC
*
* args: ap - pointer to command to send
* info - pointer to return information from the SAC
* tag - tag of port monitor to which the command applies (may
* be NULL)
*/
void
char **info;
char *tag;
{
int fd; /* file descriptor of command pipe */
}
/*
* unlock the command pipe - not really necessary since we're about to close
*/
return;
}
/*
* checkresp - check the SAC's response to our command
*
* args: fd - file descriptor of command pipe
* info - pointer to return and info send along by SAC
* tag - tag of port monitor that the command had been
* for, only used for error reporting
*/
void
int fd;
char **info;
char *tag;
{
/*
* make sure this ack is meant for me, put an alarm around the read
* so we don't hang out forever.
*/
(void) alarm(10);
do {
}
(void) alarm(0);
/*
* check out what happened
*/
case AK_ACK:
/* everything was A-OK */
/* there is return info and a place to put it */
error("could not allocate storage");
}
}
/* make sure "string" is null-terminated */
}
return;
/* something went wrong - see what */
case AK_PMRUN:
break;
case AK_PMNOTRUN:
break;
case AK_NOPM:
break;
case AK_UNKNOWN:
break;
case AK_NOCONTACT:
break;
case AK_PMLOCK:
break;
case AK_RECOVER:
break;
case AK_REQFAIL:
break;
default:
break;
}
}
/*
* catch - catcher for SIGALRM, don't need to do anything
*/
void
catch()
{
}
/*
* pflags - put port monitor flags into intelligible form for output
*
* args: flags - binary representation of flags
* dflag - true if a "-" should be returned if no flags
*/
char *
long flags;
int dflag;
{
register int i; /* scratch counter */
if (flags == 0) {
if (dflag)
return("-");
else
return("");
}
i = 0;
buf[i++] = 'd';
}
buf[i++] = 'x';
}
if (flags) {
exit(1);
}
buf[i] = '\0';
return(buf);
}
/*
* sac_home - returns true is sac has a lock on its logfile, false
* otherwise (useful to avoid errors for administrative actions in
* single user mode)
*/
int
sac_home()
{
int fd; /* fd to sac logfile */
if (fd < 0) {
return(FALSE);
}
/* everything is ok */
return(TRUE);
}
else {
/* no one home */
return(FALSE);
}
}