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 * @(#)uname.c 8.1 (Berkeley) 1/4/94
30 * $FreeBSD: src/lib/libc/gen/uname.c,v 1.7 1999/08/27 23:59:06 peter Exp $
31 */
32
33 #include <sys/param.h>
34 #include <sys/sysctl.h>
35 #include <sys/utsname.h>
36
37 #include <errno.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41
42 int
uname(struct utsname * name)43 uname(struct utsname *name)
44 {
45 int mib[2], rval;
46 size_t len;
47 char *p;
48 int oerrno;
49
50 rval = 0;
51
52 bzero(name->sysname, sizeof(name->sysname));
53 if ((p = getenv("UNAME_s"))) {
54 strlcpy(name->sysname, p, sizeof(name->sysname));
55 } else {
56 mib[0] = CTL_KERN;
57 mib[1] = KERN_OSTYPE;
58 len = sizeof(name->sysname);
59 oerrno = errno;
60 if (sysctl(mib, 2, name->sysname, &len, NULL, 0) == -1) {
61 if(errno == ENOMEM)
62 errno = oerrno;
63 else
64 rval = -1;
65 }
66 name->sysname[sizeof(name->sysname) - 1] = '\0';
67 }
68
69 bzero(name->nodename, sizeof(name->nodename));
70 mib[0] = CTL_KERN;
71 mib[1] = KERN_HOSTNAME;
72 len = sizeof(name->nodename);
73 oerrno = errno;
74 if (sysctl(mib, 2, name->nodename, &len, NULL, 0) == -1) {
75 if(errno == ENOMEM)
76 errno = oerrno;
77 else
78 rval = -1;
79 }
80 name->nodename[sizeof(name->nodename) - 1] = '\0';
81
82 if ((p = getenv("UNAME_r"))) {
83 strlcpy(name->release, p, sizeof(name->release));
84 } else {
85 mib[0] = CTL_KERN;
86 mib[1] = KERN_OSRELEASE;
87 len = sizeof(name->release);
88 oerrno = errno;
89 if (sysctl(mib, 2, name->release, &len, NULL, 0) == -1) {
90 if(errno == ENOMEM)
91 errno = oerrno;
92 else
93 rval = -1;
94 }
95 name->release[sizeof(name->release) - 1] = '\0';
96 }
97
98 bzero(name->version, sizeof(name->version));
99 if ((p = getenv("UNAME_v"))) {
100 strlcpy(name->version, p, sizeof(name->version));
101 } else {
102 /* The version may contain newlines, turn them into spaces. */
103 mib[0] = CTL_KERN;
104 mib[1] = KERN_VERSION;
105 len = sizeof(name->version);
106 oerrno = errno;
107 if (sysctl(mib, 2, name->version, &len, NULL, 0) == -1) {
108 if (errno == ENOMEM)
109 errno = oerrno;
110 else
111 rval = -1;
112 }
113 name->version[sizeof(name->version) - 1] = '\0';
114 for (p = name->version; len--; ++p) {
115 if (*p == '\n' || *p == '\t') {
116 if (len > 1)
117 *p = ' ';
118 else
119 *p = '\0';
120 }
121 }
122 }
123
124 bzero(name->machine, sizeof(name->machine));
125 if ((p = getenv("UNAME_m"))) {
126 strlcpy(name->machine, p, sizeof(name->machine));
127 } else {
128 oerrno = errno;
129 mib[1] = HW_MACHINE;
130 mib[0] = CTL_HW;
131 len = sizeof(name->machine);
132 if (sysctl(mib, 2, name->machine, &len, NULL, 0) == -1) {
133 if (errno == ENOMEM) {
134 errno = oerrno;
135 } else {
136 rval = -1;
137 }
138 }
139 name->machine[sizeof(name->machine) - 1] = '\0';
140 }
141 return (rval);
142 }
143