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