1 /**
2  * Copyright 1993 Network Computing Devices, Inc.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name Network Computing Devices, Inc. not be
9  * used in advertising or publicity pertaining to distribution of this
10  * software without specific, written prior permission.
11  *
12  * THIS SOFTWARE IS PROVIDED 'AS-IS'.  NETWORK COMPUTING DEVICES, INC.,
13  * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
14  * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
15  * PARTICULAR PURPOSE, OR NONINFRINGEMENT.  IN NO EVENT SHALL NETWORK
16  * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
17  * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
18  * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
19  * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  *
22  * $NCDId: @(#)ListDevice.c,v 1.3 1994/04/07 20:41:22 greg Exp $
23  */
24 
25 #include "Alibint.h"
26 
27 AuDeviceAttributes *
AuListDevices(AuServer * aud,AuMask mask,AuDeviceAttributes * attr,int * num_devices,AuStatus * ret_status)28 AuListDevices(
29               AuServer       *aud,
30               AuMask          mask,
31               AuDeviceAttributes *attr,
32               int            *num_devices,
33               AuStatus       *ret_status
34               )
35 {
36     auReq *req;
37     auListDevicesReply rep;
38     auDeviceAttributes a;
39     AuDeviceAttributes *list = NULL,
40                    *l,
41                     tmp;
42     int             stringLen, childLen;
43     AuMask          savemask;
44 
45     if (attr)
46 	savemask = AuDeviceValueMask(attr);
47     else
48 	attr = &tmp;
49 
50     AuDeviceValueMask(attr) = mask;
51 
52     if (ret_status)
53 	*ret_status = AuSuccess;
54 
55     _AuLockServer();
56     _AuGetEmptyReq(ListDevices, req, aud);
57 
58     stringLen = (AuDeviceValueMask(attr) & AuCompCommonDescriptionMask) ?
59 	AuDeviceDescription(attr)->len : 0;
60     childLen = (AuDeviceValueMask(attr) & AuCompDeviceChildrenMask) ?
61 	AuDeviceNumChildren(attr) * sizeof(AuDeviceID) : 0;
62 
63     req->length += (SIZEOF(auDeviceAttributes) + PAD4(stringLen) +
64 		    childLen) >> 2;
65 
66     _xferDeviceAttributes(attr, a);
67 
68     _AuData(aud, (char *) &a, SIZEOF(auDeviceAttributes));
69 
70     if (stringLen)
71 	_AuData(aud, AuDeviceDescription(attr)->data, stringLen);
72 
73     if (childLen)
74 	_AuData(aud, (char *) AuDeviceChildren(attr), childLen);
75 
76     AuDeviceValueMask(attr) = savemask;
77 
78     (void) _AuReply(aud, (auReply *) & rep, 0, auFalse, ret_status);
79 
80     *num_devices = rep.num_devices;
81 
82     if (rep.num_devices)
83     {
84 	if (!(list = l = (AuDeviceAttributes *)
85 	      Aucalloc(1, rep.num_devices * sizeof(AuDeviceAttributes))))
86 	{
87 	    _AuUnlockServer();
88 	    _AuSyncHandle(aud);
89 	    return NULL;
90 	}
91 
92 	while (rep.num_devices--)
93 	{
94 	    _AuReadPad(aud, (char *) &a, SIZEOF(auDeviceAttributes));
95 
96 	    _xferDeviceAttributes(&a, *l);
97 
98 	    if ((AuDeviceValueMask(l) & AuCompCommonDescriptionMask) &&
99 		AuDeviceDescription(l)->len)
100 	    {
101 		if (!(AuDeviceDescription(l)->data = (char *)
102 		      Aumalloc(AuDeviceDescription(l)->len + 1)))
103 		{
104 		    AuFreeDeviceAttributes(aud, *num_devices, list);
105 		    _AuUnlockServer();
106 		    _AuSyncHandle(aud);
107 		    return NULL;
108 		}
109 
110 		_AuReadPad(aud, AuDeviceDescription(l)->data,
111 			   AuDeviceDescription(l)->len);
112 
113 		AuDeviceDescription(l)->data[AuDeviceDescription(l)->len] = 0;
114 	    }
115 
116 	    if ((AuDeviceValueMask(l) & AuCompDeviceChildrenMask) &&
117 		AuDeviceNumChildren(l))
118 	    {
119 		if (!(AuDeviceChildren(l) = (AuDeviceID *)
120 		      Aumalloc(AuDeviceNumChildren(l) * sizeof(AuDeviceID))))
121 		{
122 		    AuFreeDeviceAttributes(aud, *num_devices, list);
123 		    _AuUnlockServer();
124 		    _AuSyncHandle(aud);
125 		    return NULL;
126 		}
127 
128 		_AuReadPad(aud, (char *) AuDeviceChildren(l),
129 			   AuDeviceNumChildren(l) * sizeof(AuDeviceID));
130 	    }
131 
132 	    l++;
133 	}
134     }
135 
136     _AuUnlockServer();
137     _AuSyncHandle(aud);
138 
139     return list;
140 }
141