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 samedate(WvStringParm file1, WvStringParm file2)
00110 {
00111 struct stat buf;
00112 struct stat buf2;
00113
00114 if (stat(file1, &buf) || stat(file2, &buf2))
00115 return false;
00116
00117 if (buf.st_mtime == buf2.st_mtime || buf.st_ctime == buf2.st_ctime)
00118 return true;
00119
00120 return false;
00121 }
00122
00123
00124 bool samedate(WvStringParm dir1, WvStringParm dir2, WvStringParm relname)
00125 {
00126 return samedate(WvString("%s/%s", dir1, relname),
00127 WvString("%s/%s", dir2, relname));
00128 }
00129
00130
00131 #ifndef _WIN32
00132
00133
00134 bool wvfnmatch(WvStringList& patterns, WvStringParm name, int flags)
00135 {
00136 WvStringList::Iter i(patterns);
00137 bool match = false;
00138
00139 for (i.rewind(); i.next(); )
00140 {
00141
00142 if (*i == "!") {
00143 match = false;
00144 continue;
00145 }
00146
00147
00148
00149 if (i->cstr()[0] == '!')
00150 {
00151 if (!match)
00152 continue;
00153 if (fnmatch(*i+1, name, flags) == 0)
00154 match = false;
00155 }
00156 else
00157 {
00158
00159 if (fnmatch(*i, name, flags) == 0)
00160 match = true;
00161 }
00162 }
00163
00164 return match;
00165 }
00166
00167
00168 int wvchmod(const char *path, mode_t mode)
00169 {
00170 struct stat st;
00171 if (lstat(path, &st) == -1) {
00172 return -1;
00173 }
00174
00175 int filedes = open(path, O_RDONLY);
00176 if (filedes == -1) {
00177
00178
00179
00180
00181
00182
00183
00184 struct stat sst;
00185 if (getuid() != 0)
00186 if (stat(path, &sst) != -1)
00187 if (st.st_ino == sst.st_ino)
00188 return chmod(path, mode);
00189
00190 return -1;
00191 }
00192
00193 struct stat fst;
00194 if (fstat(filedes, &fst) == -1) {
00195 close(filedes);
00196 return -1;
00197 }
00198
00199 if (st.st_ino != fst.st_ino) {
00200 close(filedes);
00201 return -1;
00202 }
00203
00204 int retval = fchmod(filedes, mode);
00205 close(filedes);
00206
00207 return retval;
00208 }
00209 #endif
00210
00211
00212 FILE *wvtmpfile()
00213 {
00214 #ifndef _WIN32 // tmpfile() is really the best choice, when it works
00215 return tmpfile();
00216 #else
00217
00218
00219 char *name = _tempnam("c:\\temp", "wvtmp");
00220 FILE *f = fopen(name, "wb+");
00221 free(name);
00222 return f;
00223 #endif
00224 }
00225
00226
00227 WvString wvtmpfilename(WvStringParm prefix)
00228 {
00229 #ifndef _WIN32 // tmpfile() is really the best choice, when it works
00230 WvString tmpname("/tmp/%sXXXXXX", prefix);
00231 int fd;
00232 if ((fd = mkstemp(tmpname.edit())) == (-1))
00233 return WvString();
00234 close(fd);
00235 #else
00236 WvString tmpname(_tempnam("c:\\temp", prefix.cstr()));
00237 #endif
00238
00239 return tmpname;
00240 }
00241
00242
00243 mode_t get_umask()
00244 {
00245 mode_t rv = umask(0);
00246 umask(rv);
00247
00248 return rv;
00249 }
00250