xref: /freebsd/lib/libc/gen/__xuname.c (revision 3416500aef140042c64bc149cb1ec6620483bc44)
1 /*-
2  * Copyright (c) 1994
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #if defined(LIBC_SCCS) && !defined(lint)
31 /*static char sccsid[] = "From: @(#)uname.c	8.1 (Berkeley) 1/4/94";*/
32 #endif /* LIBC_SCCS and not lint */
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35 
36 #include <sys/param.h>
37 #include <sys/sysctl.h>
38 #include <sys/utsname.h>
39 #include <errno.h>
40 #include <stdlib.h>
41 #include <string.h>
42 
43 int
44 __xuname(int namesize, void *namebuf)
45 {
46 	int mib[2], rval;
47 	size_t len;
48 	char *p, *q;
49 	int oerrno;
50 
51 	rval = 0;
52 	q = (char *)namebuf;
53 
54 	mib[0] = CTL_KERN;
55 
56 	if ((p = getenv("UNAME_s")))
57 		strlcpy(q, p, namesize);
58 	else {
59 		mib[1] = KERN_OSTYPE;
60 		len = namesize;
61 		oerrno = errno;
62 		if (sysctl(mib, 2, q, &len, NULL, 0) == -1) {
63 			if (errno == ENOMEM)
64 				errno = oerrno;
65 			else
66 				rval = -1;
67 		}
68 		q[namesize - 1] = '\0';
69 	}
70 	q += namesize;
71 
72 	mib[1] = KERN_HOSTNAME;
73 	len = namesize;
74 	oerrno = errno;
75 	if (sysctl(mib, 2, q, &len, NULL, 0) == -1) {
76 		if (errno == ENOMEM)
77 			errno = oerrno;
78 		else
79 			rval = -1;
80 	}
81 	q[namesize - 1] = '\0';
82 	q += namesize;
83 
84 	if ((p = getenv("UNAME_r")))
85 		strlcpy(q, p, namesize);
86 	else {
87 		mib[1] = KERN_OSRELEASE;
88 		len = namesize;
89 		oerrno = errno;
90 		if (sysctl(mib, 2, q, &len, NULL, 0) == -1) {
91 			if (errno == ENOMEM)
92 				errno = oerrno;
93 			else
94 				rval = -1;
95 		}
96 		q[namesize - 1] = '\0';
97 	}
98 	q += namesize;
99 
100 	if ((p = getenv("UNAME_v")))
101 		strlcpy(q, p, namesize);
102 	else {
103 
104 		/*
105 		 * The version may have newlines in it, turn them into
106 		 * spaces.
107 		 */
108 		mib[1] = KERN_VERSION;
109 		len = namesize;
110 		oerrno = errno;
111 		if (sysctl(mib, 2, q, &len, NULL, 0) == -1) {
112 			if (errno == ENOMEM)
113 				errno = oerrno;
114 			else
115 				rval = -1;
116 		}
117 		q[namesize - 1] = '\0';
118 		for (p = q; len--; ++p) {
119 			if (*p == '\n' || *p == '\t') {
120 				if (len > 1)
121 					*p = ' ';
122 				else
123 					*p = '\0';
124 			}
125 		}
126 	}
127 	q += namesize;
128 
129 	if ((p = getenv("UNAME_m")))
130 		strlcpy(q, p, namesize);
131 	else {
132 		mib[0] = CTL_HW;
133 		mib[1] = HW_MACHINE;
134 		len = namesize;
135 		oerrno = errno;
136 		if (sysctl(mib, 2, q, &len, NULL, 0) == -1) {
137 			if (errno == ENOMEM)
138 				errno = oerrno;
139 			else
140 				rval = -1;
141 		}
142 		q[namesize - 1] = '\0';
143 	}
144 
145 	return (rval);
146 }
147