xref: /original-bsd/usr.sbin/eeprom/eeprom.c (revision 42f60e33)
1 /*-
2  * Copyright (c) 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This software was developed by the Computer Systems Engineering group
6  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7  * contributed to Berkeley.
8  *
9  * All advertising materials mentioning features or use of this software
10  * must display the following acknowledgement:
11  *	This product includes software developed by the University of
12  *	California, Lawrence Berkeley Laboratory.
13  *
14  * %sccs.include.redist.c%
15  */
16 
17 #ifndef lint
18 static char copyright[] =
19 "@(#) Copyright (c) 1993\n\
20 	The Regents of the University of California.  All rights reserved.\n";
21 #endif /* not lint */
22 
23 #ifndef lint
24 static char sccsid[] = "@(#)eeprom.c	8.1 (Berkeley) 06/06/93";
25 #endif /* not lint */
26 
27 /*
28  * eeprom - openprom control utility
29  *
30  * usage:
31  *
32  *	eeprom [field] [field=value]
33  */
34 
35 #include <sys/types.h>
36 #include <sys/file.h>
37 #include <sys/ioctl.h>
38 
39 #include <machine/openpromio.h>
40 
41 #include <errno.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 
46 #include "pathnames.h"
47 
48 static	char openprom[] = _PATH_OPENPROM;
49 static	char usage[] = "usage: %s [field] [field=value]\n";
50 
51 int
52 main(argc, argv)
53 	int argc;
54 	char **argv;
55 {
56 	register char *cp;
57 	register int i, op, fd, flags, status;
58 	register struct opiocdesc *dp;
59 	struct opiocdesc desc;
60 	char buf[1024], buf2[sizeof(buf)];
61 	char *prog, *name;
62 
63 	/* Determine simple program name for error messages */
64 	if (cp = rindex(argv[0], '/'))
65 		prog = cp + 1;
66 	else
67 		prog = argv[0];
68 
69 	/* Parse flags */
70 	opterr = 0;
71 	while ((op = getopt(argc, argv, "")) != EOF)
72 		switch (op) {
73 
74 		default:
75 			(void) fprintf(stderr, usage, prog);
76 			exit(1);
77 		}
78 
79 	argc -= optind;
80 	argv += optind;
81 
82 	/* Determine flags and open device */
83 	flags = O_RDONLY;
84 	for (i = 0; i < argc; ++i)
85 		if (index(argv[i], '=') != NULL) {
86 			flags = O_RDWR;
87 			break;
88 		}
89 	if ((fd = open(openprom, flags, 0)) < 0) {
90 		fprintf(stderr, "%s: open %s: %s\n",
91 		    prog, openprom, strerror(errno));
92 		exit(1);
93 	}
94 
95 	dp = &desc;
96 	bzero(dp, sizeof(*dp));
97 	if (ioctl(fd, OPIOCGETOPTNODE, &dp->op_nodeid) < 0) {
98 		fprintf(stderr, "%s: get optionsnode: %s\n",
99 		    prog, strerror(errno));
100 		exit(1);
101 	}
102 
103 	if (argc <= 0) {
104 		/* Prime the pump with a zero length name */
105 		dp->op_name = buf;
106 		dp->op_name[0] = '\0';
107 		dp->op_namelen = 0;
108 		dp->op_buf = buf2;
109 		for (;;) {
110 			/* Get the next property name */
111 			dp->op_buflen = sizeof(buf);
112 			if (ioctl(fd, OPIOCNEXTPROP, dp) < 0) {
113 				fprintf(stderr, "%s: get next: %s\n",
114 				    prog, strerror(errno));
115 				exit(1);
116 			}
117 
118 			/* Zero length name means we're done */
119 			if (dp->op_buflen <= 0)
120 				break;
121 
122 			/* Clever hack, swap buffers */
123 			cp = dp->op_buf;
124 			dp->op_buf = dp->op_name;
125 			dp->op_name = cp;
126 			dp->op_namelen = dp->op_buflen;
127 
128 			/* Get the value */
129 			dp->op_buflen = sizeof(buf);
130 			if (ioctl(fd, OPIOCGET, dp) < 0) {
131 				fprintf(stderr, "%s: get \"%s\": %s\n",
132 				    prog, cp, strerror(errno));
133 				exit(1);
134 			}
135 			printf("%.*s=%.*s\n", dp->op_namelen, dp->op_name,
136 			    dp->op_buflen, dp->op_buf);
137 		}
138 		exit(0);
139 	}
140 
141 	status = 0;
142 	for (i = 0; i < argc; ++i) {
143 		dp->op_name = name = argv[i];
144 		cp = index(name, '=');
145 		if (cp) {
146 			*cp++ = '\0';
147 			dp->op_buf = cp;
148 			dp->op_buflen = strlen(dp->op_buf);
149 		} else {
150 			dp->op_buf = buf;
151 			dp->op_buflen = sizeof(buf);
152 		}
153 		dp->op_namelen = strlen(name);
154 		if (ioctl(fd, cp ? OPIOCSET : OPIOCGET, dp) < 0) {
155 			fprintf(stderr, "%s: %s \"%s\": %s\n",
156 			    prog, cp ? "set" : "get", name, strerror(errno));
157 			status |= 1;
158 			continue;
159 		}
160 
161 		/* If setting an entry, we're done */
162 		if (cp)
163 			continue;
164 		if (dp->op_buflen < 0) {
165 			fprintf(stderr, "%s: \"%s\" not found\n", prog, name);
166 			status |= 1;
167 			continue;
168 		}
169 		if (dp->op_buflen >= sizeof(buf)) {
170 			fprintf(stderr, "%s: \"%s\" truncated\n", prog, name);
171 			status |= 1;
172 			/* fall thorugh and print truncated value */
173 		}
174 		printf("%s=%.*s\n", name, dp->op_buflen, buf);
175 	}
176 
177 	exit(status);
178 }
179