1/*
2 * uname - print system information
3 *
4 * usage: uname [-amnrsv]
5 *
6 */
7
8#include <config.h>
9#include <stdio.h>
10
11#include "bashtypes.h"
12
13#if defined (HAVE_UNAME)
14#  include <sys/utsname.h>
15#else
16struct utsname {
17	char	sysname[32];
18	char	nodename[32];
19	char	release[32];
20	char	version[32];
21	char	machine[32];
22};
23#endif
24
25#include <errno.h>
26
27#include "builtins.h"
28#include "shell.h"
29#include "bashgetopt.h"
30
31#define FLAG_SYSNAME	0x01	/* -s */
32#define FLAG_NODENAME	0x02	/* -n */
33#define FLAG_RELEASE	0x04	/* -r */
34#define FLAG_VERSION	0x08	/* -v */
35#define FLAG_MACHINE	0x10	/* -m, -p */
36
37#define FLAG_ALL	0x1f
38
39#ifndef errno
40extern int errno;
41#endif
42
43static void uprint();
44
45static int uname_flags;
46
47uname_builtin (list)
48     WORD_LIST *list;
49{
50  int opt, r;
51  struct utsname uninfo;
52
53  uname_flags = 0;
54  reset_internal_getopt ();
55  while ((opt = internal_getopt (list, "amnprsv")) != -1)
56    {
57      switch (opt)
58	{
59	case 'a':
60	  uname_flags |= FLAG_ALL;
61	  break;
62	case 'm':
63	case 'p':
64	  uname_flags |= FLAG_MACHINE;
65	  break;
66	case 'n':
67	  uname_flags |= FLAG_NODENAME;
68	  break;
69	case 'r':
70	  uname_flags |= FLAG_RELEASE;
71	  break;
72	case 's':
73	  uname_flags |= FLAG_SYSNAME;
74	  break;
75	case 'v':
76	  uname_flags |= FLAG_VERSION;
77	  break;
78	default:
79	  builtin_usage ();
80	  return (EX_USAGE);
81	}
82    }
83  list = loptend;
84
85  if (list)
86    {
87      builtin_usage ();
88      return (EX_USAGE);
89    }
90
91  if (uname_flags == 0)
92    uname_flags = FLAG_SYSNAME;
93
94  /* Only ancient systems will not have uname(2). */
95#ifdef HAVE_UNAME
96  if (uname (&uninfo) < 0)
97    {
98      builtin_error ("cannot get system name: %s", strerror (errno));
99      return (EXECUTION_FAILURE);
100    }
101#else
102  builtin_error ("cannot get system information: uname(2) not available");
103  return (EXECUTION_FAILURE);
104#endif
105
106  uprint (FLAG_SYSNAME, uninfo.sysname);
107  uprint (FLAG_NODENAME, uninfo.nodename);
108  uprint (FLAG_RELEASE, uninfo.release);
109  uprint (FLAG_VERSION, uninfo.version);
110  uprint (FLAG_MACHINE, uninfo.machine);
111
112  return (EXECUTION_SUCCESS);
113}
114
115static void
116uprint (flag, info)
117     int flag;
118     char *info;
119{
120  if (uname_flags & flag)
121    {
122      uname_flags &= ~flag;
123      printf ("%s%c", info, uname_flags ? ' ' : '\n');
124    }
125}
126
127char *uname_doc[] = {
128	"display information about the system",
129	(char *)NULL
130};
131
132struct builtin uname_struct = {
133	"uname",
134	uname_builtin,
135	BUILTIN_ENABLED,
136	uname_doc,
137	"uname [-amnrsv]",
138	0
139};
140