1 /* This file is part of Netwib. Read and honor its license.
2 */
3
4 /*-------------------------------------------------------------*/
netwib_priv_dir_create(netwib_constbuf * pdirname)5 netwib_err netwib_priv_dir_create(netwib_constbuf *pdirname)
6 {
7 netwib_string dirnamestr;
8 netwib_bool errwin240;
9 int reti;
10
11 netwib__constbuf_ref_string(pdirname, dirnamestr, bufstorage,
12 netwib_priv_dir_create(&bufstorage));
13
14 errwin240 = NETWIB_FALSE;
15 #if defined NETWIBDEF_SYSNAME_Unix
16 reti = mkdir(dirnamestr, 0700);
17 #elif defined NETWIBDEF_SYSNAME_Windows
18 reti = _mkdir(dirnamestr);
19 if (reti == -1) {
20 if (errno == ENOENT) {
21 errwin240 = NETWIB_TRUE;
22 }
23 }
24 #else
25 #error "Unknown value for NETWIBDEF_SYSNAME"
26 #endif
27
28 if (reti == -1) {
29 netwib_er(netwib_priv_errmsg_string("cannot create this dir: "));
30 netwib_er(netwib_priv_errmsg_append_buf(pdirname));
31 #if defined NETWIBDEF_SYSNAME_Unix
32 #elif defined NETWIBDEF_SYSNAME_Windows
33 if (errwin240) {
34 netwib_er(netwib_priv_errmsg_append_string(" (origin of this problem is perhaps Windows'limitation of 240 chars for total pathname length)"));
35 }
36 #else
37 #error "Unknown value for NETWIBDEF_SYSNAME"
38 #endif
39 return(NETWIB_ERR_FUMKDIR);
40 }
41
42 return(NETWIB_ERR_OK);
43 }
44
45 /*-------------------------------------------------------------*/
netwib_priv_dir_create_recur(netwib_constbuf * pdirname,netwib_uint32 numcall)46 static netwib_err netwib_priv_dir_create_recur(netwib_constbuf *pdirname,
47 netwib_uint32 numcall)
48 {
49 netwib_byte array[512];
50 netwib_buf parent;
51 netwib_bool yes;
52 netwib_err ret;
53
54 numcall++;
55 if (numcall > 100) {
56 /* we suppose it is not legitimate to create too many directories */
57 return(NETWIB_ERR_PATOOHIGH);
58 }
59
60 netwib_er(netwib_buf_init_ext_storagearraysizeof(array, &parent));
61 ret = netwib_path_decode_parent(pdirname, &parent);
62 if (ret == NETWIB_ERR_PAPATHCANTINIT) {
63 /* can't go up: we will directly create directory */
64 ret = NETWIB_ERR_OK;
65 } else if (ret == NETWIB_ERR_OK) {
66 /* eventually create parent */
67 netwib_er(netwib_dirname_exists(&parent, &yes));
68 if ( !yes ) {
69 ret = netwib_priv_dir_create_recur(&parent, numcall);
70 }
71 }
72 netwib_er(netwib_buf_close(&parent));
73
74 if (ret == NETWIB_ERR_OK) {
75 ret = netwib_priv_dir_create(pdirname);
76 }
77
78 return(ret);
79 }
80
81 /*-------------------------------------------------------------*/
netwib_priv_dir_create_parents(netwib_constbuf * ppathname)82 netwib_err netwib_priv_dir_create_parents(netwib_constbuf *ppathname)
83 {
84 netwib_byte parentarray[512], startarray[128];
85 netwib_buf parent, start;
86 netwib_bool yes;
87 netwib_err ret;
88
89 /* obtain parent */
90 netwib_er(netwib_buf_init_ext_storagearraysizeof(parentarray, &parent));
91 ret = netwib_path_decode_parent(ppathname, &parent);
92 if (ret == NETWIB_ERR_PAPATHCANTINIT) {
93 /* can't go up */
94 netwib_er(netwib_buf_close(&parent));
95 return(NETWIB_ERR_OK);
96 } else if (ret != NETWIB_ERR_OK) {
97 netwib_er(netwib_buf_close(&parent));
98 return(ret);
99 }
100
101 /* if parent exists, do not need to continue */
102 netwib_er(netwib_dirname_exists(&parent, &yes));
103 if ( yes ) {
104 netwib_er(netwib_buf_close(&parent));
105 return(NETWIB_ERR_OK);
106 }
107
108 /* check if begin directory exists */
109 netwib_er(netwib_buf_init_ext_storagearraysizeof(startarray, &start));
110 netwib_er(netwib_path_decode_begin(&parent, &start));
111 netwib_er(netwib_dirname_exists(&start, &yes));
112 if ( !yes ) {
113 netwib_er(netwib_priv_errmsg_string("cannot create this dir: "));
114 netwib_er(netwib_priv_errmsg_append_buf(&start));
115 netwib_er(netwib_buf_close(&start));
116 netwib_er(netwib_buf_close(&parent));
117 return(NETWIB_ERR_NOTFOUND);
118 }
119 netwib_er(netwib_buf_close(&start));
120
121 /* create parent */
122 ret = netwib_priv_dir_create_recur(&parent, 0);
123 if (ret != NETWIB_ERR_OK) {
124 netwib_er(netwib_priv_errmsg_string("cannot create parent dir: "));
125 netwib_er(netwib_priv_errmsg_append_buf(&parent));
126 }
127 netwib_er(netwib_buf_close(&parent));
128
129 return(ret);
130 }
131