logo

utils-std

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

mkdir.c (2212B)


  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. int c = -1;
  45. while((c = getopt(argc, argv, ":pvm:")) != -1)
  46. {
  47. switch(c)
  48. {
  49. case 'p':
  50. opt_p = true;
  51. break;
  52. case 'v':
  53. mkdir_parents_verbose = true;
  54. break;
  55. case 'm':
  56. mode = new_mode(optarg, 0777, &errstr);
  57. if(errstr != NULL)
  58. {
  59. fprintf(stderr, "%s: error: Failed parsing mode '%s': %s\n", argv0, optarg, errstr);
  60. return 1;
  61. }
  62. break;
  63. case ':':
  64. fprintf(stderr, "%s: error: Missing operand for option: '-%c'\n", argv0, optopt);
  65. usage();
  66. return 1;
  67. case '?':
  68. fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
  69. usage();
  70. return 1;
  71. default:
  72. abort();
  73. }
  74. }
  75. argc -= optind;
  76. argv += optind;
  77. if(argc < 1)
  78. {
  79. fprintf(stderr, "%s: error: Missing operand\n", argv0);
  80. usage();
  81. return 1;
  82. }
  83. for(int i = 0; i < argc; i++)
  84. {
  85. int ret = 0;
  86. if(opt_p)
  87. ret = mkdir_parents(argv[i], mode);
  88. else
  89. ret = mkdir_simple(argv[i], mode);
  90. if(ret < 0) return 1;
  91. }
  92. return 0;
  93. }