00001
00002
00003
00004
00005
00006
00007
00008 #include "fileutils.h"
00009 #include "wvfile.h"
00010 #include "wvdiriter.h"
00011 #include <string.h>
00012 #include <sys/stat.h>
00013 #ifndef _WIN32
00014 #include <fnmatch.h>
00015 #endif
00016 #ifndef _MSC_VER
00017 #include <unistd.h>
00018 #include <utime.h>
00019 #endif
00020
00021 int wvmkdir(WvStringParm _dir, int create_mode)
00022 {
00023 #ifdef _WIN32
00024 return mkdir(_dir);
00025 #else
00026 return mkdir(_dir, create_mode);
00027 #endif
00028 }
00029
00030 int mkdirp(WvStringParm _dir, int create_mode)
00031 {
00032 if (!access(_dir, X_OK))
00033 return 0;
00034
00035
00036 assert(!!_dir);
00037
00038 WvString dir(_dir);
00039 char *p = dir.edit();
00040
00041 while ((p = strchr(++p, '/')))
00042 {
00043 *p = '\0';
00044 if (access(dir, X_OK) && wvmkdir(dir, create_mode))
00045 return -1;
00046 *p = '/';
00047 }
00048
00049
00050
00051 return (access(dir, X_OK&W_OK) && wvmkdir(dir, create_mode)) ? -1 : 0;
00052 }
00053
00054
00055 void rm_rf(WvStringParm dir)
00056 {
00057 WvDirIter i(dir, false, false);
00058 for (i.rewind(); i.next(); )
00059 {
00060 if (i.isdir())
00061 rm_rf(i->fullname);
00062 else
00063 ::unlink(i->fullname);
00064 }
00065 ::rmdir(dir);
00066 ::unlink(dir);
00067 }
00068
00069
00070 bool fcopy(WvStringParm src, WvStringParm dst)
00071 {
00072 struct stat buf;
00073 if (stat(src, &buf))
00074 return false;
00075
00076 WvFile in(src, O_RDONLY);
00077 unlink(dst);
00078
00079 int oldmode = umask(0);
00080 WvFile out(dst, O_CREAT|O_WRONLY, buf.st_mode & 007777);
00081 umask(oldmode);
00082
00083 in.autoforward(out);
00084 while (in.isok() && out.isok())
00085 {
00086
00087
00088
00089
00090 if (in.select(-1, true, false))
00091 in.callback();
00092 }
00093 if (!out.isok())
00094 return false;
00095
00096 struct utimbuf utim;
00097 utim.actime = utim.modtime = buf.st_mtime;
00098 if (utime(dst, &utim))
00099 return false;
00100
00101 return true;
00102 }
00103
00104
00105 bool fcopy(WvStringParm srcdir, WvStringParm dstdir, WvStringParm relname)
00106 {
00107 return fcopy(WvString("%s/%s", srcdir, relname),
00108 WvString("%s/%s", dstdir, relname));
00109 }
00110
00111
00112 bool ftouch(WvStringParm file, time_t mtime)
00113 {
00114 if (!WvFile(file, O_WRONLY|O_CREAT).isok())
00115 return false;
00116
00117 struct utimbuf *buf = NULL;
00118 if (mtime != 0)
00119 {
00120 buf = (struct utimbuf *)malloc(sizeof(struct utimbuf));
00121 buf->actime = time(NULL);
00122 buf->modtime = mtime;
00123 }
00124
00125 if (utime(file, buf) == 0)
00126 {
00127 free(buf);
00128 return true;
00129 }
00130
00131 free(buf);
00132 return false;
00133 }
00134
00135
00136 bool samedate(WvStringParm file1, WvStringParm file2)
00137 {
00138 struct stat buf;
00139 struct stat buf2;
00140
00141 if (stat(file1, &buf) || stat(file2, &buf2))
00142 return false;
00143
00144 if (buf.st_mtime == buf2.st_mtime || buf.st_ctime == buf2.st_ctime)
00145 return true;
00146
00147 return false;
00148 }
00149
00150
00151 bool samedate(WvStringParm dir1, WvStringParm dir2, WvStringParm relname)
00152 {
00153 return samedate(WvString("%s/%s", dir1, relname),
00154 WvString("%s/%s", dir2, relname));
00155 }
00156
00157
00158 #ifndef _WIN32
00159
00160
00161 bool wvfnmatch(WvStringList& patterns, WvStringParm name, int flags)
00162 {
00163 WvStringList::Iter i(patterns);
00164 bool match = false;
00165
00166 for (i.rewind(); i.next(); )
00167 {
00168
00169 if (*i == "!") {
00170 match = false;
00171 continue;
00172 }
00173
00174
00175
00176 if (i->cstr()[0] == '!')
00177 {
00178 if (!match)
00179 continue;
00180 if (fnmatch(*i+1, name, flags) == 0)
00181 match = false;
00182 }
00183 else
00184 {
00185
00186 if (fnmatch(*i, name, flags) == 0)
00187 match = true;
00188 }
00189 }
00190
00191 return match;
00192 }
00193 #endif
00194
00195 #ifndef _WIN32 // file permissions are too screwy in win32
00196 int wvchmod(const char *path, mode_t mode)
00197 {
00198 struct stat st;
00199 if (lstat(path, &st) == -1) {
00200 return -1;
00201 }
00202
00203 int filedes = open(path, O_RDONLY);
00204 if (filedes == -1) {
00205
00206
00207
00208
00209
00210
00211
00212 struct stat sst;
00213 if (getuid() != 0)
00214 if (stat(path, &sst) != -1)
00215 if (st.st_ino == sst.st_ino)
00216 return chmod(path, mode);
00217
00218 return -1;
00219 }
00220
00221 struct stat fst;
00222 if (fstat(filedes, &fst) == -1) {
00223 close(filedes);
00224 return -1;
00225 }
00226
00227 if (st.st_ino != fst.st_ino) {
00228 close(filedes);
00229 return -1;
00230 }
00231
00232 #ifndef _WIN32
00233
00234
00235
00236 int retval = fchmod(filedes, mode);
00237 #else
00238
00239
00240
00241 int retval = chmod(path, mode);
00242 #endif
00243 close(filedes);
00244
00245 return retval;
00246 }
00247 #endif // !_WIN32
00248
00249
00250 FILE *wvtmpfile()
00251 {
00252 #ifndef _WIN32 // tmpfile() is really the best choice, when it works
00253 return tmpfile();
00254 #else
00255
00256
00257 char *name = _tempnam("c:\\temp", "wvtmp");
00258 FILE *f = fopen(name, "wb+");
00259 free(name);
00260 return f;
00261 #endif
00262 }
00263
00264
00265 WvString wvtmpfilename(WvStringParm prefix)
00266 {
00267 #ifndef _WIN32 // tmpfile() is really the best choice, when it works
00268 WvString tmpname("/tmp/%sXXXXXX", prefix);
00269 int fd;
00270 if ((fd = mkstemp(tmpname.edit())) == (-1))
00271 return WvString();
00272 close(fd);
00273 #else
00274 WvString tmpname(_tempnam("c:\\temp", prefix.cstr()));
00275 int fd;
00276 fd = open(tmpname, O_WRONLY|O_CREAT|O_EXCL, 0777);
00277 if (fd < 0)
00278 return WvString::null;
00279 _close(fd);
00280 #endif
00281
00282 return tmpname;
00283 }
00284
00285
00286 mode_t get_umask()
00287 {
00288 mode_t rv = umask(0);
00289 umask(rv);
00290
00291 return rv;
00292 }
00293
00294
00295 void wvdelay(int msec_delay)
00296 {
00297 #ifdef _WIN32
00298 Sleep(msec_delay);
00299 #else
00300 usleep(msec_delay * 1000);
00301 #endif
00302 }