/*
* 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"
/*
* Implements the "putdev" command.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fmtmsg.h>
#include <devmgmt.h>
#include <devtab.h>
/*
* General Purpose Constants
* TRUE Boolean TRUE (if not already defined)
* FALSE Boolean FALSE (if not already defined)
* NULL Null address (if not already defined)
*/
#ifndef TRUE
#endif
#ifndef FALSE
#define FALSE (0)
#endif
/*
* Exit codes
* EX_OK All went well
* EX_ERROR Usage or internal error
* EX_EXISTS The specified alias already exists
* EX_ATTRIB One or more attributes requested for removal was not
* defined for the device
* EX_RELPATH Pathname supplied for cdevice, bdevice or pathname
* attributes was not a full pathname
*/
#define EX_OK 0
/*
* Error messages
*/
#define E_USAGE "usage: putdev -a alias [attribute=value [...]]\n putdev -m device attribute=value [attribute=value [...]]\n putdev -d device [attribute [...]]"
/*
* Macros
* stdmsg(r,l,s,t) Using fmtmsg(), write a standard message to the
* standard error stream.
* Where:
* r The recoverability of the error
* l The label-component
* s The severity-component
* t The text-component
*/
/*
* Static data
* msg Space for message's text-component
*/
/*
* char *mklbl(cmd)
* char *cmd
*
* This function builds a standard label from the command used to invoke
* this process and the standard label prefix ("UX:")
*
* Arguments:
* char *cmd The command used to invoke this process.
*
* Returns: char *
* Pointer to malloc()ed space containing the standard label,
* or (char *) NULL if an error occurred.
*/
static char *
char *cmd;
{
/* Automatic data */
char *p; /* Temporary */
/* Find the 1st char of the basename of the command */
else p = cmd;
/* Allocate and build the string value to return */
}
/* Now that we've done all of that work, change the environment
* so that only the text-component is written by fmtmsg().
* (This should go away in SVR4.1)
*/
(void) putenv("MSGVERB=text");
/* Done */
return(rtn);
}
/*
* putdev -a alias [attribute=value [...]]
* putdev -m alias attribute=value [attribute=value [...]]
* putdev -d alias [attribute [...]]
*
* Modify the device-table. If -a specified, add a record for <alias>
* to the table. If -m specified, modify the attributes specified for
* the <device> specified. If -d specified, remove the specified
* attributes from the specified device or remove the specified device.
*
* Options:
* -a Add an alias description to the device table
* -m Modify an existing device description
* -d (if no attributes specified) remove the specified
* device from the device table, or (if attributes
* specified) remove the specified attributes from
* the specified device.
*
* Exit values:
* 0 All went well
* 1 Usage error (includes specifying "alias" as an
* <attribute>)
* 2 The device table file could not be opened, read
* or modified
* 3 If -a, the alias already exists. Otherwise, the
* specified device does not exist in the table
* 4 One of the specified attributes did not exist
* for the device and therefore wasn't removed
*/
int
{
/* Automatic data */
char *p; /* Temp ptr to char */
/* Generate the label for messages */
/* Extract arguments - validate usage */
case 'a':
}
break;
case 'd':
}
break;
case 'm':
}
break;
case '?':
default:
}
/* Write a usage message if we've seen a blatant error */
}
/* Set up */
/* putdev -a alias [attr=value [...]] */
if (a_seen) {
/* Syntax check */
if (nattrs < 0) {
} else {
/* Attempt to add the new alias */
/* Attempt failed. Write appropriate error message. */
switch(errno) {
/*
* EINVAL indicates that <alias> is not valid or "alias"
* was mentioned as <attr> in <attr>=<value> pair. If the
* alias is a valid alias, assume that's the problem.
*/
case EINVAL:
if (_validalias(alias))
p = E_NOALIAS;
break;
/*
* EEXIST indicates that the alias <alias> already exists
* in the device table.
*/
case EEXIST:
break;
/*
* EACCES and ENOENT indicate problems reading or writing
* the device table.
*/
case EACCES:
case ENOENT:
p = _devtabpath();
else
break;
/*
* EAGAIN indicates that an attribute was defined on the
* command line more than once.
*/
case EAGAIN:
break;
/*
* ENXIO indicates that a relative pathname was supplied
* for the cdevice, bdevice or pathname attributes. Full
* pathnames are required for these attributes.
*/
case ENXIO:
exitcd = EX_RELPATH;
break;
/*
* Some other problem (odd?)
*/
default:
}
}
}
} /* End -a case */
/* putdev -m device attr=value [...] */
else if (m_seen) {
/* Check usage */
if (nattrs <= 0) {
} else {
/* Attempt to modify a device's record */
/* Modification attempt failed */
switch(errno) {
/*
* EINVAL indicates that "alias" was used as an attribute
* in an <attr>=<value> pair.
*/
case EINVAL:
break;
/*
* ENODEV indicates that the device that was to
* be modified doesn't exist.
*/
case ENODEV:
break;
/*
* ENOENT indicates that the device-table doesn't exist.
*/
case ENOENT:
break;
/*
* EACCES indicates that there was a problem reading the
* old device table or creating the new table. If the
* old table is readable, assume that we can't create the
* new table. Otherwise, assume that the old table isn't
* accessible.
*/
case EACCES:
p = _devtabpath();
else
break;
/*
* EAGAIN indicates that an attribute was specified more than
* once on the command line.
*/
case EAGAIN:
break;
/*
* ENXIO indicates that a relative pathname was supplied
* for the cdevice, bdevice or pathname attributes. Full
* pathnames are required for these attributes.
*/
case ENXIO:
exitcd = EX_RELPATH;
break;
/*
* Some strange problem...
*/
default:
}
}
}
} /* End -m case */
else if (d_seen) {
/* putdev -d device [attr [...]] */
/* Check usage */
if (nattrs < 0) {
} else {
/*
* Determine case (removing a device or attributes
* to a device.
*/
if (nattrs == 0) {
/* putdev -d device */
/* Attempt to remove the specified device */
/*
* ENODEV indicates that the named device is not
* defined in the device table.
*/
case ENODEV:
break;
/*
* ENOENT indicates that the device table can't
* be found.
*/
case ENOENT:
break;
/*
* EACCES indicates that there was a problem reading the
* old device table or creating the new table. If the
* old table is readable, assume that we can't create the
* new table. Otherwise, assume that the old table isn't
* accessible.
*/
case EACCES:
p = _devtabpath();
else
break;
/*
* Some strange problem...
*/
default:
} /* End switch */
}
else {
/* putdev -d device attr [attr [...]] */
/*
* Attempt to remove the specified attributes from the
* specified device.
*/
/*
* EINVAL indicates that a named attribute was not
* defined for the specified device or "alias" was
* requested. If "plist" points to a list of attrs,
* the former is the problem. Otherwise, the latter
* is the problem.
*/
case EINVAL:
if (plist) {
}
} else {
}
break;
/*
* ENODEV indicates that the named device is not
* defined in the device table.
*/
case ENODEV:
break;
/*
* ENOENT indicates that the device table can't
* be found.
*/
case ENOENT:
break;
/*
* EACCES indicates that there was a problem reading the
* old device table or creating the new table. If the
* old table is readable, assume that we can't create the
* new table. Otherwise, assume that the old table isn't
* accessible.
*/
case EACCES:
p = _devtabpath();
else
break;
/*
* Some strange problem...
*/
default:
} /* End switch */
} /* End "putdev -d device attr [...]" case */
} /* End passes usage-check case */
} /* End -d case */
/* Done. Return exit code (determined above) */
return(exitcd);
} /* main() */