]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/uname/uname.c
ena: Upgrade ena-com to freebsd v2.7.0
[FreeBSD/FreeBSD.git] / usr.bin / uname / uname.c
1 /*-
2  * SPDX-License-Identifier: BSD-4-Clause
3  *
4  * Copyright (c) 2002 Juli Mallett.
5  * Copyright (c) 1993
6  *      The Regents of the University of California.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by the University of
19  *      California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36
37 #include <sys/param.h>
38 #include <sys/sysctl.h>
39
40 #include <err.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <unistd.h>
44
45 #include <osreldate.h>
46
47 #define MFLAG   0x01
48 #define NFLAG   0x02
49 #define PFLAG   0x04
50 #define RFLAG   0x08
51 #define SFLAG   0x10
52 #define VFLAG   0x20
53 #define IFLAG   0x40
54 #define UFLAG   0x80
55 #define KFLAG   0x100
56 #define BFLAG   0x200
57
58 typedef void (*get_t)(void);
59 static get_t get_buildid, get_ident, get_platform, get_hostname, get_arch,
60     get_release, get_sysname, get_kernvers, get_uservers, get_version;
61
62 static void native_ident(void);
63 static void native_platform(void);
64 static void native_hostname(void);
65 static void native_arch(void);
66 static void native_release(void);
67 static void native_sysname(void);
68 static void native_version(void);
69 static void native_kernvers(void);
70 static void native_uservers(void);
71 static void native_buildid(void);
72 static void print_uname(u_int);
73 static void setup_get(void);
74 static void usage(void) __dead2;
75
76 static char *buildid, *ident, *platform, *hostname, *arch, *release, *sysname,
77     *version, *kernvers, *uservers;
78 static int space;
79
80 int
81 main(int argc, char *argv[])
82 {
83         u_int flags;
84         int ch;
85
86         setup_get();
87         flags = 0;
88
89         while ((ch = getopt(argc, argv, "abiKmnoprsUv")) != -1)
90                 switch(ch) {
91                 case 'a':
92                         flags |= (MFLAG | NFLAG | RFLAG | SFLAG | VFLAG);
93                         break;
94                 case 'b':
95                         flags |= BFLAG;
96                         break;
97                 case 'i':
98                         flags |= IFLAG;
99                         break;
100                 case 'K':
101                         flags |= KFLAG;
102                         break;
103                 case 'm':
104                         flags |= MFLAG;
105                         break;
106                 case 'n':
107                         flags |= NFLAG;
108                         break;
109                 case 'p':
110                         flags |= PFLAG;
111                         break;
112                 case 'r':
113                         flags |= RFLAG;
114                         break;
115                 case 's':
116                 case 'o':
117                         flags |= SFLAG;
118                         break;
119                 case 'U':
120                         flags |= UFLAG;
121                         break;
122                 case 'v':
123                         flags |= VFLAG;
124                         break;
125                 case '?':
126                 default:
127                         usage();
128                 }
129
130         argc -= optind;
131         argv += optind;
132
133         if (argc)
134                 usage();
135
136         if (!flags)
137                 flags |= SFLAG;
138
139         print_uname(flags);
140         exit(0);
141 }
142
143 #define CHECK_ENV(opt,var)                              \
144 do {                                                    \
145         if ((var = getenv("UNAME_" opt)) == NULL) {     \
146                 get_##var = native_##var;               \
147         } else {                                        \
148                 get_##var = (get_t)NULL;                \
149         }                                               \
150 } while (0)
151
152 static void
153 setup_get(void)
154 {
155         CHECK_ENV("s", sysname);
156         CHECK_ENV("n", hostname);
157         CHECK_ENV("r", release);
158         CHECK_ENV("v", version);
159         CHECK_ENV("m", platform);
160         CHECK_ENV("p", arch);
161         CHECK_ENV("i", ident);
162         CHECK_ENV("K", kernvers);
163         CHECK_ENV("U", uservers);
164         CHECK_ENV("b", buildid);
165 }
166
167 #define PRINT_FLAG(flags,flag,var)              \
168         if ((flags & flag) == flag) {           \
169                 if (space)                      \
170                         printf(" ");            \
171                 else                            \
172                         space++;                \
173                 if (get_##var != NULL)          \
174                         (*get_##var)();         \
175                 printf("%s", var);              \
176         }
177
178 static void
179 print_uname(u_int flags)
180 {
181         PRINT_FLAG(flags, SFLAG, sysname);
182         PRINT_FLAG(flags, NFLAG, hostname);
183         PRINT_FLAG(flags, RFLAG, release);
184         PRINT_FLAG(flags, VFLAG, version);
185         PRINT_FLAG(flags, MFLAG, platform);
186         PRINT_FLAG(flags, PFLAG, arch);
187         PRINT_FLAG(flags, IFLAG, ident);
188         PRINT_FLAG(flags, KFLAG, kernvers);
189         PRINT_FLAG(flags, UFLAG, uservers);
190         PRINT_FLAG(flags, BFLAG, buildid);
191         printf("\n");
192 }
193
194 #define NATIVE_SYSCTL2_GET(var,mib0,mib1)       \
195 static void                                     \
196 native_##var(void)                              \
197 {                                               \
198         int mib[] = { (mib0), (mib1) };         \
199         size_t len;                             \
200         static char buf[1024];                  \
201         char **varp = &(var);                   \
202                                                 \
203         len = sizeof buf;                       \
204         if (sysctl(mib, sizeof mib / sizeof mib[0],     \
205            &buf, &len, NULL, 0) == -1)          \
206                 err(1, "sysctl");
207
208 #define NATIVE_SYSCTLNAME_GET(var,name)         \
209 static void                                     \
210 native_##var(void)                              \
211 {                                               \
212         size_t len;                             \
213         static char buf[1024];                  \
214         char **varp = &(var);                   \
215                                                 \
216         len = sizeof buf;                       \
217         if (sysctlbyname(name, &buf, &len, NULL,\
218             0) == -1)                           \
219                 err(1, "sysctlbyname");
220
221 #define NATIVE_SET                              \
222         *varp = buf;                            \
223         return;                                 \
224 }       struct __hack
225
226 #define NATIVE_BUFFER   (buf)
227 #define NATIVE_LENGTH   (len)
228
229 NATIVE_SYSCTL2_GET(sysname, CTL_KERN, KERN_OSTYPE) {
230 } NATIVE_SET;
231
232 NATIVE_SYSCTL2_GET(hostname, CTL_KERN, KERN_HOSTNAME) {
233 } NATIVE_SET;
234
235 NATIVE_SYSCTL2_GET(release, CTL_KERN, KERN_OSRELEASE) {
236 } NATIVE_SET;
237
238 NATIVE_SYSCTL2_GET(version, CTL_KERN, KERN_VERSION) {
239         size_t n;
240         char *p;
241
242         p = NATIVE_BUFFER;
243         n = NATIVE_LENGTH;
244         for (; n--; ++p)
245                 if (*p == '\n' || *p == '\t') {
246                         if (n > 1)
247                                 *p = ' ';
248                         else
249                                 *p = '\0';
250                 }
251 } NATIVE_SET;
252
253 NATIVE_SYSCTL2_GET(platform, CTL_HW, HW_MACHINE) {
254 } NATIVE_SET;
255
256 NATIVE_SYSCTL2_GET(arch, CTL_HW, HW_MACHINE_ARCH) {
257 } NATIVE_SET;
258
259 NATIVE_SYSCTLNAME_GET(ident, "kern.ident") {
260 } NATIVE_SET;
261
262 NATIVE_SYSCTLNAME_GET(buildid, "kern.build_id") {
263 } NATIVE_SET;
264
265 static void
266 native_uservers(void)
267 {
268         static char buf[128];
269
270         snprintf(buf, sizeof(buf), "%d", __FreeBSD_version);
271         uservers = buf;
272 }
273
274 static void
275 native_kernvers(void)
276 {
277         static char buf[128];
278
279         snprintf(buf, sizeof(buf), "%d", getosreldate());
280         kernvers = buf;
281 }
282
283 static void
284 usage(void)
285 {
286         fprintf(stderr, "usage: uname [-abiKmnoprsUv]\n");
287         exit(1);
288 }