00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "Poco/File_VMS.h"
00038 #include "Poco/Exception.h"
00039 #include "Poco/Path.h"
00040 #include "Poco/String.h"
00041 #include <stdio.h>
00042 #include <unistd.h>
00043 #include <unixio.h>
00044 #include <file.h>
00045 #include <stat.h>
00046 #include <errno.h>
00047 #include <utime.h>
00048 #include <lib$routines.h>
00049 #include <rmsdef.h>
00050 #include <starlet.h>
00051 #include <lnmdef.h>
00052 #include <ssdef.h>
00053 #include <descrip.h>
00054
00055
00056 namespace Poco {
00057
00058
00059 FileImpl::FileImpl()
00060 {
00061 }
00062
00063
00064 FileImpl::FileImpl(const std::string& path): _path(path)
00065 {
00066 if (!_path.empty())
00067 {
00068 Path p(_path);
00069 p.makeFile();
00070 _path = p.toString();
00071 }
00072 }
00073
00074
00075 FileImpl::~FileImpl()
00076 {
00077 }
00078
00079
00080 void FileImpl::swapImpl(FileImpl& file)
00081 {
00082 std::swap(_path, file._path);
00083 }
00084
00085
00086 void FileImpl::setPathImpl(const std::string& path)
00087 {
00088 _path = path;
00089 }
00090
00091
00092 bool FileImpl::existsImpl() const
00093 {
00094 poco_assert (!_path.empty());
00095
00096 return access(_path.c_str(), F_OK) == 0;
00097 }
00098
00099
00100 bool FileImpl::canReadImpl() const
00101 {
00102 poco_assert (!_path.empty());
00103
00104 struct stat st;
00105 if (stat(_path.c_str(), &st) == 0)
00106 {
00107 if (st.st_uid == geteuid())
00108 return (st.st_mode & S_IRUSR) != 0;
00109 else if (st.st_gid == getegid())
00110 return (st.st_mode & S_IRGRP) != 0;
00111 else
00112 return (st.st_mode & S_IROTH) != 0;
00113 }
00114 else handleLastErrorImpl(_path);
00115 return false;
00116 }
00117
00118
00119 bool FileImpl::canWriteImpl() const
00120 {
00121 poco_assert (!_path.empty());
00122
00123 struct stat st;
00124 if (stat(_path.c_str(), &st) == 0)
00125 {
00126 if (st.st_uid == geteuid())
00127 return (st.st_mode & S_IWUSR) != 0;
00128 else if (st.st_gid == getegid())
00129 return (st.st_mode & S_IWGRP) != 0;
00130 else
00131 return (st.st_mode & S_IWOTH) != 0;
00132 }
00133 else handleLastErrorImpl(_path);
00134 return false;
00135 }
00136
00137
00138 bool FileImpl::canExecuteImpl() const
00139 {
00140 Path p(_path);
00141 return icompare(p.getExtension(), "exe") == 0;
00142 }
00143
00144
00145 bool FileImpl::isFileImpl() const
00146 {
00147 poco_assert (!_path.empty());
00148
00149 struct stat st;
00150 if (stat(_path.c_str(), &st) == 0)
00151 return S_ISREG(st.st_mode);
00152 else
00153 handleLastErrorImpl(_path);
00154 return false;
00155 }
00156
00157
00158 bool FileImpl::isDirectoryImpl() const
00159 {
00160 poco_assert (!_path.empty());
00161
00162 struct stat st;
00163 if (stat(_path.c_str(), &st) == 0)
00164 return S_ISDIR(st.st_mode);
00165 else
00166 handleLastErrorImpl(_path);
00167 return false;
00168 }
00169
00170
00171 bool FileImpl::isLinkImpl() const
00172 {
00173 return false;
00174 }
00175
00176
00177 bool FileImpl::isLinkImpl() const
00178 {
00179 return false;
00180 }
00181
00182
00183 bool FileImpl::isHiddenImpl() const
00184 {
00185 return false;
00186 }
00187
00188
00189 Timestamp FileImpl::createdImpl() const
00190 {
00191 poco_assert (!_path.empty());
00192
00193 struct stat st;
00194 if (stat(_path.c_str(), &st) == 0)
00195 return Timestamp(st.st_ctime);
00196 else
00197 handleLastErrorImpl(_path);
00198 return 0;
00199 }
00200
00201
00202 Timestamp FileImpl::getLastModifiedImpl() const
00203 {
00204 poco_assert (!_path.empty());
00205
00206 struct stat st;
00207 if (stat(_path.c_str(), &st) == 0)
00208 return Timestamp(st.st_mtime);
00209 else
00210 handleLastErrorImpl(_path);
00211 return 0;
00212 }
00213
00214
00215 void FileImpl::setLastModifiedImpl(const Timestamp& ts)
00216 {
00217 poco_assert (!_path.empty());
00218
00219 struct utimbuf tb;
00220 tb.actime = ts.epochTime();
00221 tb.modtime = ts.epochTime();
00222 if (utime(_path.c_str(), &tb) != 0)
00223 handleLastErrorImpl(_path);
00224 }
00225
00226
00227 FileImpl::FileSizeImpl FileImpl::getSizeImpl() const
00228 {
00229 poco_assert (!_path.empty());
00230
00231 struct stat st;
00232 if (stat(_path.c_str(), &st) == 0)
00233 return st.st_size;
00234 else
00235 handleLastErrorImpl(_path);
00236 return 0;
00237 }
00238
00239
00240 void FileImpl::setSizeImpl(FileSizeImpl size)
00241 {
00242 poco_assert (!_path.empty());
00243
00244 if (truncate(_path.c_str(), size) != 0)
00245 handleLastErrorImpl(_path);
00246 }
00247
00248
00249 void FileImpl::setWriteableImpl(bool flag)
00250 {
00251 poco_assert (!_path.empty());
00252
00253 struct stat st;
00254 if (stat(_path.c_str(), &st) != 0)
00255 handleLastErrorImpl(_path);
00256 mode_t mode;
00257 if (flag)
00258 {
00259 mode = st.st_mode | S_IWUSR;
00260 }
00261 else
00262 {
00263 mode_t wmask = S_IWUSR | S_IWGRP | S_IWOTH;
00264 mode = st.st_mode & ~wmask;
00265 }
00266 if (chmod(_path.c_str(), mode) != 0)
00267 handleLastErrorImpl(_path);
00268 }
00269
00270
00271 void FileImpl::setExecutableImpl(bool flag)
00272 {
00273
00274 }
00275
00276
00277 void FileImpl::copyToImpl(const std::string& path) const
00278 {
00279 poco_assert (!_path.empty());
00280
00281
00282
00283 std::string cmd = "COPY ";
00284 cmd.append(_path);
00285 cmd.append(" ");
00286 cmd.append(path);
00287 if (system(cmd.c_str()) != 0)
00288 throw FileException("COPY command failed", _path);
00289 }
00290
00291
00292 void FileImpl::renameToImpl(const std::string& path)
00293 {
00294 poco_assert (!_path.empty());
00295
00296 POCO_DESCRIPTOR_STRING(oldNameDsc, _path);
00297 POCO_DESCRIPTOR_STRING(newNameDsc, path);
00298
00299 int res;
00300 if ((res = lib$rename_file(&oldNameDsc, &newNameDsc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) != 1)
00301 {
00302 switch (res & 0x0FFFFFFF)
00303 {
00304 case RMS$_FNF:
00305 throw FileNotFoundException(_path);
00306 case RMS$_DEV:
00307 case RMS$_DNF:
00308 throw PathNotFoundException(_path);
00309 case RMS$_SYN:
00310 throw PathSyntaxException(path);
00311 case RMS$_RMV:
00312 throw FileAccessDeniedException(_path);
00313 case RMS$_PRV:
00314 throw FileAccessDeniedException("insufficient privileges", _path);
00315 default:
00316 throw FileException(path);
00317 }
00318 }
00319 }
00320
00321
00322 void FileImpl::removeImpl()
00323 {
00324 poco_assert (!_path.empty());
00325
00326 int rc;
00327 if (isDirectoryImpl())
00328 {
00329 setWriteableImpl(true);
00330 rc = rmdir(_path.c_str());
00331 }
00332 else
00333 {
00334 rc = unlink(_path.c_str());
00335 }
00336 if (rc) handleLastErrorImpl(_path);
00337 }
00338
00339
00340
00341 bool FileImpl::createFileImpl()
00342 {
00343 poco_assert (!_path.empty());
00344
00345 int n = open(_path.c_str(), O_WRONLY | O_CREAT | O_EXCL);
00346 if (n != -1)
00347 {
00348 close(n);
00349 return true;
00350 }
00351 if (n == -1 && errno == EEXIST)
00352 return false;
00353 else
00354 handleLastErrorImpl(_path);
00355 return false;
00356 }
00357
00358
00359 bool FileImpl::createDirectoryImpl()
00360 {
00361 poco_assert (!_path.empty());
00362
00363 if (existsImpl() && isDirectoryImpl())
00364 return false;
00365 Path p(_path);
00366 p.makeDirectory();
00367 if (mkdir(p.toString().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0)
00368 handleLastErrorImpl(_path);
00369 return true;
00370 }
00371
00372
00373 void FileImpl::handleLastErrorImpl(const std::string& path)
00374 {
00375 switch (errno)
00376 {
00377 case EIO:
00378 throw IOException(path);
00379 case EPERM:
00380 throw FileAccessDeniedException("insufficient permissions", path);
00381 case EACCES:
00382 throw FileAccessDeniedException(path);
00383 case ENOENT:
00384 throw FileNotFoundException(path);
00385 case ENOTDIR:
00386 throw OpenFileException("not a directory", path);
00387 case EISDIR:
00388 throw OpenFileException("not a file", path);
00389 case EROFS:
00390 throw FileReadOnlyException(path);
00391 case EEXIST:
00392 throw FileExistsException(path);
00393 case ENOSPC:
00394 throw FileException("no space left on device", path);
00395 case EDQUOT:
00396 throw FileException("disk quota exceeded", path);
00397 case ENOTEMPTY:
00398 throw FileException("directory not empty", path);
00399 case ENAMETOOLONG:
00400 throw PathSyntaxException(path);
00401 default:
00402 throw FileException(strerror(errno), path);
00403 }
00404 }
00405
00406
00407 }