1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1992-2012 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Eclipse Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.eclipse.org/org/documents/epl-v10.html * 11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <gsf@research.att.com> * 18 * David Korn <dgk@research.att.com> * 19 * * 20 ***********************************************************************/ 21 #pragma prototyped 22 /* 23 * David Korn 24 * Glenn Fowler 25 * AT&T Research 26 * 27 * uname 28 */ 29 30 static const char usage[] = 31 "[-?\n@(#)$Id: uname (AT&T Research) 2007-04-19 $\n]" 32 USAGE_LICENSE 33 "[+NAME?uname - identify the current system ]" 34 "[+DESCRIPTION?By default \buname\b writes the operating system name to" 35 " standard output. When options are specified, one or more" 36 " system characteristics are written to standard output, space" 37 " separated, on a single line. When more than one option is specified" 38 " the output is in the order specfied by the \b-A\b option below." 39 " Unsupported option values are listed as \a[option]]\a. If any unknown" 40 " options are specified then the local \b/usr/bin/uname\b is called.]" 41 "[+?If any \aname\a operands are specified then the \bsysinfo\b(2) values" 42 " for each \aname\a are listed, separated by space, on one line." 43 " \bgetconf\b(1), a pre-existing \astandard\a interface, provides" 44 " access to the same information; vendors should spend more time" 45 " using standards than inventing them.]" 46 "[+?Selected information is printed in the same order as the options below.]" 47 "[a:all?Equivalent to \b-snrvmpio\b.]" 48 "[s:system|sysname|kernel-name?The detailed kernel name. This is the default.]" 49 "[n:nodename?The hostname or nodename.]" 50 "[r:release|kernel-release?The kernel release level.]" 51 "[v:version|kernel-version?The kernel version level.]" 52 "[m:machine?The name of the hardware type the system is running on.]" 53 "[p:processor?The name of the processor instruction set architecture.]" 54 "[i:implementation|platform|hardware-platform?The hardware implementation;" 55 " this is \b--host-id\b on some systems.]" 56 "[o:operating-system?The generic operating system name.]" 57 "[h:host-id|id?The host id in hex.]" 58 "[d:domain?The domain name returned by \agetdomainname\a(2).]" 59 "[R:extended-release?The extended release name.]" 60 "[A:everything?Equivalent to \b-snrvmpiohdR\b.]" 61 "[f:list?List all \bsysinfo\b(2) names and values, one per line.]" 62 "[S:sethost?Set the hostname or nodename to \aname\a. No output is" 63 " written to standard output.]:[name]" 64 "\n" 65 "\n[ name ... ]\n" 66 "\n" 67 "[+SEE ALSO?\bhostname\b(1), \bgetconf\b(1), \buname\b(2)," 68 " \bsysconf\b(2), \bsysinfo\b(2)]" 69 ; 70 71 #if defined(__STDPP__directive) && defined(__STDPP__hide) 72 __STDPP__directive pragma pp:hide getdomainname gethostid gethostname sethostname 73 #else 74 #define getdomainname ______getdomainname 75 #define gethostid ______gethostid 76 #define gethostname ______gethostname 77 #define sethostname ______sethostname 78 #endif 79 80 #include <cmd.h> 81 #include <ctype.h> 82 #include <proc.h> 83 84 #include "FEATURE/utsname" 85 86 #define MAXHOSTNAME 64 87 88 #if _lib_uname && _sys_utsname 89 90 #include <sys/utsname.h> 91 92 #endif 93 94 #if defined(__STDPP__directive) && defined(__STDPP__hide) 95 __STDPP__directive pragma pp:nohide getdomainname gethostid gethostname sethostname 96 #else 97 #undef getdomainname 98 #undef gethostid 99 #undef gethostname 100 #undef sethostname 101 #endif 102 103 #if _lib_getdomainname 104 extern int getdomainname(char*, size_t); 105 #endif 106 #if _lib_gethostid 107 extern long gethostid(void); 108 #endif 109 #if _lib_gethostname 110 extern int gethostname(char*, size_t); 111 #endif 112 #if _lib_sethostname 113 extern int sethostname(const char*, size_t); 114 #endif 115 116 #ifndef HOSTTYPE 117 #define HOSTTYPE "unknown" 118 #endif 119 120 static const char hosttype[] = HOSTTYPE; 121 122 #if !_lib_uname || !_sys_utsname 123 124 #if defined(__STDPP__) 125 #define SYSNAME #(getprd machine) 126 #define RELEASE #(getprd release) 127 #define VERSION #(getprd version) 128 #define MACHINE #(getprd architecture) 129 #else 130 #define SYSNAME "" 131 #define RELEASE "" 132 #define VERSION "" 133 #define MACHINE "" 134 #endif 135 136 struct utsname 137 { 138 char* sysname; 139 char nodename[MAXHOSTNAME]; 140 char* release; 141 char* version; 142 char* machine; 143 }; 144 145 int 146 uname(register struct utsname* ut) 147 { 148 #ifdef HOSTTYPE 149 char* sys = 0; 150 char* arch = 0; 151 152 if (*hosttype) 153 { 154 static char buf[sizeof(hosttype)]; 155 156 strcpy(buf, hosttype); 157 sys = buf; 158 if (arch = strchr(sys, '.')) 159 { 160 *arch++ = 0; 161 if (!*arch) 162 arch = 0; 163 } 164 if (!*sys) 165 sys = 0; 166 } 167 #endif 168 #ifdef _lib_gethostname 169 if (gethostname(ut->nodename, sizeof(ut->nodename) - 1)) 170 return -1; 171 #else 172 strncpy(ut->nodename, "local", sizeof(ut->nodename) - 1); 173 #endif 174 #ifdef HOSTTYPE 175 if (!(ut->sysname = sys)) 176 #endif 177 if (!*(ut->sysname = SYSNAME)) 178 ut->sysname = ut->nodename; 179 #ifdef HOSTTYPE 180 if (!(ut->machine = arch)) 181 #endif 182 ut->machine = MACHINE; 183 ut->release = RELEASE; 184 ut->version = VERSION; 185 return 0; 186 } 187 188 #endif 189 190 #define OPT_system (1<<0) 191 #define OPT_nodename (1<<1) 192 #define OPT_release (1<<2) 193 #define OPT_version (1<<3) 194 #define OPT_machine (1<<4) 195 #define OPT_processor (1<<5) 196 197 #define OPT_STANDARD 6 198 199 #define OPT_implementation (1<<6) 200 #define OPT_operating_system (1<<7) 201 202 #define OPT_ALL 8 203 204 #define OPT_hostid (1<<8) 205 #define OPT_vendor (1<<9) 206 #define OPT_domain (1<<10) 207 #define OPT_machine_type (1<<11) 208 #define OPT_base (1<<12) 209 #define OPT_extended_release (1<<13) 210 #define OPT_extra (1<<14) 211 212 #define OPT_TOTAL 15 213 214 #define OPT_all (1L<<29) 215 #define OPT_total (1L<<30) 216 #define OPT_standard ((1<<OPT_STANDARD)-1) 217 218 #ifndef MACHINE 219 #if defined(__STDPP__) 220 #define MACHINE #(getprd architecture) 221 #else 222 #define MACHINE "" 223 #endif 224 #endif 225 226 #ifndef HOSTTYPE 227 #define HOSTTYPE "unknown" 228 #endif 229 230 #define extra(m) do \ 231 { \ 232 if ((char*)&ut.m[sizeof(ut.m)] > last) \ 233 last = (char*)&ut.m[sizeof(ut.m)]; \ 234 } while(0) 235 236 #define output(f,v,u) do \ 237 { \ 238 if ((flags&(f))&&(*(v)||(flags&(OPT_all|OPT_total))==OPT_all&&((f)&OPT_standard)||!(flags&(OPT_all|OPT_total)))) \ 239 { \ 240 if (sep) \ 241 sfputc(sfstdout, ' '); \ 242 else \ 243 sep = 1; \ 244 if (*(v)) \ 245 sfputr(sfstdout, v, -1); \ 246 else \ 247 sfprintf(sfstdout, "[%s]", u); \ 248 } \ 249 } while (0) 250 251 int 252 b_uname(int argc, char** argv, Shbltin_t* context) 253 { 254 register long flags = 0; 255 register int sep = 0; 256 register int n; 257 register char* s; 258 char* t; 259 char* e; 260 char* sethost = 0; 261 int list = 0; 262 struct utsname ut; 263 char buf[257]; 264 265 cmdinit(argc, argv, context, ERROR_CATALOG, 0); 266 for (;;) 267 { 268 switch (optget(argv, usage)) 269 { 270 case 'a': 271 flags |= OPT_all|((1L<<OPT_ALL)-1); 272 continue; 273 case 'b': 274 flags |= OPT_base; 275 continue; 276 case 'c': 277 flags |= OPT_vendor; 278 continue; 279 case 'd': 280 flags |= OPT_domain; 281 continue; 282 case 'f': 283 list = 1; 284 continue; 285 case 'h': 286 flags |= OPT_hostid; 287 continue; 288 case 'i': 289 flags |= OPT_implementation; 290 continue; 291 case 'm': 292 flags |= OPT_machine; 293 continue; 294 case 'n': 295 flags |= OPT_nodename; 296 continue; 297 case 'o': 298 flags |= OPT_operating_system; 299 continue; 300 case 'p': 301 flags |= OPT_processor; 302 continue; 303 case 'r': 304 flags |= OPT_release; 305 continue; 306 case 's': 307 flags |= OPT_system; 308 continue; 309 case 't': 310 flags |= OPT_machine_type; 311 continue; 312 case 'v': 313 flags |= OPT_version; 314 continue; 315 case 'x': 316 flags |= OPT_extra; 317 continue; 318 case 'A': 319 flags |= OPT_total|((1L<<OPT_TOTAL)-1); 320 continue; 321 case 'R': 322 flags |= OPT_extended_release; 323 continue; 324 case 'S': 325 sethost = opt_info.arg; 326 continue; 327 case ':': 328 s = "/usr/bin/uname"; 329 if (!streq(argv[0], s) && (!eaccess(s, X_OK) || !eaccess(s+=4, X_OK))) 330 { 331 argv[0] = s; 332 return sh_run(context, argc, argv); 333 } 334 error(2, "%s", opt_info.arg); 335 break; 336 case '?': 337 error(ERROR_usage(2), "%s", opt_info.arg); 338 break; 339 } 340 break; 341 } 342 argv += opt_info.index; 343 if (error_info.errors || *argv && (flags || sethost) || sethost && flags) 344 error(ERROR_usage(2), "%s", optusage(NiL)); 345 if (sethost) 346 { 347 #if _lib_sethostname 348 if (sethostname(sethost, strlen(sethost) + 1)) 349 #else 350 #ifdef ENOSYS 351 errno = ENOSYS; 352 #else 353 errno = EPERM; 354 #endif 355 #endif 356 error(ERROR_system(1), "%s: cannot set host name", sethost); 357 } 358 else if (list) 359 astconflist(sfstdout, NiL, ASTCONF_base|ASTCONF_defined|ASTCONF_lower|ASTCONF_quote|ASTCONF_matchcall, "CS|SI"); 360 else if (*argv) 361 { 362 e = &buf[sizeof(buf)-1]; 363 while (s = *argv++) 364 { 365 t = buf; 366 *t++ = 'C'; 367 *t++ = 'S'; 368 *t++ = '_'; 369 while (t < e && (n = *s++)) 370 *t++ = islower(n) ? toupper(n) : n; 371 *t = 0; 372 sfprintf(sfstdout, "%s%c", *(t = astconf(buf, NiL, NiL)) ? t : *(t = astconf(buf+3, NiL, NiL)) ? t : "unknown", *argv ? ' ' : '\n'); 373 } 374 } 375 else 376 { 377 s = buf; 378 if (!flags) 379 flags = OPT_system; 380 memzero(&ut, sizeof(ut)); 381 if (uname(&ut) < 0) 382 error(ERROR_usage(2), "information unavailable"); 383 output(OPT_system, ut.sysname, "sysname"); 384 if (flags & OPT_nodename) 385 { 386 #if !_mem_nodeext_utsname && _lib_gethostname 387 if (sizeof(ut.nodename) > 9 || gethostname(s, sizeof(buf))) 388 #endif 389 s = ut.nodename; 390 output(OPT_nodename, s, "nodename"); 391 } 392 output(OPT_release, ut.release, "release"); 393 output(OPT_version, ut.version, "version"); 394 output(OPT_machine, ut.machine, "machine"); 395 if (flags & OPT_processor) 396 { 397 if (!*(s = astconf("ARCHITECTURE", NiL, NiL))) 398 s = ut.machine; 399 output(OPT_processor, s, "processor"); 400 } 401 if (flags & OPT_implementation) 402 { 403 if (!*(s = astconf("PLATFORM", NiL, NiL)) && !*(s = astconf("HW_NAME", NiL, NiL))) 404 { 405 if (t = strchr(hosttype, '.')) 406 t++; 407 else 408 t = (char*)hosttype; 409 strncpy(s = buf, t, sizeof(buf) - 1); 410 } 411 output(OPT_implementation, s, "implementation"); 412 } 413 if (flags & OPT_operating_system) 414 { 415 s = astconf("OPERATING_SYSTEM", NiL, NiL); 416 if (!*s) 417 #ifdef _UNAME_os_DEFAULT 418 s = _UNAME_os_DEFAULT; 419 #else 420 s = ut.sysname; 421 #endif 422 output(OPT_operating_system, s, "operating-system"); 423 } 424 if (flags & OPT_extended_release) 425 { 426 s = astconf("RELEASE", NiL, NiL); 427 output(OPT_extended_release, s, "extended-release"); 428 } 429 #if _mem_idnumber_utsname 430 output(OPT_hostid, ut.idnumber, "hostid"); 431 #else 432 if (flags & OPT_hostid) 433 { 434 if (!*(s = astconf("HW_SERIAL", NiL, NiL))) 435 #if _lib_gethostid 436 sfsprintf(s = buf, sizeof(buf), "%08x", gethostid()); 437 #else 438 {/*NOP*/}; 439 #endif 440 output(OPT_hostid, s, "hostid"); 441 } 442 #endif 443 if (flags & OPT_vendor) 444 { 445 s = astconf("HW_PROVIDER", NiL, NiL); 446 output(OPT_vendor, s, "vendor"); 447 } 448 if (flags & OPT_domain) 449 { 450 if (!*(s = astconf("SRPC_DOMAIN", NiL, NiL))) 451 #if _lib_getdomainname 452 getdomainname(s, sizeof(buf)); 453 #else 454 {/*NOP*/}; 455 #endif 456 output(OPT_domain, s, "domain"); 457 } 458 #if _mem_m_type_utsname 459 s = ut.m_type; 460 #else 461 s = astconf("MACHINE", NiL, NiL); 462 #endif 463 output(OPT_machine_type, s, "m_type"); 464 #if _mem_base_rel_utsname 465 s = ut.base_rel; 466 #else 467 s = astconf("BASE", NiL, NiL); 468 #endif 469 output(OPT_base, s, "base_rel"); 470 if (flags & OPT_extra) 471 { 472 char* last = (char*)&ut; 473 474 extra(sysname); 475 extra(nodename); 476 extra(release); 477 extra(version); 478 extra(machine); 479 #if _mem_idnumber_utsname 480 extra(idnumber); 481 #endif 482 #if _mem_m_type_utsname 483 extra(m_type); 484 #endif 485 #if _mem_base_rel_utsname 486 extra(base_rel); 487 #endif 488 if (last < ((char*)(&ut + 1))) 489 { 490 s = t = last; 491 while (s < (char*)(&ut + 1)) 492 { 493 if (!(n = *s++)) 494 { 495 if ((s - t) > 1) 496 { 497 if (sep) 498 sfputc(sfstdout, ' '); 499 else 500 sep = 1; 501 sfputr(sfstdout, t, -1); 502 } 503 t = s; 504 } 505 else if (!isprint(n)) 506 break; 507 } 508 } 509 } 510 if (sep) 511 sfputc(sfstdout, '\n'); 512 } 513 return error_info.errors; 514 } 515