1 /*
2 * Copyright (c) 2024 Meta
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <unistd.h>
8
9 #include "posix_shell.h"
10
11 #include <zephyr/posix/sys/utsname.h>
12 #include <zephyr/shell/shell.h>
13
14 #define UNAME_KERNEL BIT(0)
15 #define UNAME_NODE BIT(1)
16 #define UNAME_RELEASE BIT(2)
17 #define UNAME_VERSION BIT(3)
18 #define UNAME_MACHINE BIT(4)
19 #define UNAME_PLATFORM BIT(5)
20 #define UNAME_UNKNOWN BIT(6)
21 #define UNAME_ALL \
22 (UNAME_KERNEL | UNAME_NODE | UNAME_RELEASE | UNAME_VERSION | UNAME_MACHINE | UNAME_PLATFORM)
23
24 #define HELP_USAGE \
25 "Usage: uname [OPTION]\n" \
26 "Print system information\n" \
27 "\n" \
28 " -a, all informationn\n" \
29 " -s, kernel name\n" \
30 " -o, operating system\n" \
31 " -n, network node hostname\n" \
32 " -r, kernel release\n" \
33 " -v, kernel version\n" \
34 " -m, machine hardware name\n" \
35 " -p, processor type\n" \
36 " -i, hardware platform\n"
37
uname_print_usage(const struct shell * sh)38 static void uname_print_usage(const struct shell *sh)
39 {
40 shell_print(sh, HELP_USAGE);
41 }
42
uname_cmd_handler(const struct shell * sh,size_t argc,char ** argv)43 static int uname_cmd_handler(const struct shell *sh, size_t argc, char **argv)
44 {
45 struct getopt_state *state = getopt_state_get();
46 struct utsname info;
47 unsigned int set;
48 int option;
49 char badarg = 0;
50 int ret;
51
52 set = 0;
53
54 /* Get the uname options */
55
56 optind = 1;
57 while ((option = getopt(argc, argv, "asonrvmpi")) != -1) {
58 switch (option) {
59 case 'a':
60 set = UNAME_ALL;
61 break;
62
63 case 'o':
64 case 's':
65 set |= UNAME_KERNEL;
66 break;
67
68 case 'n':
69 set |= UNAME_NODE;
70 break;
71
72 case 'r':
73 set |= UNAME_RELEASE;
74 break;
75
76 case 'v':
77 set |= UNAME_VERSION;
78 break;
79
80 case 'm':
81 set |= UNAME_MACHINE;
82 break;
83
84 case 'p':
85 if (set != UNAME_ALL) {
86 set |= UNAME_UNKNOWN;
87 }
88 break;
89
90 case 'i':
91 set |= UNAME_PLATFORM;
92 break;
93
94 case '?':
95 default:
96 badarg = (char)state->optopt;
97 break;
98 }
99 }
100
101 if (argc != optind) {
102 shell_error(sh, "uname: extra operand %s", argv[optind]);
103 uname_print_usage(sh);
104 return -1;
105 }
106
107 /* If a bad argument was encountered, then return without processing the
108 * command
109 */
110
111 if (badarg != 0) {
112 shell_error(sh, "uname: illegal option -- %c", badarg);
113 uname_print_usage(sh);
114 return -1;
115 }
116
117 /* If nothing is provided on the command line, the default is -s */
118
119 if (set == 0) {
120 set = UNAME_KERNEL;
121 }
122
123 /* Get uname data */
124
125 ret = uname(&info);
126 if (ret < 0) {
127 shell_error(sh, "cannot get system name");
128 return -1;
129 }
130
131 /* Process each option */
132
133 /* print the kernel/operating system name */
134 if (set & UNAME_KERNEL) {
135 shell_fprintf(sh, SHELL_NORMAL, "%s ", info.sysname);
136 }
137
138 /* Print nodename */
139 if (set & UNAME_NODE) {
140 shell_fprintf(sh, SHELL_NORMAL, "%s ", info.nodename);
141 }
142
143 /* Print the kernel release */
144 if (set & UNAME_RELEASE) {
145 shell_fprintf(sh, SHELL_NORMAL, "%s ", info.release);
146 }
147
148 /* Print the kernel version */
149 if (set & UNAME_VERSION) {
150 shell_fprintf(sh, SHELL_NORMAL, "%s ", info.version);
151 }
152
153 /* Print the machine hardware name */
154 if (set & UNAME_MACHINE) {
155 shell_fprintf(sh, SHELL_NORMAL, "%s ", info.machine);
156 }
157
158 /* Print the machine platform name */
159 if (set & UNAME_PLATFORM) {
160 shell_fprintf(sh, SHELL_NORMAL, "%s ", CONFIG_BOARD);
161 }
162
163 /* Print "unknown" */
164 if (set & UNAME_UNKNOWN) {
165 shell_fprintf(sh, SHELL_NORMAL, "%s ", "unknown");
166 }
167
168 shell_fprintf(sh, SHELL_NORMAL, "\n");
169
170 return 0;
171 }
172
173 POSIX_CMD_ADD(uname, NULL, "Print system information", uname_cmd_handler, 1, 1);
174