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