logo

utils

~/.local/bin tools and git-hooks git clone https://hacktivis.me/git/utils.git

env.c (1953B)


  1. // Collection of Unix tools, comparable to coreutils
  2. // SPDX-FileCopyrightText: 2017-2022 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
  3. // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
  4. #define _POSIX_C_SOURCE 200809L
  5. #include <assert.h> // assert
  6. #include <errno.h> // errno
  7. #include <stdbool.h> // bool, true, false
  8. #include <stdio.h> // puts, perror, fprintf
  9. #include <stdlib.h> // putenv
  10. #include <string.h> // strchr
  11. #include <unistd.h> // getopt, opt*
  12. extern char **environ;
  13. char *envclear[1];
  14. int export()
  15. {
  16. int i = 0;
  17. for(; environ[i] != NULL; i++)
  18. {
  19. if(puts(environ[i]) < 0)
  20. {
  21. perror("env: puts");
  22. return 1;
  23. }
  24. }
  25. return 0;
  26. }
  27. void
  28. usage()
  29. {
  30. fprintf(stderr, "env [-i] [-u key] [key=value ...] [command [args]]\n");
  31. }
  32. int
  33. main(int argc, char *argv[])
  34. {
  35. int c;
  36. bool flag_i = false;
  37. /* flawfinder: ignore. Old implementations of getopt should fix themselves */
  38. while((c = getopt(argc, argv, ":iu:")) != -1)
  39. {
  40. switch(c)
  41. {
  42. case 'i':
  43. flag_i = true;
  44. break;
  45. case 'u':
  46. unsetenv(optarg);
  47. break;
  48. case ':':
  49. fprintf(stderr, "Error: Missing operand for option: '-%c'\n", optopt);
  50. usage();
  51. return 1;
  52. case '?':
  53. fprintf(stderr, "Error: Unrecognised option: '-%c'\n", optopt);
  54. usage();
  55. return 1;
  56. default:
  57. assert(false);
  58. }
  59. }
  60. argc -= optind;
  61. argv += optind;
  62. if(flag_i)
  63. {
  64. environ = envclear;
  65. envclear[0] = NULL;
  66. }
  67. for(; argv[0]; argv++, argc--)
  68. {
  69. char *sep = strchr(argv[0], '=');
  70. if(sep == NULL)
  71. {
  72. break;
  73. }
  74. *sep = 0;
  75. sep++;
  76. if(setenv(argv[0], sep, 1))
  77. {
  78. perror("env: setenv:");
  79. return 1;
  80. }
  81. }
  82. if(argc < 1)
  83. {
  84. return export();
  85. }
  86. assert(argv[0]);
  87. errno = 0;
  88. /* flawfinder: ignore. No restrictions on commands is intended */
  89. if(execvp(argv[0], argv) < 0)
  90. {
  91. if(errno == ENOENT)
  92. {
  93. perror("env: execve");
  94. return 127;
  95. }
  96. else
  97. {
  98. perror("env: execve");
  99. return 126;
  100. }
  101. }
  102. assert(false);
  103. }