#define _POSIX_C_SOURCE 200809L #include #include #include #include int main(int argc, char * argv[]) { /* The utsname struct has to be preallocated for uname() to work. */ struct utsname * sys_name = malloc(sizeof(*sys_name)); if(sys_name == NULL) { fprintf(stderr, "%s: insufficient memory\n", argv[0]); return 2; } int stuff_printed = 0; char c; /* This variable holds what all we need to print, corresponding to the following options: 01: -m (Machine type) 02: -n (Hostname) 04: -r (Release) 010: -s (Operating system) 020: -v (Version) 037: -a (Everything) */ int stuff_print = 0; /* Get options */ while((c = getopt(argc, argv, "amnrsv")) != -1) { switch(c) { case 'm': stuff_print |= 01; break; case 'n': stuff_print |= 02; break; case 'r': stuff_print |= 04; break; case 's': stuff_print |= 010; break; case 'v': stuff_print |= 020; break; case 'a': stuff_print |= 037; break; } /* If we saw -a, then just leave, we're done here. */ if(c == 'a') { break; } } /* If no options specified, print OS name */ if(stuff_print == 0) { stuff_print = 010; } int got_uname = 0; got_uname = uname(sys_name); /* Try to get the utsname struct */ if(got_uname == -1) { fprintf(stderr, "%s: could not get uname\n", argv[0]); return 1; } /* Print everything and trailing newline */ if(stuff_print & 010) { printf("%s ", sys_name->sysname); } if(stuff_print & 02) { printf("%s ", sys_name->nodename); } if(stuff_print & 04) { printf("%s ", sys_name->release); } if(stuff_print & 020) { printf("%s ", sys_name->version); } if(stuff_print & 01) { printf("%s", sys_name->machine); } printf("\n"); return 0; }