2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
5 * Various useful file utilities.
10 #include "wvdiriter.h"
21 int wvmkdir(WvStringParm _dir
, int create_mode
)
26 return mkdir(_dir
, create_mode
);
30 int mkdirp(WvStringParm _dir
, int create_mode
)
32 if (!access(_dir
, X_OK
))
35 // You're trying to make a nothing directory eh?
41 while ((p
= strchr(++p
, '/')))
44 if (access(dir
, X_OK
) && wvmkdir(dir
, create_mode
))
49 // You're probably creating the directory to write to it? Maybe this should
50 // look for R_OK&X_OK instead of X_OK&W_OK...
51 return (access(dir
, X_OK
&W_OK
) && wvmkdir(dir
, create_mode
)) ? -1 : 0;
55 void rm_rf(WvStringParm dir
)
57 WvDirIter
i(dir
, false, false); // non-recursive, don't skip_mounts
58 for (i
.rewind(); i
.next(); )
63 ::unlink(i
->fullname
);
70 bool fcopy(WvStringParm src
, WvStringParm dst
)
76 WvFile
in(src
, O_RDONLY
);
79 int oldmode
= umask(0);
80 WvFile
out(dst
, O_CREAT
|O_WRONLY
, buf
.st_mode
& 007777);
84 while (in
.isok() && out
.isok())
86 /* This used to be a select(0), but really, if select() returns
87 * false, it'll keep doing it until the end of time. If you're
88 * going into an infinite loop, better save the CPU a bit, since
89 * you can still find out about it with strace... */
90 if (in
.select(-1, true, false))
97 utim
.actime
= utim
.modtime
= buf
.st_mtime
;
98 if (utime(dst
, &utim
))
105 bool fcopy(WvStringParm srcdir
, WvStringParm dstdir
, WvStringParm relname
)
107 return fcopy(WvString("%s/%s", srcdir
, relname
),
108 WvString("%s/%s", dstdir
, relname
));
112 bool ftouch(WvStringParm file
, time_t mtime
)
114 if (!WvFile(file
, O_WRONLY
|O_CREAT
).isok())
117 struct utimbuf
*buf
= NULL
;
120 buf
= (struct utimbuf
*)malloc(sizeof(struct utimbuf
));
121 buf
->actime
= time(NULL
);
122 buf
->modtime
= mtime
;
125 if (utime(file
, buf
) == 0)
136 bool samedate(WvStringParm file1
, WvStringParm file2
)
141 if (stat(file1
, &buf
) || stat(file2
, &buf2
))
144 if (buf
.st_mtime
== buf2
.st_mtime
|| buf
.st_ctime
== buf2
.st_ctime
)
151 bool samedate(WvStringParm dir1
, WvStringParm dir2
, WvStringParm relname
)
153 return samedate(WvString("%s/%s", dir1
, relname
),
154 WvString("%s/%s", dir2
, relname
));
159 // runs fnmatch against everything in patterns. We also interpret
160 // CVS-style '!' patterns, which makes us very fancy.
161 bool wvfnmatch(WvStringList
& patterns
, WvStringParm name
, int flags
)
163 WvStringList::Iter
i(patterns
);
166 for (i
.rewind(); i
.next(); )
168 // if we hit JUST a '!', reset any matches found so far.
174 // if we hit something that starts with '!', we unmatch anything
176 if (i
->cstr()[0] == '!')
179 continue; // nothing to unmatch, so why try?
180 if (fnmatch(*i
+1, name
, flags
) == 0) // matches
181 match
= false; // unmatch it.
185 // just a straightforward matching case.
186 if (fnmatch(*i
, name
, flags
) == 0) // matches
195 #ifndef _WIN32 // file permissions are too screwy in win32
196 int wvchmod(const char *path
, mode_t mode
)
199 if (lstat(path
, &st
) == -1) {
203 int filedes
= open(path
, O_RDONLY
);
205 // if we're not running as root, this file/dir may have 0
206 // perms and open() fails, so let's try again
208 // NOTE: This is not as secure as the proper way, since
209 // it's conceivable that someone swaps out the dir/file
210 // for a symlink between our check and the chmod() call
214 if (stat(path
, &sst
) != -1)
215 if (st
.st_ino
== sst
.st_ino
)
216 return chmod(path
, mode
);
222 if (fstat(filedes
, &fst
) == -1) {
227 if (st
.st_ino
!= fst
.st_ino
) {
233 // we're definitely chmod'ing the open file here, which is good,
234 // because the filename itself might have been moved around between
235 // our stat'ing and chmod'ing it.
236 int retval
= fchmod(filedes
, mode
);
238 // this is guaranteed to be the same file as filedes, because in
239 // Windows, open files can't be changed on the filesystem (unlike in
241 int retval
= chmod(path
, mode
);
252 #ifndef _WIN32 // tmpfile() is really the best choice, when it works
255 // in win32, tmpfile() creates files in c:\...
256 // and that directory isn't always writable! Idiots.
257 char *name
= _tempnam("c:\\temp", "wvtmp");
258 FILE *f
= fopen(name
, "wb+");
265 WvString
wvtmpfilename(WvStringParm prefix
)
267 #ifndef _WIN32 // tmpfile() is really the best choice, when it works
268 WvString
tmpname("/tmp/%sXXXXXX", prefix
);
270 if ((fd
= mkstemp(tmpname
.edit())) == (-1))
274 WvString
tmpname(_tempnam("c:\\temp", prefix
.cstr()));
276 fd
= open(tmpname
, O_WRONLY
|O_CREAT
|O_EXCL
, 0777);
278 return WvString::null
; // weird
288 mode_t rv
= umask(0);
295 void wvdelay(int msec_delay
)
300 usleep(msec_delay
* 1000);