1/* vi: set sw=4 ts=4: */ 2/* 3 * uname -- print system information 4 * Copyright (C) 1989-1999 Free Software Foundation, Inc. 5 * 6 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 7 */ 8/* Option Example 9 * -s, --sysname SunOS 10 * -n, --nodename rocky8 11 * -r, --release 4.0 12 * -v, --version 13 * -m, --machine sun 14 * -a, --all SunOS rocky8 4.0 sun 15 * 16 * The default behavior is equivalent to '-s'. 17 * 18 * David MacKenzie <djm@gnu.ai.mit.edu> 19 * 20 * GNU coreutils 6.10: 21 * Option: struct Example(s): 22 * utsname 23 * field: 24 * -s, --kernel-name sysname Linux 25 * -n, --nodename nodename localhost.localdomain 26 * -r, --kernel-release release 2.6.29 27 * -v, --kernel-version version #1 SMP Sun Jan 11 20:52:37 EST 2009 28 * -m, --machine machine x86_64 i686 29 * -p, --processor (none) x86_64 i686 30 * -i, --hardware-platform (none) x86_64 i386 31 * NB: vanilla coreutils reports "unknown" -p and -i, 32 * x86_64 and i686/i386 shown above are Fedora's inventions. 33 * -o, --operating-system (none) GNU/Linux 34 * -a, --all: all of the above, in the order shown. 35 * If -p or -i is not known, don't show them 36 */ 37/* Busyboxed by Erik Andersen 38 * 39 * Before 2003: Glenn McGrath and Manuel Novoa III 40 * Further size reductions. 41 * Mar 16, 2003: Manuel Novoa III (mjn3@codepoet.org) 42 * Now does proper error checking on i/o. Plus some further space savings. 43 * Jan 2009: 44 * Fix handling of -a to not print "unknown", add -o and -i support. 45 */ 46//config:config UNAME 47//config: bool "uname (3.9 kb)" 48//config: default y 49//config: help 50//config: uname is used to print system information. 51//config: 52//config:config UNAME_OSNAME 53//config: string "Operating system name" 54//config: default "GNU/Linux" 55//config: depends on UNAME 56//config: help 57//config: Sets the operating system name reported by uname -o. The 58//config: default is "GNU/Linux". 59//config: 60//can't use "ARCH" for this applet, all hell breaks loose in build system :) 61//config:config BB_ARCH 62//config: bool "arch (1.1 kb)" 63//config: default y 64//config: help 65//config: Same as uname -m. 66 67// APPLET_NOFORK:name main location suid_type help 68//applet:IF_UNAME(APPLET_NOFORK( uname, uname, BB_DIR_BIN, BB_SUID_DROP, uname)) 69//applet:IF_BB_ARCH(APPLET_NOFORK(arch, uname, BB_DIR_BIN, BB_SUID_DROP, arch)) 70 71//kbuild:lib-$(CONFIG_UNAME) += uname.o 72//kbuild:lib-$(CONFIG_BB_ARCH) += uname.o 73 74/* BB_AUDIT SUSv3 compliant */ 75/* http://www.opengroup.org/onlinepubs/007904975/utilities/uname.html */ 76 77//usage:#define uname_trivial_usage 78//usage: "[-amnrspvio]" 79//usage:#define uname_full_usage "\n\n" 80//usage: "Print system information\n" 81//usage: "\n -a Print all" 82//usage: "\n -m Machine (hardware) type" 83//usage: "\n -n Hostname" 84//usage: "\n -r Kernel release" 85//usage: "\n -s Kernel name (default)" 86//usage: "\n -p Processor type" 87//usage: "\n -v Kernel version" 88//usage: "\n -i Hardware platform" 89//usage: "\n -o OS name" 90//usage: 91//usage:#define uname_example_usage 92//usage: "$ uname -a\n" 93//usage: "Linux debian 2.4.23 #2 Tue Dec 23 17:09:10 MST 2003 i686 GNU/Linux\n" 94 95//usage:#define arch_trivial_usage 96//usage: "" 97//usage:#define arch_full_usage "\n\n" 98//usage: "Print system architecture" 99 100#include "libbb.h" 101/* After libbb.h, since it needs sys/types.h on some systems */ 102#include <sys/utsname.h> 103 104typedef struct { 105 struct utsname name; 106 char processor[sizeof(((struct utsname*)NULL)->machine)]; 107 char platform[sizeof(((struct utsname*)NULL)->machine)]; 108 char os[sizeof(CONFIG_UNAME_OSNAME)]; 109} uname_info_t; 110 111#if ENABLE_UNAME 112#define options "snrvmpioa" 113static const unsigned short utsname_offset[] = { 114 offsetof(uname_info_t, name.sysname), /* -s */ 115 offsetof(uname_info_t, name.nodename), /* -n */ 116 offsetof(uname_info_t, name.release), /* -r */ 117 offsetof(uname_info_t, name.version), /* -v */ 118 offsetof(uname_info_t, name.machine), /* -m */ 119 offsetof(uname_info_t, processor), /* -p */ 120 offsetof(uname_info_t, platform), /* -i */ 121 offsetof(uname_info_t, os), /* -o */ 122}; 123#endif 124 125int uname_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 126int uname_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) 127{ 128 uname_info_t uname_info; 129 IF_UNAME(const char *unknown_str = "unknown";) 130#if ENABLE_UNAME 131 unsigned toprint = (1 << 4); /* "arch" = "uname -m" */ 132 133 if (!ENABLE_BB_ARCH || applet_name[0] == 'u') { 134# if ENABLE_LONG_OPTS 135 static const char uname_longopts[] ALIGN1 = 136 /* name, has_arg, val */ 137 "all\0" No_argument "a" 138 "kernel-name\0" No_argument "s" 139 "nodename\0" No_argument "n" 140 "kernel-release\0" No_argument "r" 141 "release\0" No_argument "r" 142 "kernel-version\0" No_argument "v" 143 "machine\0" No_argument "m" 144 "processor\0" No_argument "p" 145 "hardware-platform\0" No_argument "i" 146 "operating-system\0" No_argument "o" 147 ; 148# endif 149 toprint = getopt32long(argv, options, uname_longopts); 150 if (argv[optind]) { /* coreutils-6.9 compat */ 151 bb_show_usage(); 152 } 153 if (toprint & (1 << 8)) { /* -a => all opts on */ 154 toprint = (1 << 8) - 1; 155 unknown_str = ""; /* -a does not print unknown fields */ 156 } 157 if (toprint == 0) { /* no opts => -s (sysname) */ 158 toprint = 1; 159 } 160 } /* if "uname" */ 161#endif 162 163 uname(&uname_info.name); /* never fails */ 164 165#if defined(__sparc__) && defined(__linux__) 166 { 167 char *fake_sparc = getenv("FAKE_SPARC"); 168 if (fake_sparc && (fake_sparc[0] | 0x20) == 'y') { 169 strcpy(uname_info.name.machine, "sparc"); 170 } 171 } 172#endif 173 if (ENABLE_BB_ARCH && (!ENABLE_UNAME || applet_name[0] == 'a')) { 174 puts(uname_info.name.machine); 175 } else { 176#if ENABLE_UNAME 177 /* "uname" */ 178 const char *fmt; 179 const unsigned short *delta; 180 181 strcpy(uname_info.processor, unknown_str); 182 strcpy(uname_info.platform, unknown_str); 183 strcpy(uname_info.os, CONFIG_UNAME_OSNAME); 184# if ENABLE_FEDORA_COMPAT 185 /* Fedora does something like this */ 186 strcpy(uname_info.processor, uname_info.name.machine); 187 strcpy(uname_info.platform, uname_info.name.machine); 188 if (uname_info.platform[0] == 'i' 189 && uname_info.platform[1] 190 && uname_info.platform[2] == '8' 191 && uname_info.platform[3] == '6' 192 ) { 193 uname_info.platform[1] = '3'; 194 } 195# endif 196 delta = utsname_offset; 197 fmt = " %s" + 1; 198 do { 199 if (toprint & 1) { 200 const char *p = (char *)(&uname_info) + *delta; 201 if (p[0]) { 202 printf(fmt, p); 203 fmt = " %s"; 204 } 205 } 206 ++delta; 207 } while (toprint >>= 1); 208 bb_putchar('\n'); 209#endif 210 } 211 212 fflush_stdout_and_exit_SUCCESS(); /* coreutils-6.9 compat */ 213} 214