logo

utils-std

Collection of commonly available Unix tools

uname.c (2307B)


  1. // utils-std: Collection of commonly available Unix tools
  2. // SPDX-FileCopyrightText: 2017-2022 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
  3. // SPDX-License-Identifier: MPL-2.0
  4. #define _POSIX_C_SOURCE 200809L
  5. #include "../lib/bitmasks.h"
  6. #include <errno.h>
  7. #include <stdio.h> // printf
  8. #include <stdlib.h> // exit, abort
  9. #include <string.h> // strerror
  10. #include <sys/utsname.h> // uname
  11. #include <unistd.h> // getopt
  12. enum uname_names
  13. {
  14. CMD_UNAME_SYSNAME = 1 << 1,
  15. CMD_UNAME_NODENAME = 1 << 2,
  16. CMD_UNAME_RELEASE = 1 << 3,
  17. CMD_UNAME_VERSION = 1 << 4,
  18. CMD_UNAME_MACHINE = 1 << 5,
  19. CMD_UNAME_ALL = CMD_UNAME_SYSNAME | CMD_UNAME_NODENAME | CMD_UNAME_RELEASE | CMD_UNAME_VERSION |
  20. CMD_UNAME_MACHINE,
  21. };
  22. const char *fmt = "%s";
  23. enum uname_names names = 0;
  24. static void
  25. maybe_print_name(enum uname_names key, char *value)
  26. {
  27. if(FIELD_MATCH(names, key))
  28. {
  29. if(printf(fmt, value) < 0)
  30. {
  31. fprintf(stderr, "uname: Write Error: %s", strerror(errno));
  32. exit(1);
  33. }
  34. fmt = " %s";
  35. }
  36. }
  37. static void
  38. usage()
  39. {
  40. fprintf(stderr, "Usage: uname [-amnrsv]\n");
  41. }
  42. int
  43. main(int argc, char *argv[])
  44. {
  45. int c = -1;
  46. while((c = getopt(argc, argv, ":amnrsv")) != -1)
  47. {
  48. switch(c)
  49. {
  50. case 'a':
  51. names = CMD_UNAME_ALL;
  52. break;
  53. case 'm':
  54. names |= CMD_UNAME_MACHINE;
  55. break;
  56. case 'n':
  57. names |= CMD_UNAME_NODENAME;
  58. break;
  59. case 'r':
  60. names |= CMD_UNAME_RELEASE;
  61. break;
  62. case 's':
  63. names |= CMD_UNAME_SYSNAME;
  64. break;
  65. case 'v':
  66. names |= CMD_UNAME_VERSION;
  67. break;
  68. case ':':
  69. fprintf(stderr, "uname: Error: Missing operand for option: '-%c'\n", optopt);
  70. usage();
  71. return 1;
  72. case '?':
  73. fprintf(stderr, "uname: Error: Unrecognised option: '-%c'\n", optopt);
  74. usage();
  75. return 1;
  76. default:
  77. abort();
  78. }
  79. }
  80. if(names == 0) names |= CMD_UNAME_SYSNAME;
  81. struct utsname name;
  82. if(uname(&name) != 0)
  83. {
  84. fprintf(
  85. stderr, "uname: Failed getting current system names via uname(): %s\n", strerror(errno));
  86. return 1;
  87. }
  88. maybe_print_name(CMD_UNAME_SYSNAME, name.sysname);
  89. maybe_print_name(CMD_UNAME_NODENAME, name.nodename);
  90. maybe_print_name(CMD_UNAME_RELEASE, name.release);
  91. maybe_print_name(CMD_UNAME_VERSION, name.version);
  92. maybe_print_name(CMD_UNAME_MACHINE, name.machine);
  93. printf("\n");
  94. return 0;
  95. }