chmod.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /* SPDX-License-Identifier: BSD-3-Clause */
  2. /*
  3. * Copyright (C) 2022, 2023 Ferass El Hafidi <vitali64pmemail@protonmail.com>
  4. */
  5. #include <sys/stat.h>
  6. #include <unistd.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <errno.h>
  11. #define REQ_PRINT_USAGE /* Require print_usage() from ../common/common.h */
  12. #define REQ_ERRPRINT /* Require errprint() from ../common/common.h */
  13. #define DESCRIPTION "Change file modes."
  14. #define OPERANDS "mode file"
  15. #include "../common/common.h"
  16. int main(int argc, char *const argv[]) {
  17. int argument, i = 0;
  18. mode_t owner_modes, group_modes, other_modes;
  19. char *argv0 = strdup(argv[0]);
  20. if (argc == 1) {
  21. print_usage(argv[0], DESCRIPTION, OPERANDS, VERSION);
  22. return 1;
  23. }
  24. while ((argument = getopt(argc, argv, "")) != -1) {
  25. if (argument == '?') {
  26. print_usage(argv[0], DESCRIPTION, OPERANDS, VERSION);
  27. return 1;
  28. }
  29. } argc -= optind; argv += optind;
  30. /* I know there's a better way of doing it, please let me know if you
  31. * know a better way of doing it
  32. */
  33. if (argv[0][i] == '0') i++;
  34. switch (argv[0][i]) {
  35. /* Owner modes */
  36. case '7':
  37. owner_modes = S_IRWXU;
  38. break;
  39. case '4':
  40. owner_modes = S_IRUSR;
  41. break;
  42. case '2':
  43. owner_modes = S_IWUSR;
  44. break;
  45. case '1':
  46. owner_modes = S_IXUSR;
  47. break;
  48. default:
  49. print_usage(argv0, DESCRIPTION, OPERANDS, VERSION);
  50. return 1;
  51. }
  52. i++;
  53. switch (argv[0][i]) {
  54. /* Group modes */
  55. case '7':
  56. group_modes = S_IRWXG;
  57. break;
  58. case '4':
  59. group_modes = S_IRGRP;
  60. break;
  61. case '2':
  62. group_modes = S_IWGRP;
  63. break;
  64. case '1':
  65. group_modes = S_IXGRP;
  66. break;
  67. default:
  68. print_usage(argv0, DESCRIPTION, OPERANDS, VERSION);
  69. return 1;
  70. }
  71. i++;
  72. switch (argv[0][i]) {
  73. /* Other modes */
  74. case '7':
  75. other_modes = S_IRWXO;
  76. break;
  77. case '4':
  78. other_modes = S_IROTH;
  79. break;
  80. case '2':
  81. other_modes = S_IWOTH;
  82. break;
  83. case '1':
  84. other_modes = S_IXOTH;
  85. break;
  86. default:
  87. print_usage(argv0, DESCRIPTION, OPERANDS, VERSION);
  88. return 1;
  89. }
  90. chmod(argv[1], owner_modes | group_modes | other_modes);
  91. return errprint(argv[0], "chmod()", errno);
  92. }