87af1a216e0eb227f1a228dad90c9eddb9c7ecca
[platform/upstream/coreutils.git] / src / uname.c
1 /* uname -- print system information
2
3    Copyright 1989, 1992, 1993, 1996, 1997, 1999, 2000, 2001, 2002, 2003 Free
4    Software Foundation, Inc.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software Foundation,
18    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 /* Written by David MacKenzie <djm@gnu.ai.mit.edu> */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <sys/types.h>
25 #include <sys/utsname.h>
26 #include <getopt.h>
27
28 #if HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H
29 # include <sys/systeminfo.h>
30 #endif
31
32 #if HAVE_SYSCTL && HAVE_SYS_SYSCTL_H
33 # include <sys/param.h> /* needed for OpenBSD 3.0 */
34 # include <sys/sysctl.h>
35 # ifdef HW_MODEL
36 #  ifdef HW_MACHINE_ARCH
37 /* E.g., FreeBSD 4.5, NetBSD 1.5.2 */
38 #   define UNAME_HARDWARE_PLATFORM HW_MODEL
39 #   define UNAME_PROCESSOR HW_MACHINE_ARCH
40 #  else
41 /* E.g., OpenBSD 3.0 */
42 #   define UNAME_PROCESSOR HW_MODEL
43 #  endif
44 # endif
45 #endif
46
47 #include "system.h"
48 #include "error.h"
49
50 /* The official name of this program (e.g., no `g' prefix).  */
51 #define PROGRAM_NAME "uname"
52
53 #define WRITTEN_BY _("Written by David MacKenzie.")
54
55 /* Values that are bitwise or'd into `toprint'. */
56 /* Kernel name. */
57 #define PRINT_KERNEL_NAME 1
58
59 /* Node name on a communications network. */
60 #define PRINT_NODENAME 2
61
62 /* Kernel release. */
63 #define PRINT_KERNEL_RELEASE 4
64
65 /* Kernel version. */
66 #define PRINT_KERNEL_VERSION 8
67
68 /* Machine hardware name. */
69 #define PRINT_MACHINE 16
70
71 /* Processor type. */
72 #define PRINT_PROCESSOR 32
73
74 /* Hardware platform.  */
75 #define PRINT_HARDWARE_PLATFORM 64
76
77 /* Operating system.  */
78 #define PRINT_OPERATING_SYSTEM 128
79
80 /* The name this program was run with, for error messages. */
81 char *program_name;
82
83 static struct option const long_options[] =
84 {
85   {"all", no_argument, NULL, 'a'},
86   {"kernel-name", no_argument, NULL, 's'},
87   {"sysname", no_argument, NULL, 's'},  /* Obsolescent.  */
88   {"nodename", no_argument, NULL, 'n'},
89   {"kernel-release", no_argument, NULL, 'r'},
90   {"release", no_argument, NULL, 'r'},  /* Obsolescent.  */
91   {"kernel-version", no_argument, NULL, 'v'},
92   {"machine", no_argument, NULL, 'm'},
93   {"processor", no_argument, NULL, 'p'},
94   {"hardware-platform", no_argument, NULL, 'i'},
95   {"operating-system", no_argument, NULL, 'o'},
96   {GETOPT_HELP_OPTION_DECL},
97   {GETOPT_VERSION_OPTION_DECL},
98   {NULL, 0, NULL, 0}
99 };
100
101 void
102 usage (int status)
103 {
104   if (status != 0)
105     fprintf (stderr, _("Try `%s --help' for more information.\n"),
106              program_name);
107   else
108     {
109       printf (_("Usage: %s [OPTION]...\n"), program_name);
110       fputs (_("\
111 Print certain system information.  With no OPTION, same as -s.\n\
112 \n\
113   -a, --all                print all information, in the following order:\n\
114   -s, --kernel-name        print the kernel name\n\
115   -n, --nodename           print the network node hostname\n\
116   -r, --kernel-release     print the kernel release\n\
117 "), stdout);
118       fputs (_("\
119   -v, --kernel-version     print the kernel version\n\
120   -m, --machine            print the machine hardware name\n\
121   -p, --processor          print the processor type\n\
122   -i, --hardware-platform  print the hardware platform\n\
123   -o, --operating-system   print the operating system\n\
124 "), stdout);
125       fputs (HELP_OPTION_DESCRIPTION, stdout);
126       fputs (VERSION_OPTION_DESCRIPTION, stdout);
127       printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
128     }
129   exit (status);
130 }
131
132 /* Print ELEMENT, preceded by a space if something has already been
133    printed.  */
134
135 static void
136 print_element (char const *element)
137 {
138   static int printed;
139   if (printed++)
140     putchar (' ');
141   fputs (element, stdout);
142 }
143
144 int
145 main (int argc, char **argv)
146 {
147   int c;
148   static char const unknown[] = "unknown";
149
150   /* Mask indicating which elements to print. */
151   unsigned toprint = 0;
152
153   initialize_main (&argc, &argv);
154   program_name = argv[0];
155   setlocale (LC_ALL, "");
156   bindtextdomain (PACKAGE, LOCALEDIR);
157   textdomain (PACKAGE);
158
159   atexit (close_stdout);
160
161   while ((c = getopt_long (argc, argv, "asnrvmpio", long_options, NULL)) != -1)
162     {
163       switch (c)
164         {
165         case 0:
166           break;
167
168         case 'a':
169           toprint = -1;
170           break;
171
172         case 's':
173           toprint |= PRINT_KERNEL_NAME;
174           break;
175
176         case 'n':
177           toprint |= PRINT_NODENAME;
178           break;
179
180         case 'r':
181           toprint |= PRINT_KERNEL_RELEASE;
182           break;
183
184         case 'v':
185           toprint |= PRINT_KERNEL_VERSION;
186           break;
187
188         case 'm':
189           toprint |= PRINT_MACHINE;
190           break;
191
192         case 'p':
193           toprint |= PRINT_PROCESSOR;
194           break;
195
196         case 'i':
197           toprint |= PRINT_HARDWARE_PLATFORM;
198           break;
199
200         case 'o':
201           toprint |= PRINT_OPERATING_SYSTEM;
202           break;
203
204         case_GETOPT_HELP_CHAR;
205
206         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, WRITTEN_BY);
207
208         default:
209           usage (EXIT_FAILURE);
210         }
211     }
212
213   if (argc < optind)
214     {
215       error (0, 0, _("too many arguments"));
216       usage (EXIT_FAILURE);
217     }
218
219   if (toprint == 0)
220     toprint = PRINT_KERNEL_NAME;
221
222   if (toprint
223        & (PRINT_KERNEL_NAME | PRINT_NODENAME | PRINT_KERNEL_RELEASE
224           | PRINT_KERNEL_VERSION | PRINT_MACHINE))
225     {
226       struct utsname name;
227
228       if (uname (&name) == -1)
229         error (EXIT_FAILURE, errno, _("cannot get system name"));
230
231       if (toprint & PRINT_KERNEL_NAME)
232         print_element (name.sysname);
233       if (toprint & PRINT_NODENAME)
234         print_element (name.nodename);
235       if (toprint & PRINT_KERNEL_RELEASE)
236         print_element (name.release);
237       if (toprint & PRINT_KERNEL_VERSION)
238         print_element (name.version);
239       if (toprint & PRINT_MACHINE)
240         print_element (name.machine);
241     }
242
243   if (toprint & PRINT_PROCESSOR)
244     {
245       char const *element = unknown;
246 #if HAVE_SYSINFO && defined SI_ARCHITECTURE
247       {
248         static char processor[257];
249         if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
250           element = processor;
251       }
252 #endif
253 #ifdef UNAME_PROCESSOR
254       if (element == unknown)
255         {
256           static char processor[257];
257           size_t s = sizeof processor;
258           static int mib[] = { CTL_HW, UNAME_PROCESSOR };
259           if (sysctl (mib, 2, processor, &s, 0, 0) >= 0)
260             element = processor;
261         }
262 #endif
263       print_element (element);
264     }
265
266   if (toprint & PRINT_HARDWARE_PLATFORM)
267     {
268       char const *element = unknown;
269 #if HAVE_SYSINFO && defined SI_PLATFORM
270       {
271         static char hardware_platform[257];
272         if (0 <= sysinfo (SI_PLATFORM,
273                           hardware_platform, sizeof hardware_platform))
274           element = hardware_platform;
275       }
276 #endif
277 #ifdef UNAME_HARDWARE_PLATFORM
278       if (element == unknown)
279         {
280           static char hardware_platform[257];
281           size_t s = sizeof hardware_platform;
282           static int mib[] = { CTL_HW, UNAME_HARDWARE_PLATFORM };
283           if (sysctl (mib, 2, hardware_platform, &s, 0, 0) >= 0)
284             element = hardware_platform;
285         }
286 #endif
287       print_element (element);
288     }
289
290   if (toprint & PRINT_OPERATING_SYSTEM)
291     print_element (HOST_OPERATING_SYSTEM);
292
293   putchar ('\n');
294
295   exit (EXIT_SUCCESS);
296 }