1 /*@ S-nail - a mail user agent derived from Berkeley Mail.
2  *@ Path and directory related operations.
3  *
4  * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
5  * Copyright (c) 2012 - 2020 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
6  * SPDX-License-Identifier: BSD-3-Clause TODO ISC
7  */
8 /*
9  * Copyright (c) 1980, 1993
10  *      The Regents of the University of California.  All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36 #undef su_FILE
37 #define su_FILE path
38 #define mx_SOURCE
39 
40 #ifndef mx_HAVE_AMALGAMATION
41 # include "mx/nail.h"
42 #endif
43 
44 #include <su/cs.h>
45 
46 /* TODO fake */
47 #include "su/code-in.h"
48 
49 FL boole
n_is_dir(char const * name,boole check_access)50 n_is_dir(char const *name, boole check_access){
51    struct stat sbuf;
52    boole rv;
53    NYD2_IN;
54 
55    if((rv = (stat(name, &sbuf) == 0))){
56       if((rv = (S_ISDIR(sbuf.st_mode) != 0)) && check_access){
57          int mode;
58 
59          mode = R_OK | X_OK;
60          if(check_access != TRUM1)
61             mode |= W_OK;
62          rv = (access(name, mode) == 0);
63       }
64    }
65    NYD2_OU;
66    return rv;
67 }
68 
69 FL boole
n_path_mkdir(char const * name)70 n_path_mkdir(char const *name){
71    struct stat st;
72    boole rv;
73    NYD_IN;
74 
75 jredo:
76    if(!mkdir(name, 0777))
77       rv = TRU1;
78    else{
79       int e = su_err_no();
80 
81       /* Try it recursively */
82       if(e == su_ERR_NOENT){
83          char const *vp;
84 
85          if((vp = su_cs_rfind_c(name, '/')) != NULL){ /* TODO magic dirsep */
86             while(vp > name && vp[-1] == '/')
87                --vp;
88             vp = savestrbuf(name, P2UZ(vp - name));
89 
90             if(n_path_mkdir(vp))
91                goto jredo;
92          }
93       }
94 
95       rv = ((e == su_ERR_EXIST || e == su_ERR_NOSYS) && !stat(name, &st) &&
96             S_ISDIR(st.st_mode));
97    }
98    NYD_OU;
99    return rv;
100 }
101 
102 FL boole
n_path_rm(char const * name)103 n_path_rm(char const *name){
104    struct stat sb;
105    boole rv;
106    NYD2_IN;
107 
108    if(stat(name, &sb) != 0)
109       rv = FAL0;
110    else if(!S_ISREG(sb.st_mode))
111       rv = TRUM1;
112    else
113       rv = (unlink(name) == 0);
114    NYD2_OU;
115    return rv;
116 }
117 
118 #ifdef mx_HAVE_FCHDIR
119 FL enum okay
cwget(struct cw * cw)120 cwget(struct cw *cw)
121 {
122    enum okay rv = STOP;
123    NYD_IN;
124 
125    if ((cw->cw_fd = open(".", O_RDONLY)) == -1)
126       goto jleave;
127    if (fchdir(cw->cw_fd) == -1) {
128       close(cw->cw_fd);
129       goto jleave;
130    }
131    rv = OKAY;
132 jleave:
133    NYD_OU;
134    return rv;
135 }
136 
137 FL enum okay
cwret(struct cw * cw)138 cwret(struct cw *cw)
139 {
140    enum okay rv = STOP;
141    NYD_IN;
142 
143    if (!fchdir(cw->cw_fd))
144       rv = OKAY;
145    NYD_OU;
146    return rv;
147 }
148 
149 FL void
cwrelse(struct cw * cw)150 cwrelse(struct cw *cw)
151 {
152    NYD_IN;
153    close(cw->cw_fd);
154    NYD_OU;
155 }
156 
157 #else /* !mx_HAVE_FCHDIR */
158 FL enum okay
cwget(struct cw * cw)159 cwget(struct cw *cw)
160 {
161    enum okay rv = STOP;
162    NYD_IN;
163 
164    if (getcwd(cw->cw_wd, sizeof cw->cw_wd) != NULL && !chdir(cw->cw_wd))
165       rv = OKAY;
166    NYD_OU;
167    return rv;
168 }
169 
170 FL enum okay
cwret(struct cw * cw)171 cwret(struct cw *cw)
172 {
173    enum okay rv = STOP;
174    NYD_IN;
175 
176    if (!chdir(cw->cw_wd))
177       rv = OKAY;
178    NYD_OU;
179    return rv;
180 }
181 
182 FL void
cwrelse(struct cw * cw)183 cwrelse(struct cw *cw)
184 {
185    NYD_IN;
186    UNUSED(cw);
187    NYD_OU;
188 }
189 #endif /* !mx_HAVE_FCHDIR */
190 
191 #include "su/code-ou.h"
192 /* s-it-mode */
193