/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* autopush(1) is the command interface to the STREAMS autopush
* mechanism. The autopush command can be used to configure autopush
* information about a STREAMS driver, remove autopush information,
* and report on current configuration information. Its use is as
* follows:
*
* autopush -f file
* autopush -r -M major -m minor
* autopush -g -M major -m minor
*
* The -f option allows autopush information to be set from a file. The
* format of the file is as follows:
*
* # Comment lines begin with a # in column one.
* # The fields are separated by white space and are:
* # major minor lastminor module1 module2 ... module8
*
* "lastminor" is used to configure ranges of minor devices, from "minor"
* to "lastminor" inclusive. It should be set to zero when not in use.
* The -r option allows autopush information to be removed for the given
* to be printed. The format of printing is the same as for the file.
*/
/*
*/
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <locale.h>
#include <zone.h>
/*
* Output format.
*/
"numeric\n")
"ignored\n")
static void usage();
static int is_white_space(), parse_line();
/*
* main():
* process command line arguments.
*/
int
{
int c; /* character read by getopt(3C) */
char *cp;
int exitcode;
#if !defined(TEXT_DOMAIN)
#endif
(void) textdomain(TEXT_DOMAIN);
/*
* Get command name.
*/
/*
* Get options.
*/
switch (c) {
case 'M':
errflag++;
else {
majflag++;
exit(1);
}
}
break;
case 'm':
errflag++;
else {
minflag++;
exit(1);
}
}
break;
case 'f':
errflag++;
else {
fflag++;
}
break;
case 'r':
errflag++;
else
rflag++;
break;
case 'g':
errflag++;
else
gflag++;
break;
default:
errflag++;
break;
} /* switch */
if (errflag) {
usage();
exit(1);
}
} /* while */
usage();
exit(1);
}
if (getzoneid() != GLOBAL_ZONEID) {
"can only be run from the global zone.\n"));
exit(1);
}
if (fflag)
else if (rflag)
else if (gflag)
else {
usage();
exit(1);
}
return (exitcode);
}
/*
* usage():
* print out usage statement.
*/
static void
usage()
{
"\t%s -r -M major -m minor\n"
}
/*
* set_info():
* set autopush configuration information.
* namep: autopush configuration filename
*/
static int
{
perror("");
return (1);
}
perror("");
return (1);
}
line = 0;
line++;
continue;
if (parsecode != 0) {
continue;
}
else if (push.sap_lastminor == 0)
else
retcode = 1;
gettext("%s: ERROR: File %s: could not configure "
switch (error) {
case EPERM:
"You don't have permission to set autopush "
"information\n"), Cmdp);
break;
case EINVAL:
"Invalid major device number or invalid "
"module name or too many modules\n"), Cmdp);
break;
case ENOSTR:
"Major device is not a STREAMS "
"driver\n"), Cmdp);
break;
case EEXIST:
break;
case ENOSR:
"out of autopush structures\n"), Cmdp);
break;
case ERANGE:
"lastminor must be greater than minor\n"),
Cmdp);
break;
default:
Cmdp);
break;
} /* switch */
} /* if */
} /* while */
return (retcode);
}
/*
* rem_info():
* remove autopush configuration information.
*/
static int
{
perror("");
return (1);
}
retcode = 1;
"autopush information\n"), Cmdp);
switch (error) {
case EPERM:
"have permission to remove autopush "
"information\n"), Cmdp);
break;
case EINVAL:
"When removing an entry for ALL minors, "
"minor must be set to 0\n"), Cmdp);
else
"Invalid major device number\n"), Cmdp);
break;
case ENODEV:
"not configured for autopush\n"), Cmdp);
break;
case ERANGE:
"be set to begining of range when clearing\n"),
Cmdp);
break;
default:
break;
} /* switch */
}
return (retcode);
}
/*
* get_info():
* get autopush configuration information.
*/
static int
{
int i; /* counter */
perror("");
return (1);
}
"autopush information\n"), Cmdp);
switch (error) {
case EINVAL:
"major device number\n"), Cmdp);
break;
case ENOSTR:
"device is not a STREAMS driver\n"), Cmdp);
break;
case ENODEV:
"not configured for autopush\n"), Cmdp);
break;
default:
break;
} /* switch */
return (1);
}
case SAP_ONE:
break;
case SAP_RANGE:
break;
case SAP_ALL:
break;
default:
return (1);
}
(void) printf(" ");
}
(void) printf("\n");
return (0);
}
/*
* is_white_space():
* Return 1 if buffer is all white space.
* Return 0 otherwise.
*/
static int
{
while (*bufp) {
return (0);
bufp++;
}
return (1);
}
/*
* parse_line():
* Parse input line from file and report any errors found. Fill
* strapush structure along the way. Returns 1 if the line has
* errors and 0 if the line is well-formed. Another hidden
* dependency on MAXAPUSH. `linep' is the input buffer, `lineno'
* is the current line number, and `namep' is the filename.
*/
static int
{
char c;
/*
* Find the major device number.
*/
;
;
return (1);
}
c = *cp;
*cp = '\0';
return (1);
}
*cp = c;
/*
* Find the minor device number. Must handle negative values here.
*/
;
;
return (1);
}
/*
* Find the lastminor.
*/
;
;
return (1);
}
/*
* Read the list of module names.
*/
npush = 0;
cp++;
if (pushp->sap_anchor != 0) {
gettext("%s: ERROR: File %s: more than "
"one anchor in line, line %d ignored\n"),
return (1);
}
if (npush == 0)
gettext("%s: WARNING: File %s: anchor at "
"beginning of stream on line %d ignored\n"),
continue;
}
"File %s: module name too long, line %d "
return (1);
}
}
if (midx > 0) {
npush++;
}
}
/*
* We have everything we want from the line.
* Now make sure there is no extra garbage on the line.
*/
cp++;
if (*cp) {
gettext("%s: ERROR: File %s: too many modules, line %d "
return (1);
}
return (0);
}