2023-05-03 16:17:56 +00:00
|
|
|
#include "../command.h"
|
|
|
|
|
|
|
|
static struct {
|
|
|
|
bool make_parent;
|
|
|
|
mode_t mode;
|
|
|
|
} flags;
|
|
|
|
|
|
|
|
static int short_arg(char c, char* next) {
|
|
|
|
switch (c) {
|
|
|
|
case 'p':
|
|
|
|
flags.make_parent = true;
|
|
|
|
break;
|
|
|
|
case 'm':
|
|
|
|
check_arg(next);
|
|
|
|
flags.mode = get_mode(next);
|
|
|
|
return ARG_USED;
|
|
|
|
default:
|
|
|
|
return ARG_INVALID;
|
|
|
|
}
|
|
|
|
return ARG_UNUSED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void help(void) {
|
|
|
|
printf("Usage: mkdir [-m MODE] [-p] DIRECTORY...\n\n");
|
|
|
|
printf("Create DIRECTORY\n\n");
|
|
|
|
printf("\t-m\tMODE\n");
|
|
|
|
printf("\t-p\tNo error if exists; make parent directories as needed\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool mkdir_parents(char* path) {
|
2023-05-04 20:10:37 +00:00
|
|
|
size_t i;
|
|
|
|
for (i = 1; i < strlen(path); i++) {
|
2023-05-03 16:17:56 +00:00
|
|
|
if (path[i] != '/') continue;
|
|
|
|
path[i] = '\0';
|
|
|
|
if (mkdir(path, flags.mode) < 0 && errno != EEXIST) {
|
|
|
|
error_s("failed to create directory '%s': %s", path, strerror(errno));
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
path[i] = '/';
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
COMMAND(makedir) {
|
2023-05-04 20:10:37 +00:00
|
|
|
|
|
|
|
int start, i;
|
|
|
|
|
2023-05-03 16:17:56 +00:00
|
|
|
if (argc < 1) global_help(help);
|
|
|
|
|
|
|
|
flags.make_parent = false;
|
|
|
|
flags.mode = 0755;
|
2023-05-04 20:10:37 +00:00
|
|
|
|
|
|
|
start = parse_args(argc, argv, help, short_arg, NULL);
|
2023-05-03 16:17:56 +00:00
|
|
|
|
2023-05-04 20:10:37 +00:00
|
|
|
for (i = start; i < argc; i++) {
|
2023-05-03 16:17:56 +00:00
|
|
|
if (flags.make_parent && !mkdir_parents(argv[i])) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (mkdir(argv[i], flags.mode) < 0) {
|
|
|
|
error_s("failed to create directory '%s': %s", argv[i], strerror(errno));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|