1 /**
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  */
35 int 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  */
84 int 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  */
120 int 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  */
147 const 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  */
162 const 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  */
177 const 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  */
192 const 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  */
220 int 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 }
234