1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1992-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
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
uname(register struct utsname * ut)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
b_uname(int argc,char ** argv,void * context)252 b_uname(int argc, char** argv, void* 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