logo

utils-std

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

uname.c (2441B)


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