blob: a68f377567eb210ea18d2eb93bac0ac030ff1531 [file] [log] [blame]
James Kuszmaul82f6c042021-01-17 11:30:16 -08001/**
2 * @file sys.c System information
3 *
4 * Copyright (C) 2010 Creytiv.com
5 */
6#include <stdlib.h>
7#include <string.h>
8#include <re_types.h>
9#include <re_fmt.h>
10#include <re_sys.h>
11#ifdef HAVE_UNISTD_H
12#include <unistd.h>
13#endif
14#ifdef HAVE_UNAME
15#include <sys/utsname.h>
16#endif
17#ifdef HAVE_SYS_TIME_H
18#include <sys/time.h>
19#endif
20#ifdef HAVE_SETRLIMIT
21#include <sys/resource.h>
22#endif
23
24
25/**
26 * Get system release version
27 *
28 * @param rel Binary encoded release
29 * @param maj Major version number
30 * @param min Minor version number
31 * @param patch Patch number
32 *
33 * @return 0 if success, otherwise errorcode
34 */
35int sys_rel_get(uint32_t *rel, uint32_t *maj, uint32_t *min, uint32_t *patch)
36{
37#ifdef HAVE_UNAME
38 struct utsname u;
39 struct pl pl_mj, pl_mn, pl_p;
40 uint32_t mj, mn, p;
41 int err;
42
43 if (0 != uname(&u))
44 return errno;
45
46 err = re_regex(u.release, strlen(u.release),
47 "[0-9]+.[0-9]+[.\\-]1[0-9]+",
48 &pl_mj, &pl_mn, NULL, &pl_p);
49 if (err)
50 return err;
51
52 mj = pl_u32(&pl_mj);
53 mn = pl_u32(&pl_mn);
54 p = pl_u32(&pl_p);
55
56 if (rel)
57 *rel = mj<<16 | mn<<8 | p;
58 if (maj)
59 *maj = mj;
60 if (min)
61 *min = mn;
62 if (patch)
63 *patch = p;
64
65 return 0;
66#else
67 (void)rel;
68 (void)maj;
69 (void)min;
70 (void)patch;
71 return EINVAL;
72#endif
73}
74
75
76/**
77 * Get kernel name and version
78 *
79 * @param pf Print function for output
80 * @param unused Unused parameter
81 *
82 * @return 0 if success, otherwise errorcode
83 */
84int sys_kernel_get(struct re_printf *pf, void *unused)
85{
86#ifdef HAVE_UNAME
87 struct utsname u;
88
89 (void)unused;
90
91 if (0 != uname(&u))
92 return errno;
93
94 return re_hprintf(pf, "%s %s %s %s %s", u.sysname, u.nodename,
95 u.release, u.version, u.machine);
96#else
97 const char *str;
98
99 (void)unused;
100
101#if defined(WIN32)
102 str = "Win32";
103#else
104 str = "?";
105#endif
106
107 return re_hprintf(pf, "%s", str);
108#endif
109}
110
111
112/**
113 * Get build info
114 *
115 * @param pf Print function for output
116 * @param unused Unused parameter
117 *
118 * @return 0 if success, otherwise errorcode
119 */
120int sys_build_get(struct re_printf *pf, void *unused)
121{
122 const unsigned int bus_width = 8*sizeof(void *);
123 const char *endian = "unknown";
124
125 const uint32_t a = 0x12345678;
126 const uint8_t b0 = ((uint8_t *)&a)[0];
127 const uint8_t b1 = ((uint8_t *)&a)[1];
128 const uint8_t b2 = ((uint8_t *)&a)[2];
129 const uint8_t b3 = ((uint8_t *)&a)[3];
130
131 (void)unused;
132
133 if (0x12==b0 && 0x34==b1 && 0x56==b2 && 0x78==b3)
134 endian = "big";
135 else if (0x12==b3 && 0x34==b2 && 0x56==b1 && 0x78==b0)
136 endian = "little";
137
138 return re_hprintf(pf, "%u-bit %s endian", bus_width, endian);
139}
140
141
142/**
143 * Get architecture
144 *
145 * @return Architecture string
146 */
147const char *sys_arch_get(void)
148{
149#ifdef ARCH
150 return ARCH;
151#else
152 return "?";
153#endif
154}
155
156
157/**
158 * Get name of Operating System
159 *
160 * @return Operating System string
161 */
162const char *sys_os_get(void)
163{
164#ifdef OS
165 return OS;
166#else
167 return "?";
168#endif
169}
170
171
172/**
173 * Get libre version
174 *
175 * @return libre version string
176 */
177const char *sys_libre_version_get(void)
178{
179#ifdef VERSION
180 return VERSION;
181#else
182 return "?";
183#endif
184}
185
186
187/**
188 * Return the username (login name) for the current user
189 *
190 * @return Username or NULL if not available
191 */
192const char *sys_username(void)
193{
194#ifdef HAVE_PWD_H
195 char *login;
196
197 login = getenv("LOGNAME");
198 if (!login)
199 login = getenv("USER");
200#ifdef HAVE_UNISTD_H
201 if (!login) {
202 login = getlogin();
203 }
204#endif
205
206 return str_isset(login) ? login : NULL;
207#else
208 return NULL;
209#endif
210}
211
212
213/**
214 * Enable or disable coredump
215 *
216 * @param enable true to enable, false to disable coredump
217 *
218 * @return 0 if success, otherwise errorcode
219 */
220int sys_coredump_set(bool enable)
221{
222#ifdef HAVE_SETRLIMIT
223 const struct rlimit rlim = {
224 enable ? RLIM_INFINITY : 0,
225 enable ? RLIM_INFINITY : 0
226 };
227
228 return 0 == setrlimit(RLIMIT_CORE, &rlim) ? 0 : errno;
229#else
230 (void)enable;
231 return ENOSYS;
232#endif
233}