logo

utils-std

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

mkdir.c (2210B)


  1. // utils-std: Collection of commonly available Unix tools
  2. // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
  3. // SPDX-License-Identifier: MPL-2.0
  4. #define _POSIX_C_SOURCE 200809L
  5. #include "../lib/lib_mkdir.h"
  6. #include "../lib/mode.h"
  7. #include <errno.h>
  8. #include <stdbool.h>
  9. #include <stdio.h> // fprintf
  10. #include <stdlib.h> // abort
  11. #include <string.h> // strerror
  12. #include <sys/stat.h> // mkdir
  13. #include <unistd.h> // getopt
  14. const char *argv0 = "mkdir";
  15. bool mkdir_parents_verbose = false;
  16. mode_t mkdir_parents_filemask;
  17. static int
  18. mkdir_simple(char *path, mode_t mode)
  19. {
  20. if(mkdir(path, mode) < 0)
  21. {
  22. fprintf(stderr, "%s: error: Failed making directory '%s': %s\n", argv0, path, strerror(errno));
  23. errno = 0;
  24. return -1;
  25. }
  26. if(mkdir_parents_verbose) fprintf(stderr, "%s: Made directory: %s\n", argv0, path);
  27. return 0;
  28. }
  29. static void
  30. usage(void)
  31. {
  32. fprintf(stderr, "Usage: mkdir [-pv] [-m mode] path ...\n");
  33. }
  34. int
  35. main(int argc, char *argv[])
  36. {
  37. mkdir_parents_filemask = umask(0);
  38. umask(mkdir_parents_filemask);
  39. // clang-format off
  40. mode_t mode = (S_IRWXU | S_IRWXG | S_IRWXO | ~mkdir_parents_filemask) & 0777;
  41. bool opt_p = false;
  42. const char *errstr = NULL;
  43. // clang-format on
  44. for(int c = -1; (c = getopt(argc, argv, ":pvm:")) != -1;)
  45. {
  46. switch(c)
  47. {
  48. case 'p':
  49. opt_p = true;
  50. break;
  51. case 'v':
  52. mkdir_parents_verbose = true;
  53. break;
  54. case 'm':
  55. mode = new_mode(optarg, 0777, &errstr);
  56. if(errstr != NULL)
  57. {
  58. fprintf(stderr, "%s: error: Failed parsing mode '%s': %s\n", argv0, optarg, errstr);
  59. return 1;
  60. }
  61. break;
  62. case ':':
  63. fprintf(stderr, "%s: error: Missing operand for option: '-%c'\n", argv0, optopt);
  64. usage();
  65. return 1;
  66. case '?':
  67. fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
  68. usage();
  69. return 1;
  70. default:
  71. abort();
  72. }
  73. }
  74. argc -= optind;
  75. argv += optind;
  76. if(argc < 1)
  77. {
  78. fprintf(stderr, "%s: error: Missing operand\n", argv0);
  79. usage();
  80. return 1;
  81. }
  82. for(int i = 0; i < argc; i++)
  83. {
  84. int ret = 0;
  85. if(opt_p)
  86. ret = mkdir_parents(argv[i], mode);
  87. else
  88. ret = mkdir_simple(argv[i], mode);
  89. if(ret < 0) return 1;
  90. }
  91. return 0;
  92. }