Initial commit
[mkdir_p.git] / mkdir_p.c
1 /*
2  * mkdir_p, a very simple `mkdir -p` implementation in C
3  * Copyright (C) 2016  Rafał Długołęcki
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; version 2 of the License.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21
22 #include "mkdir_p.h"
23
24 int mkdir_p(const char *pathname, mode_t mode)
25 {
26         int i = 0;
27         int error = 0;
28         char * path = NULL;
29         int len = 0;
30         
31         if (pathname == NULL) {
32                 return -1;
33         }
34         
35         len = strlen(pathname);
36
37         if (pathname[0] == MKDIR_P_SEPARATOR) {
38                 i = 1;
39         }
40
41         while ((i <= len) && !error) {
42                 if ((i + 1 < len) && (pathname[i + 1] == MKDIR_P_SEPARATOR)) {
43                         path = malloc(sizeof(char) * (i + 2));
44                         strncpy(path, pathname, i + 1);
45                         path[i + 1] = '\0';
46                 }
47                 else if ((i + 1 == len) && (pathname[i] != MKDIR_P_SEPARATOR)) {
48                         path = malloc(sizeof(char) * (i + 2));
49                         strncpy(path, pathname, i + 1);
50                         path[i + 1] = '\0';
51                 }
52
53
54                 if (path != NULL) {
55                         error = mkdir(path, mode);
56
57                         if ((error != 0) && (errno != EEXIST)) {
58                                 perror("Unable to create directory");
59                         }
60                         else {
61                                 error = 0;
62                         }
63
64                         free(path);
65                         path = NULL;
66                 }
67                 i++;
68         }
69
70         return error;
71 }
72
73 #ifdef _MKDIR_P_STANDALONE
74
75 int main(int argc, char ** argv)
76 {
77         if (argc == 2) {
78                 return mkdir_p(argv[1], 0700);
79         }
80         else {
81                 puts("mkdir_p, a very simple `mkdir -p` implementation in C");
82                 puts("Version: " MKDIR_P_VERSION);
83                 puts("\n\tUsage: mkdir_p PATH\n\n");
84         }
85         
86         return 0;
87 }
88
89 #endif /* _MKDIR_P_STANDALONE */