logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git/

uname.c (2354B)


  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: error: Failed writing %s", strerror(errno));
  32. exit(1);
  33. }
  34. fmt = " %s";
  35. }
  36. }
  37. static void
  38. usage(void)
  39. {
  40. fprintf(stderr, "Usage: uname [-amnprsv]\n");
  41. }
  42. int
  43. main(int argc, char *argv[])
  44. {
  45. int c = -1;
  46. while((c = getopt(argc, argv, ":amnprsv")) != -1)
  47. {
  48. switch(c)
  49. {
  50. case 'a':
  51. names = CMD_UNAME_ALL;
  52. break;
  53. case 'p':
  54. case 'm':
  55. names |= CMD_UNAME_MACHINE;
  56. break;
  57. case 'n':
  58. names |= CMD_UNAME_NODENAME;
  59. break;
  60. case 'r':
  61. names |= CMD_UNAME_RELEASE;
  62. break;
  63. case 's':
  64. names |= CMD_UNAME_SYSNAME;
  65. break;
  66. case 'v':
  67. names |= CMD_UNAME_VERSION;
  68. break;
  69. case ':':
  70. fprintf(stderr, "uname: error: Missing operand for option: '-%c'\n", optopt);
  71. usage();
  72. return 1;
  73. case '?':
  74. fprintf(stderr, "uname: error: Unrecognised option: '-%c'\n", optopt);
  75. usage();
  76. return 1;
  77. default:
  78. abort();
  79. }
  80. }
  81. if(names == 0) names |= CMD_UNAME_SYSNAME;
  82. struct utsname name;
  83. if(uname(&name) != 0)
  84. {
  85. fprintf(stderr,
  86. "uname: error: Failed getting current system names via uname(): %s\n",
  87. strerror(errno));
  88. return 1;
  89. }
  90. maybe_print_name(CMD_UNAME_SYSNAME, name.sysname);
  91. maybe_print_name(CMD_UNAME_NODENAME, name.nodename);
  92. maybe_print_name(CMD_UNAME_RELEASE, name.release);
  93. maybe_print_name(CMD_UNAME_VERSION, name.version);
  94. maybe_print_name(CMD_UNAME_MACHINE, name.machine);
  95. printf("\n");
  96. return 0;
  97. }