cc-test.sh: t_behave_iconv_mainbody() should compile test instead, sigh!
[s-mailx.git] / path.c
blobb5c757f763ff1e16e122b2c108c3852c86fac7cd
1 /*@ S-nail - a mail user agent derived from Berkeley Mail.
2 *@ Path and directory related operations.
4 * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
5 * Copyright (c) 2012 - 2018 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
6 */
7 /*
8 * Copyright (c) 1980, 1993
9 * The Regents of the University of California. All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
35 #undef n_FILE
36 #define n_FILE path
38 #ifndef HAVE_AMALGAMATION
39 # include "nail.h"
40 #endif
42 FL bool_t
43 n_is_dir(char const *name, bool_t check_access){
44 struct stat sbuf;
45 bool_t rv;
46 NYD2_ENTER;
48 if((rv = (stat(name, &sbuf) == 0))){
49 if((rv = (S_ISDIR(sbuf.st_mode) != 0)) && check_access){
50 int mode;
52 mode = R_OK | X_OK;
53 if(check_access != TRUM1)
54 mode |= W_OK;
55 rv = (access(name, mode) == 0);
58 NYD2_LEAVE;
59 return rv;
62 FL bool_t
63 n_path_mkdir(char const *name){
64 struct stat st;
65 bool_t rv;
66 NYD_ENTER;
68 jredo:
69 if(!mkdir(name, 0777))
70 rv = TRU1;
71 else{
72 int e = n_err_no;
74 /* Try it recursively */
75 if(e == n_ERR_NOENT){
76 char const *vp;
78 if((vp = strrchr(name, '/')) != NULL){ /* TODO magic dirsep */
79 while(vp > name && vp[-1] == '/')
80 --vp;
81 vp = savestrbuf(name, PTR2SIZE(vp - name));
83 if(n_path_mkdir(vp))
84 goto jredo;
88 rv = ((e == n_ERR_EXIST || e == n_ERR_NOSYS) && !stat(name, &st) &&
89 S_ISDIR(st.st_mode));
91 NYD_LEAVE;
92 return rv;
95 FL bool_t
96 n_path_rm(char const *name){
97 struct stat sb;
98 bool_t rv;
99 NYD2_ENTER;
101 if(stat(name, &sb) != 0)
102 rv = FAL0;
103 else if(!S_ISREG(sb.st_mode))
104 rv = TRUM1;
105 else
106 rv = (unlink(name) == 0);
107 NYD2_LEAVE;
108 return rv;
111 #ifdef HAVE_FCHDIR
112 FL enum okay
113 cwget(struct cw *cw)
115 enum okay rv = STOP;
116 NYD_ENTER;
118 if ((cw->cw_fd = open(".", O_RDONLY)) == -1)
119 goto jleave;
120 if (fchdir(cw->cw_fd) == -1) {
121 close(cw->cw_fd);
122 goto jleave;
124 rv = OKAY;
125 jleave:
126 NYD_LEAVE;
127 return rv;
130 FL enum okay
131 cwret(struct cw *cw)
133 enum okay rv = STOP;
134 NYD_ENTER;
136 if (!fchdir(cw->cw_fd))
137 rv = OKAY;
138 NYD_LEAVE;
139 return rv;
142 FL void
143 cwrelse(struct cw *cw)
145 NYD_ENTER;
146 close(cw->cw_fd);
147 NYD_LEAVE;
150 #else /* !HAVE_FCHDIR */
151 FL enum okay
152 cwget(struct cw *cw)
154 enum okay rv = STOP;
155 NYD_ENTER;
157 if (getcwd(cw->cw_wd, sizeof cw->cw_wd) != NULL && !chdir(cw->cw_wd))
158 rv = OKAY;
159 NYD_LEAVE;
160 return rv;
163 FL enum okay
164 cwret(struct cw *cw)
166 enum okay rv = STOP;
167 NYD_ENTER;
169 if (!chdir(cw->cw_wd))
170 rv = OKAY;
171 NYD_LEAVE;
172 return rv;
175 FL void
176 cwrelse(struct cw *cw)
178 NYD_ENTER;
179 n_UNUSED(cw);
180 NYD_LEAVE;
182 #endif /* !HAVE_FCHDIR */
184 /* s-it-mode */