1 /* $NetBSD: ophandlers.c,v 1.9 2007/01/16 17:32:04 hubertf Exp $ */
4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/types.h>
33 #include <sys/ioctl.h>
41 #include <machine/eeprom.h>
42 #include <machine/openpromio.h>
46 extern char *path_openprom
;
50 static char err_str
[BUFSIZE
];
52 static void op_notsupp (struct extabent
*, struct opiocdesc
*, char *);
55 * There are several known fields that I either don't know how to
56 * deal with or require special treatment.
58 static struct extabent opextab
[] = {
59 { "security-password", op_notsupp
},
60 { "security-mode", op_notsupp
},
61 { "oem-logo", op_notsupp
},
65 #define BARF(str1, str2) { \
66 snprintf(err_str, sizeof err_str, "%s: %s", (str1), (str2)); \
72 op_action(keyword
, arg
)
77 if ((cp
= op_handler(keyword
, arg
)) != NULL
)
82 #if defined(__sparc__) && !defined(__arch64__)
88 /* if we can't open it, obviously we can't use it. */
89 if ((fd
= open(path_openprom
, O_RDONLY
)) < 0)
92 /* check for the presence of OpenFirmware with OPIOCGETOPTNODE */
93 rv
= ioctl(fd
, OPIOCGETOPTNODE
, (char *)&optnode
);
101 op_handler(keyword
, arg
)
104 struct opiocdesc opio
;
106 char opio_buf
[BUFSIZE
];
109 if ((fd
= open(path_openprom
, arg
? O_RDWR
: O_RDONLY
, 0640)) < 0)
110 BARF(path_openprom
, strerror(errno
));
112 /* Check to see if it's a special-case keyword. */
113 for (ex
= opextab
; ex
->ex_keyword
!= NULL
; ++ex
)
114 if (strcmp(ex
->ex_keyword
, keyword
) == 0)
117 if (ioctl(fd
, OPIOCGETOPTNODE
, (char *)&optnode
) < 0)
118 BARF("OPIOCGETOPTNODE", strerror(errno
));
120 memset(&opio_buf
[0], 0, sizeof(opio_buf
));
121 memset(&opio
, 0, sizeof(opio
));
122 opio
.op_nodeid
= optnode
;
123 opio
.op_name
= keyword
;
124 opio
.op_namelen
= strlen(opio
.op_name
);
130 opio
.op_buf
= &opio_buf
[0];
131 opio
.op_buflen
= sizeof(opio_buf
);
132 if (ioctl(fd
, OPIOCGET
, (char *)&opio
) < 0)
133 BARF("OPIOCGET", strerror(errno
));
135 if (opio
.op_buflen
<= 0) {
136 printf("nothing available for %s\n", keyword
);
140 if (ex
->ex_keyword
!= NULL
)
141 (*ex
->ex_handler
)(ex
, &opio
, NULL
);
143 printf("%s\n", opio
.op_buf
);
146 if (ex
->ex_keyword
!= NULL
)
147 (*ex
->ex_handler
)(ex
, &opio
, arg
);
150 opio
.op_buflen
= strlen(arg
);
153 if (ioctl(fd
, OPIOCSET
, (char *)&opio
) < 0)
154 BARF("invalid keyword", keyword
);
158 if (ex
->ex_keyword
!= NULL
)
159 (*ex
->ex_handler
)(ex
, &opio
, NULL
);
161 printf("%s\n", opio
.op_buf
);
164 opio
.op_buf
= &opio_buf
[0];
165 opio
.op_buflen
= sizeof(opio_buf
);
166 if (ioctl(fd
, OPIOCGET
, (char *)&opio
) < 0)
167 BARF("OPIOCGET", strerror(errno
));
169 if (opio
.op_buflen
<= 0) {
170 (void)snprintf(err_str
, sizeof err_str
,
171 "nothing available for %s", keyword
);
175 if (ex
->ex_keyword
!= NULL
)
176 (*ex
->ex_handler
)(ex
, &opio
, NULL
);
178 printf("%s=%s\n", keyword
, opio
.op_buf
);
187 op_notsupp(exent
, opiop
, arg
)
188 struct extabent
*exent
;
189 struct opiocdesc
*opiop
;
193 warnx("property `%s' not yet supported", exent
->ex_keyword
);
197 * XXX: This code is quite ugly. You have been warned.
198 * (Really! This is the only way I could get it to work!)
203 struct opiocdesc opio1
, opio2
;
205 char buf1
[BUFSIZE
], buf2
[BUFSIZE
], buf3
[BUFSIZE
], buf4
[BUFSIZE
];
208 if ((fd
= open(path_openprom
, O_RDONLY
, 0640)) < 0)
209 err(1, "open: %s", path_openprom
);
211 if (ioctl(fd
, OPIOCGETOPTNODE
, (char *)&optnode
) < 0)
212 err(1, "OPIOCGETOPTNODE");
214 memset(&opio1
, 0, sizeof(opio1
));
216 /* This will grab the first property name from OPIOCNEXTPROP. */
217 memset(buf1
, 0, sizeof(buf1
));
218 memset(buf2
, 0, sizeof(buf2
));
220 opio1
.op_nodeid
= opio2
.op_nodeid
= optnode
;
222 opio1
.op_name
= buf1
;
225 opio2
.op_name
= buf3
;
229 * For reference: opio1 is for obtaining the name. Pass the
230 * name of the last property read in op_name, and the next one
231 * will be returned in op_buf. To get the first name, pass
232 * an empty string. There are no more properties when an
233 * empty string is returned.
235 * opio2 is for obtaining the value associated with that name.
236 * For some crazy reason, it seems as if we need to do all
237 * of that gratuitious zapping and copying. *sigh*
240 opio1
.op_namelen
= strlen(opio1
.op_name
);
241 opio1
.op_buflen
= sizeof(buf2
);
243 if (ioctl(fd
, OPIOCNEXTPROP
, (char *)&opio1
) < 0)
244 err(1, "ioctl: OPIOCNEXTPROP");
247 * The name of the property we wish to get the
248 * value for has been stored in the value field
249 * of opio1. If the length of the name is 0, there
250 * are no more properties left.
252 strcpy(opio2
.op_name
, opio1
.op_buf
); /* XXX strcpy is safe */
253 opio2
.op_namelen
= strlen(opio2
.op_name
);
255 if (opio2
.op_namelen
== 0) {
260 memset(opio2
.op_buf
, 0, sizeof(buf4
));
261 opio2
.op_buflen
= sizeof(buf4
);
263 if (ioctl(fd
, OPIOCGET
, (char *)&opio2
) < 0)
264 err(1, "ioctl: OPIOCGET");
266 for (ex
= opextab
; ex
->ex_keyword
!= NULL
; ++ex
)
267 if (strcmp(ex
->ex_keyword
, opio2
.op_name
) == 0)
270 if (ex
->ex_keyword
!= NULL
)
271 (*ex
->ex_handler
)(ex
, &opio2
, NULL
);
273 printf("%s=%s\n", opio2
.op_name
, opio2
.op_buf
);
276 * Place the name of the last read value back into
277 * opio1 so that we may obtain the next name.
279 memset(opio1
.op_name
, 0, sizeof(buf1
));
280 memset(opio1
.op_buf
, 0, sizeof(buf2
));
281 strcpy(opio1
.op_name
, opio2
.op_name
); /* XXX strcpy is safe */