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 #ifdef solarisGcc
00030 # define _SYS_VNODE_H
00031 #endif
00032
00033 #include <OpenFOAM/OSspecific.H>
00034 #include "POSIX.H"
00035 #include <OpenFOAM/foamVersion.H>
00036 #include <OpenFOAM/fileName.H>
00037 #include "fileStat.H"
00038 #include "timer.H"
00039
00040 #include <fstream>
00041 #include <cstdlib>
00042 #include <cctype>
00043
00044 #include <stdio.h>
00045 #include <unistd.h>
00046 #include <dirent.h>
00047 #include <pwd.h>
00048 #include <errno.h>
00049 #include <sys/types.h>
00050 #include <sys/stat.h>
00051 #include <sys/socket.h>
00052 #include <netdb.h>
00053
00054 #include <netinet/in.h>
00055
00056
00057
00058 defineTypeNameAndDebug(Foam::POSIX, 0);
00059
00060
00061
00062 pid_t Foam::pid()
00063 {
00064 return getpid();
00065 }
00066
00067 pid_t Foam::ppid()
00068 {
00069 return getppid();
00070 }
00071
00072 pid_t Foam::pgid()
00073 {
00074 return getpgrp();
00075 }
00076
00077 bool Foam::env(const word& envName)
00078 {
00079 return getenv(envName.c_str()) != NULL;
00080 }
00081
00082
00083 Foam::string Foam::getEnv(const word& envName)
00084 {
00085 char* env = getenv(envName.c_str());
00086
00087 if (env)
00088 {
00089 return string(env);
00090 }
00091 else
00092 {
00093
00094
00095 return string();
00096 }
00097 }
00098
00099
00100 bool Foam::setEnv
00101 (
00102 const word& envName,
00103 const string& value,
00104 const bool overwrite
00105 )
00106 {
00107 return setenv(envName.c_str(), value.c_str(), overwrite) == 0;
00108 }
00109
00110
00111 Foam::word Foam::hostName()
00112 {
00113 char buffer[256];
00114 gethostname(buffer, 256);
00115
00116 return buffer;
00117 }
00118
00119
00120 Foam::word Foam::userName()
00121 {
00122 struct passwd* pw = getpwuid(getuid());
00123
00124 if (pw != NULL)
00125 {
00126 return pw->pw_name;
00127 }
00128 else
00129 {
00130 return word::null;
00131 }
00132 }
00133
00134
00135
00136 Foam::fileName Foam::home()
00137 {
00138 char* env = getenv("HOME");
00139
00140 if (env != NULL)
00141 {
00142 return fileName(env);
00143 }
00144 else
00145 {
00146 struct passwd* pw = getpwuid(getuid());
00147
00148 if (pw != NULL)
00149 {
00150 return pw->pw_dir;
00151 }
00152 else
00153 {
00154 return fileName::null;
00155 }
00156 }
00157 }
00158
00159
00160 Foam::fileName Foam::home(const word& userName)
00161 {
00162 struct passwd* pw;
00163
00164 if (userName.size())
00165 {
00166 pw = getpwnam(userName.c_str());
00167 }
00168 else
00169 {
00170 char* env = getenv("HOME");
00171
00172 if (env != NULL)
00173 {
00174 return fileName(env);
00175 }
00176
00177 pw = getpwuid(getuid());
00178 }
00179
00180 if (pw != NULL)
00181 {
00182 return pw->pw_dir;
00183 }
00184 else
00185 {
00186 return fileName::null;
00187 }
00188 }
00189
00190
00191 Foam::fileName Foam::cwd()
00192 {
00193 char buf[255];
00194 if (getcwd(buf, 255))
00195 {
00196 return buf;
00197 }
00198 else
00199 {
00200 FatalErrorIn("Foam::cwd()")
00201 << "Couldn't get the current working directory"
00202 << exit(FatalError);
00203
00204 return fileName::null;
00205 }
00206 }
00207
00208
00209 bool Foam::chDir(const fileName& dir)
00210 {
00211 return chdir(dir.c_str()) != 0;
00212 }
00213
00214
00215 Foam::fileName Foam::findEtcFile(const fileName& name, bool mandatory)
00216 {
00217
00218
00219
00220
00221
00222
00223
00224
00225 fileName searchDir;
00226 if(env("FREEFOAM_CONFIG_DIR"))
00227 {
00228 searchDir = getEnv("FREEFOAM_CONFIG_DIR");
00229 }
00230 if (isDir(searchDir))
00231 {
00232
00233 fileName fullName = searchDir/name;
00234 if (isFile(fullName))
00235 {
00236 return fullName;
00237 }
00238 }
00239
00240
00241
00242 searchDir = home()/".FreeFOAM";
00243 if (isDir(searchDir))
00244 {
00245
00246 fileName fullName = searchDir/FOAMversion/name;
00247 if (isFile(fullName))
00248 {
00249 return fullName;
00250 }
00251
00252
00253 fullName = searchDir/name;
00254 if (isFile(fullName))
00255 {
00256 return fullName;
00257 }
00258 }
00259
00260
00261
00262 searchDir = FOAMConfigDir;
00263 if (isDir(searchDir))
00264 {
00265
00266 fileName fullName = searchDir/name;
00267 if (isFile(fullName))
00268 {
00269 return fullName;
00270 }
00271 }
00272
00273
00274
00275 if (mandatory)
00276 {
00277 cerr<< "--> FOAM FATAL ERROR in Foam::findEtcFile() :"
00278 " could not find mandatory file\n '"
00279 << name.c_str() << "'\n\n" << std::endl;
00280 ::exit(1);
00281 }
00282
00283
00284
00285 return fileName();
00286 }
00287
00288
00289 bool Foam::mkDir(const fileName& pathName, mode_t mode)
00290 {
00291
00292 if (pathName.empty())
00293 {
00294 return false;
00295 }
00296
00297
00298 if (::mkdir(pathName.c_str(), mode) == 0)
00299 {
00300
00301 return true;
00302 }
00303 else
00304 {
00305 switch (errno)
00306 {
00307 case EPERM:
00308 {
00309 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00310 << "The filesystem containing " << pathName
00311 << " does not support the creation of directories."
00312 << exit(FatalError);
00313
00314 return false;
00315 }
00316
00317 case EEXIST:
00318 {
00319
00320 return true;
00321 }
00322
00323 case EFAULT:
00324 {
00325 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00326 << "" << pathName
00327 << " points outside your accessible address space."
00328 << exit(FatalError);
00329
00330 return false;
00331 }
00332
00333 case EACCES:
00334 {
00335 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00336 << "The parent directory does not allow write "
00337 "permission to the process,"<< nl
00338 << "or one of the directories in " << pathName
00339 << " did not allow search (execute) permission."
00340 << exit(FatalError);
00341
00342 return false;
00343 }
00344
00345 case ENAMETOOLONG:
00346 {
00347 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00348 << "" << pathName << " is too long."
00349 << exit(FatalError);
00350
00351 return false;
00352 }
00353
00354 case ENOENT:
00355 {
00356
00357 if (pathName.path().size() && mkDir(pathName.path(), mode))
00358 {
00359 return mkDir(pathName, mode);
00360 }
00361 else
00362 {
00363 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00364 << "Couldn't create directory " << pathName
00365 << exit(FatalError);
00366
00367 return false;
00368 }
00369 }
00370
00371 case ENOTDIR:
00372 {
00373 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00374 << "A component used as a directory in " << pathName
00375 << " is not, in fact, a directory."
00376 << exit(FatalError);
00377
00378 return false;
00379 }
00380
00381 case ENOMEM:
00382 {
00383 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00384 << "Insufficient kernel memory was available to make "
00385 "directory " << pathName << '.'
00386 << exit(FatalError);
00387
00388 return false;
00389 }
00390
00391 case EROFS:
00392 {
00393 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00394 << "" << pathName
00395 << " refers to a file on a read-only filesystem."
00396 << exit(FatalError);
00397
00398 return false;
00399 }
00400
00401 case ELOOP:
00402 {
00403 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00404 << "Too many symbolic links were encountered in resolving "
00405 << pathName << '.'
00406 << exit(FatalError);
00407
00408 return false;
00409 }
00410
00411 case ENOSPC:
00412 {
00413 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00414 << "The device containing " << pathName
00415 << " has no room for the new directory or "
00416 << "the user's disk quota is exhausted."
00417 << exit(FatalError);
00418
00419 return false;
00420 }
00421
00422 default:
00423 {
00424 FatalErrorIn("Foam::mkDir(const fileName&, mode_t)")
00425 << "Couldn't create directory " << pathName
00426 << exit(FatalError);
00427
00428 return false;
00429 }
00430 }
00431 }
00432 }
00433
00434
00435
00436 bool Foam::chMod(const fileName& name, const mode_t m)
00437 {
00438 return ::chmod(name.c_str(), m) == 0;
00439 }
00440
00441
00442
00443 mode_t Foam::mode(const fileName& name)
00444 {
00445 fileStat fileStatus(name);
00446 if (fileStatus.isValid())
00447 {
00448 return fileStatus.status().st_mode;
00449 }
00450 else
00451 {
00452 return 0;
00453 }
00454 }
00455
00456
00457
00458 Foam::fileName::Type Foam::type(const fileName& name)
00459 {
00460 mode_t m = mode(name);
00461
00462 if (S_ISREG(m))
00463 {
00464 return fileName::FILE;
00465 }
00466 else if (S_ISDIR(m))
00467 {
00468 return fileName::DIRECTORY;
00469 }
00470 else
00471 {
00472 return fileName::UNDEFINED;
00473 }
00474 }
00475
00476
00477
00478 bool Foam::exists(const fileName& name, const bool checkGzip)
00479 {
00480 return mode(name) || isFile(name, checkGzip);
00481 }
00482
00483
00484
00485 bool Foam::isDir(const fileName& name)
00486 {
00487 return S_ISDIR(mode(name));
00488 }
00489
00490
00491
00492 bool Foam::isFile(const fileName& name, const bool checkGzip)
00493 {
00494 return S_ISREG(mode(name)) || (checkGzip && S_ISREG(mode(name + ".gz")));
00495 }
00496
00497
00498
00499 off_t Foam::fileSize(const fileName& name)
00500 {
00501 fileStat fileStatus(name);
00502 if (fileStatus.isValid())
00503 {
00504 return fileStatus.status().st_size;
00505 }
00506 else
00507 {
00508 return -1;
00509 }
00510 }
00511
00512
00513
00514 time_t Foam::lastModified(const fileName& name)
00515 {
00516 fileStat fileStatus(name);
00517 if (fileStatus.isValid())
00518 {
00519 return fileStatus.status().st_mtime;
00520 }
00521 else
00522 {
00523 return 0;
00524 }
00525 }
00526
00527
00528
00529 Foam::fileNameList Foam::readDir
00530 (
00531 const fileName& directory,
00532 const fileName::Type type,
00533 const bool filtergz
00534 )
00535 {
00536
00537
00538 static const int maxNnames = 100;
00539
00540 if (POSIX::debug)
00541 {
00542 Info<< "readDir(const fileName&, const fileType, const bool filtergz)"
00543 << " : reading directory " << directory << endl;
00544 }
00545
00546
00547 fileNameList dirEntries(maxNnames);
00548
00549
00550 DIR *source;
00551 struct dirent *list;
00552
00553
00554 label nEntries = 0;
00555
00556
00557 if ((source = opendir(directory.c_str())) == NULL)
00558 {
00559 dirEntries.setSize(0);
00560
00561 if (POSIX::debug)
00562 {
00563 Info<< "readDir(const fileName&, const fileType, "
00564 "const bool filtergz) : cannot open directory "
00565 << directory << endl;
00566 }
00567 }
00568 else
00569 {
00570
00571 while ((list = readdir(source)) != NULL)
00572 {
00573 fileName fName(list->d_name);
00574
00575
00576 if (fName.size() && fName[0] != '.')
00577 {
00578 word fExt = fName.ext();
00579
00580 if
00581 (
00582 (type == fileName::DIRECTORY)
00583 ||
00584 (
00585 type == fileName::FILE
00586 && fName[fName.size()-1] != '~'
00587 && fExt != "bak"
00588 && fExt != "BAK"
00589 && fExt != "old"
00590 && fExt != "save"
00591 )
00592 )
00593 {
00594 if ((directory/fName).type() == type)
00595 {
00596 if (nEntries >= dirEntries.size())
00597 {
00598 dirEntries.setSize(dirEntries.size() + maxNnames);
00599 }
00600
00601 if (filtergz && fExt == "gz")
00602 {
00603 dirEntries[nEntries++] = fName.lessExt();
00604 }
00605 else
00606 {
00607 dirEntries[nEntries++] = fName;
00608 }
00609 }
00610 }
00611 }
00612 }
00613
00614
00615 dirEntries.setSize(nEntries);
00616
00617 closedir(source);
00618 }
00619
00620 return dirEntries;
00621 }
00622
00623
00624
00625 bool Foam::cp(const fileName& src, const fileName& dest)
00626 {
00627
00628 if (!exists(src))
00629 {
00630 return false;
00631 }
00632
00633 fileName destFile(dest);
00634
00635
00636 if (src.type() == fileName::FILE)
00637 {
00638
00639 if (destFile.type() == fileName::DIRECTORY)
00640 {
00641 destFile = destFile/src.name();
00642 }
00643
00644
00645 if (!isDir(destFile.path()) && !mkDir(destFile.path()))
00646 {
00647 return false;
00648 }
00649
00650
00651 std::ifstream srcStream(src.c_str());
00652 if (!srcStream)
00653 {
00654 return false;
00655 }
00656
00657 std::ofstream destStream(destFile.c_str());
00658 if (!destStream)
00659 {
00660 return false;
00661 }
00662
00663
00664 char ch;
00665 while (srcStream.get(ch))
00666 {
00667 destStream.put(ch);
00668 }
00669
00670
00671 if (!srcStream.eof() || !destStream)
00672 {
00673 return false;
00674 }
00675 }
00676 else if (src.type() == fileName::DIRECTORY)
00677 {
00678
00679 if (destFile.type() == fileName::DIRECTORY)
00680 {
00681 destFile = destFile/src.component(src.components().size() -1);
00682 }
00683
00684
00685 if (!isDir(destFile) && !mkDir(destFile))
00686 {
00687 return false;
00688 }
00689
00690
00691 fileNameList contents = readDir(src, fileName::FILE, false);
00692 forAll(contents, i)
00693 {
00694 if (POSIX::debug)
00695 {
00696 Info<< "Copying : " << src/contents[i]
00697 << " to " << destFile/contents[i] << endl;
00698 }
00699
00700
00701 cp(src/contents[i], destFile/contents[i]);
00702 }
00703
00704
00705 fileNameList subdirs = readDir(src, fileName::DIRECTORY);
00706 forAll(subdirs, i)
00707 {
00708 if (POSIX::debug)
00709 {
00710 Info<< "Copying : " << src/subdirs[i]
00711 << " to " << destFile << endl;
00712 }
00713
00714
00715 cp(src/subdirs[i], destFile);
00716 }
00717 }
00718
00719 return true;
00720 }
00721
00722
00723
00724 bool Foam::ln(const fileName& src, const fileName& dst)
00725 {
00726 if (POSIX::debug)
00727 {
00728 Info<< "Create softlink from : " << src << " to " << dst
00729 << endl;
00730 }
00731
00732 if (exists(dst))
00733 {
00734 WarningIn("ln(const fileName&, const fileName&)")
00735 << "destination " << dst << " already exists. Not linking."
00736 << endl;
00737 return false;
00738 }
00739
00740 if (!exists(src))
00741 {
00742 WarningIn("ln(const fileName&, const fileName&)")
00743 << "source " << src << " does not exist." << endl;
00744 return false;
00745 }
00746
00747 if (symlink(src.c_str(), dst.c_str()) == 0)
00748 {
00749 return true;
00750 }
00751 else
00752 {
00753 WarningIn("ln(const fileName&, const fileName&)")
00754 << "symlink from " << src << " to " << dst << " failed." << endl;
00755 return false;
00756 }
00757 }
00758
00759
00760
00761 bool Foam::mv(const fileName& src, const fileName& dst)
00762 {
00763 if (POSIX::debug)
00764 {
00765 Info<< "Move : " << src << " to " << dst << endl;
00766 }
00767
00768 if
00769 (
00770 dst.type() == fileName::DIRECTORY
00771 && src.type() != fileName::DIRECTORY
00772 )
00773 {
00774 const fileName dstName(dst/src.name());
00775
00776 return rename(src.c_str(), dstName.c_str()) == 0;
00777 }
00778 else
00779 {
00780 return rename(src.c_str(), dst.c_str()) == 0;
00781 }
00782 }
00783
00784
00785
00786
00787 bool Foam::mvBak(const fileName& src, const std::string& ext)
00788 {
00789 if (POSIX::debug)
00790 {
00791 Info<< "mvBak : " << src << " to extension " << ext << endl;
00792 }
00793
00794 if (exists(src, false))
00795 {
00796 const int maxIndex = 99;
00797 char index[3];
00798
00799 for (int n = 0; n <= maxIndex; n++)
00800 {
00801 fileName dstName(src + "." + ext);
00802 if (n)
00803 {
00804 sprintf(index, "%02d", n);
00805 dstName += index;
00806 }
00807
00808
00809
00810 if (!exists(dstName, false) || n == maxIndex)
00811 {
00812 return rename(src.c_str(), dstName.c_str()) == 0;
00813 }
00814
00815 }
00816 }
00817
00818
00819 return false;
00820 }
00821
00822
00823
00824
00825 bool Foam::rm(const fileName& file)
00826 {
00827 if (POSIX::debug)
00828 {
00829 Info<< "Removing : " << file << endl;
00830 }
00831
00832
00833 if (remove(file.c_str()) == 0)
00834 {
00835 return true;
00836 }
00837 else
00838 {
00839 return remove(string(file + ".gz").c_str()) == 0;
00840 }
00841 }
00842
00843
00844
00845 bool Foam::rmDir(const fileName& directory)
00846 {
00847 if (POSIX::debug)
00848 {
00849 Info<< "rmDir(const fileName&) : "
00850 << "removing directory " << directory << endl;
00851 }
00852
00853
00854 DIR *source;
00855 struct dirent *list;
00856
00857
00858 if ((source = opendir(directory.c_str())) == NULL)
00859 {
00860 WarningIn("rmDir(const fileName&)")
00861 << "cannot open directory " << directory << endl;
00862
00863 return false;
00864 }
00865 else
00866 {
00867
00868 while ((list = readdir(source)) != NULL)
00869 {
00870 fileName fName(list->d_name);
00871
00872 if (fName != "." && fName != "..")
00873 {
00874 fileName path = directory/fName;
00875
00876 if (path.type() == fileName::DIRECTORY)
00877 {
00878 if (!rmDir(path))
00879 {
00880 WarningIn("rmDir(const fileName&)")
00881 << "failed to remove directory " << fName
00882 << " while removing directory " << directory
00883 << endl;
00884
00885 closedir(source);
00886
00887 return false;
00888 }
00889 }
00890 else
00891 {
00892 if (!rm(path))
00893 {
00894 WarningIn("rmDir(const fileName&)")
00895 << "failed to remove file " << fName
00896 << " while removing directory " << directory
00897 << endl;
00898
00899 closedir(source);
00900
00901 return false;
00902 }
00903 }
00904 }
00905
00906 }
00907
00908 if (!rm(directory))
00909 {
00910 WarningIn("rmDir(const fileName&)")
00911 << "failed to remove directory " << directory << endl;
00912
00913 closedir(source);
00914
00915 return false;
00916 }
00917
00918 closedir(source);
00919
00920 return true;
00921 }
00922 }
00923
00924
00925 unsigned int Foam::sleep(const unsigned int s)
00926 {
00927 return ::sleep(s);
00928 }
00929
00930
00931 void Foam::fdClose(const int fd)
00932 {
00933 if (close(fd) != 0)
00934 {
00935 FatalErrorIn
00936 (
00937 "fdClose(const int fd)"
00938 ) << "close error on " << fd << endl
00939 << abort(FatalError);
00940 }
00941 }
00942
00943
00944 bool Foam::ping
00945 (
00946 const word& destName,
00947 const label destPort,
00948 const label timeOut
00949 )
00950 {
00951 char *serverAddress;
00952 struct in_addr *ptr;
00953 struct hostent *hostPtr;
00954 volatile int sockfd;
00955 struct sockaddr_in destAddr;
00956 u_int addr;
00957
00958 if ((hostPtr = gethostbyname(destName.c_str())) == NULL)
00959 {
00960 FatalErrorIn
00961 (
00962 "Foam::ping(const word&, const label)"
00963 ) << "gethostbyname error " << h_errno << " for host " << destName
00964 << abort(FatalError);
00965 }
00966
00967
00968 serverAddress = *(hostPtr->h_addr_list);
00969 ptr = reinterpret_cast<struct in_addr*>(serverAddress);
00970 addr = ptr->s_addr;
00971
00972
00973 sockfd = socket(AF_INET, SOCK_STREAM, 0);
00974 if (sockfd < 0)
00975 {
00976 FatalErrorIn
00977 (
00978 "Foam::ping(const word&, const label)"
00979 ) << "socket error"
00980 << abort(FatalError);
00981 }
00982
00983
00984 memset (reinterpret_cast<char *>(&destAddr), '\0', sizeof(destAddr));
00985 destAddr.sin_family = AF_INET;
00986 destAddr.sin_port = htons(ushort(destPort));
00987 destAddr.sin_addr.s_addr = addr;
00988
00989
00990 timer myTimer(timeOut);
00991
00992 if (timedOut(myTimer))
00993 {
00994
00995 fdClose(sockfd);
00996 return false;
00997 }
00998
00999 if
01000 (
01001 connect
01002 (
01003 sockfd,
01004 reinterpret_cast<struct sockaddr*>(&destAddr),
01005 sizeof(struct sockaddr)
01006 ) != 0
01007 )
01008 {
01009
01010
01011 int connectErr = errno;
01012
01013 fdClose(sockfd);
01014
01015 if (connectErr == ECONNREFUSED)
01016 {
01017 return true;
01018 }
01019
01020
01021 return false;
01022 }
01023
01024 fdClose(sockfd);
01025
01026 return true;
01027 }
01028
01029
01030 bool Foam::ping(const word& hostname, const label timeOut)
01031 {
01032 return ping(hostname, 222, timeOut) || ping(hostname, 22, timeOut);
01033 }
01034
01035
01036 int Foam::system(const string& command)
01037 {
01038 return ::system(command.c_str());
01039 }
01040
01041
01042