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/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23/*	  All Rights Reserved  	*/
24
25
26/*
27 * Copyright (c) 1997, by Sun Microsystems, Inc.
28 * All rights reserved.
29 */
30
31#pragma	ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.2 */
32/*LINTLIBRARY*/
33
34/*
35 * listdev.c
36 *
37 *  Contains:
38 *	listdev()	List attributes defined for a device
39 */
40
41/*
42 *  Header files needed:
43 *	<sys/types.h>	System Data Types
44 *	<string.h>	Standard string definitions
45 *	<devmgmt.h>	Device management definitions
46 *	"devtab.h"	Local device table definitions
47 */
48
49#include	<sys/types.h>
50#include	<string.h>
51#include	<devmgmt.h>
52#include	"devtab.h"
53#include	<stdlib.h>
54
55/*
56 *  Local Definitions:
57 */
58
59
60/*
61 *  Local, Static data:
62 */
63
64/*
65 * void sortlist(list)
66 *	char  **list
67 *
68 *	This function sorts a list of character strings
69 *	so that the list is ordered alphabetically.
70 *
71 *  Arguments:
72 *	list	The list to be sorted
73 *
74 *  Returns:  void
75 */
76
77static	void
78sortlist(char **list)		/* List to be sorted */
79{
80	char  **pp;		/* Pointer to item being sorted */
81	char  **qq;
82	char  **rr;
83	char   *t;		/* Temp for swapping pointers */
84
85	/* If the list isn't empty ... */
86	if (*list) {
87
88	    /* Find the last item in the list */
89	    for (pp = list; *pp; pp++)
90		;
91	    --pp;
92
93	/*
94	 * Sort 'em by sorting larger and larger portions
95	 * of the list (my CSC101 fails me, I forget what
96	 * this sort is called!) [Where I come from, CS
97	 * is Crop Science...]
98	 */
99
100	    while (pp != list) {
101		qq = pp;
102		rr = --pp;
103		while (*qq && (strcmp(*rr, *qq) > 0)) {
104		    t = *rr;
105		    *rr++ = *qq;
106		    *qq++ = t;
107		}
108	    }
109	}
110}
111
112/*
113 * char **listdev(device)
114 *	char   *device;
115 *
116 *	Generate an alphabetized list of attribute names of the
117 *	attributes defined for the device <device>.
118 *
119 *  Arguments:
120 *	device		Device who's attributes are to be listed
121 *
122 *  Returns: char **
123 *	List of attribute names of the attributes defined for this
124 *	device.  (Never empty since all devices have the "alias"
125 *	attribute defined.)
126 */
127
128char **
129listdev(char *device)		/* Device to describe */
130{
131	/*  Automatic data  */
132
133	struct devtabent	*devtabent;	/* Ptr to devtab entry */
134	struct attrval		*attrval;	/* Ptr to attr val pair */
135	char			**list;		/* Ptr to alloc'd list */
136	char			**rtnval;	/* Value to return */
137	char			**pp;		/* Ptr to current val in list */
138	int			noerror;	/* FLAG, TRUE if :-) */
139	int			n;		/* Temp counter */
140
141
142	/*  If the device <device> is defined ...  */
143	if (devtabent = _getdevrec(device)) {
144
145	/*
146	 *  Count the number of attributes defined for the device
147	 *  being sure to count the (char *) NULL that terminates
148	 *  the list
149	 */
150
151	    n = 1;
152	    if (devtabent->alias) n++;		/*  Alias, if defined  */
153	    if (devtabent->cdevice) n++;	/*  Char spcl, if defined  */
154	    if (devtabent->bdevice) n++;	/*  Blk spcl, if defined  */
155	    if (devtabent->pathname) n++;	/*  Pathname, if defined  */
156
157	    /*  Other attributes, if any  */
158	    if ((attrval = devtabent->attrlist) != NULL) {
159		do
160		    n++;
161		while ((attrval = attrval->next) != NULL);
162	    }
163	    noerror = TRUE;
164	    if (list = malloc(n*sizeof (char *))) {
165		pp = list;
166		if (devtabent->alias) {
167		    if (*pp = malloc(strlen(DTAB_ALIAS)+1))
168			(void) strcpy(*pp++, DTAB_ALIAS);
169		    else noerror = FALSE;
170		}
171		if (noerror && devtabent->bdevice) {
172		    if (*pp = malloc(strlen(DTAB_BDEVICE)+1))
173
174			(void) strcpy(*pp++, DTAB_BDEVICE);
175		    else noerror = FALSE;
176		}
177		if (noerror && devtabent->cdevice) {
178		    if (*pp = malloc(strlen(DTAB_CDEVICE)+1))
179
180			(void) strcpy(*pp++, DTAB_CDEVICE);
181		    else noerror = FALSE;
182		}
183		if (noerror && devtabent->pathname) {
184		    if (*pp = malloc(strlen(DTAB_PATHNAME)+1))
185
186			(void) strcpy(*pp++, DTAB_PATHNAME);
187		    else noerror = FALSE;
188		}
189		if (noerror && (attrval = devtabent->attrlist)) {
190		    do {
191			if (*pp = malloc(strlen(attrval->attr)+1))
192
193			    (void) strcpy(*pp++, attrval->attr);
194			else noerror = FALSE;
195		    } while (noerror && (attrval = attrval->next));
196		}
197		if (noerror) {
198		    *pp = NULL;
199		    sortlist(list);
200		    rtnval = list;
201		} else {
202		    for (pp = list; *pp; pp++) free(*pp);
203		    free(list);
204		    rtnval = NULL;
205		}
206	    } else rtnval = NULL;
207	} else rtnval = NULL;
208
209	_enddevtab();
210
211	/* Fini */
212	return (rtnval);
213}
214