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