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