casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SymLink.h
Go to the documentation of this file.
00001 //# SymLink.h: Get information about, and manipulate symbolic links
00002 //# Copyright (C) 1996
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: SymLink.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $
00027 
00028 
00029 #ifndef CASA_SYMLINK_H
00030 #define CASA_SYMLINK_H
00031 
00032 //# Includes
00033 #include <casa/aips.h>
00034 #include <casa/OS/Path.h>
00035 #include <casa/OS/File.h>
00036 
00037 
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00040 // <summary>  
00041 // Get information about, and manipulate symbolic links
00042 // </summary>
00043 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00044 // </reviewed>
00045 
00046 // <use visibility=export>
00047 
00048 // <prerequisite> 
00049 //    <li> Basic knowledge of the UNIX file system 
00050 //    <li> <linkto class=File>File</linkto>
00051 // </prerequisite>
00052 
00053 // <etymology> 
00054 // The class SymLink handles SYMbolic LINKs in the file system.
00055 // </etymology>
00056 
00057 // <synopsis> 
00058 // SymLink provides functions to manipulate and to get information about 
00059 // symbolic links. The functions for getting information (like ownership,
00060 // dates) about symbolic links are inherited from the
00061 // <linkto class=File>File</linkto> class.
00062 // <br>
00063 // The class SymLink itself provides functions to create, remove, copy, and
00064 // move symbolic links. There is a function readSymLink which reads a link and 
00065 // then returns a path and there is a function followSymLink which reads a
00066 // link recursively. If the link eventually refers to itself (a loop),
00067 // an exception will be thrown.  
00068 // </synopsis>
00069 
00070 // <example>
00071 // <srcblock>
00072 //    SymLink symLink1("isLink");
00073 //    SymLink symLink2("isLink2");
00074 //    SymLink symLinkA("A");
00075 //    SymLink symLinkB("B");
00076 //
00077 //    symLink1.create("~", True);    // Create a symbolic link to the home
00078 //                                   // directory. When it exists it will be
00079 //                                   // overwritten.
00080 //    symLink2.create("isLink", False); // Create a symbolic link to 
00081 //                                      // isLink. When it exists it will not
00082 //                                      // be overwritten.
00083 //    symLinkA.create(Path("B"));    // Create a recursive link
00084 //    symLinkB.create(Path("A"));    // Create a recursive link
00085 //
00086 //    cout << symLink1.readSymLink() << endl;  // The homedirectory is printed
00087 //    cout << symLink2.readSymLink() << endl;  // isLink is printed
00088 //    cout << symLink2.followSymLink() << endl;// The homedirectory is printed
00089 //    cout << symLinkA.readSymLink() << endl;  // B is printed
00090 //    cout << symLinkA.followSymLink() << endl;// An exception is thrown (loop)
00091 // </srcblock>
00092 // </example>
00093 
00094 // <motivation> 
00095 // Provide functions for manipulating and getting information 
00096 // about symbolic links.
00097 // </motivation>
00098 
00099 
00100 class SymLink: public File
00101 {
00102 public:
00103 
00104     // The default constructor creates a SymLink with path ".".
00105     SymLink();
00106 
00107     // Create a SymLink with the given path.
00108     // An exception is thrown if the path exist and is no symbolic link
00109     // or if it does not exist, but cannot be created.
00110     // <group>
00111     SymLink (const Path& name);
00112     SymLink (const String& name);
00113     SymLink (const File& name);
00114     // </group>
00115 
00116     // Copy constructor (copy semantics).
00117     SymLink (const SymLink& that);
00118 
00119     ~SymLink();
00120 
00121     // Assignment (copy semantics).
00122     SymLink& operator= (const SymLink& that);
00123  
00124     // Make a symbolic link to a file given by target.
00125     // An exception will be thrown if:
00126     // <br>-target already exists and is no symlink
00127     // <br>-or target already exists and overwrite==False
00128     // <group>
00129     void create (const Path& target, Bool overwrite = True);
00130     void create (const String& target, Bool overwrite = True);
00131     // </group>
00132 
00133     // Copy the symlink to the target path using the system command cp.
00134     // The target path can be a directory or a file (as in cp).
00135     // An exception is thrown if:
00136     // <br>- the target directory is not writable
00137     // <br>- or the target file already exists and overwrite==False
00138     // <br>- or the target file already exists and is not writable
00139     // <group>
00140     void copy (const Path& target, Bool overwrite = True) const;
00141     void copy (const String& target, Bool overwrite = True) const;
00142     // </group>
00143 
00144     // Move the symlink to the target path using the system command mv.
00145     // The target path can be a directory or a file (as in mv).
00146     // An exception is thrown if:
00147     // <br>- the target directory is not writable
00148     // <br>- or the target file already exists and overwrite==False
00149     // <br>- or the target file already exists and is not writable
00150     // <group>
00151     void move (const Path& target, Bool overwrite = True);
00152     void move (const String& target, Bool overwrite = True);
00153     // </group>
00154 
00155     // Remove a symbolic link.
00156     void remove();
00157 
00158     // Read value of a symbolic link and return it as a Path. If 
00159     // the symlink does not exist, an exception will be thrown.
00160     // When the symlink points to a file with a relative name,
00161     // the resulting file name gets prepended by the dirname of the symlink,
00162     // which is similar to the way a shell handles symlinks.
00163     // E.g.
00164     // <srcblock>
00165     //  ls > subdir/a
00166     //  ln -s a subdir/b
00167     //  more subdir/b
00168     // </srcblock>
00169     // The more command shows the results of subdir/a. 
00170     Path readSymLink() const;
00171 
00172     // As readSymLink, but the entire symlink chain is followed
00173     // when the symlinks points to other symlinks.
00174     // An exception is thrown if this results in a loop (that is, if more
00175     // than 25 links are encountered).
00176     Path followSymLink() const;
00177 
00178 private:
00179     // Check if the path of the file is valid.
00180     // Also resolve possible symlinks.
00181     void checkPath() const;
00182 
00183     // Get the value of the symlink.
00184     String getSymLink() const;
00185 };
00186 
00187 
00188 inline void SymLink::create (const String& target, Bool overwrite)
00189 {
00190     create (Path(target), overwrite);
00191 }
00192 inline void SymLink::copy (const String& target, Bool overwrite) const
00193 {
00194     copy (Path(target), overwrite);
00195 }
00196 inline void SymLink::move (const String& target, Bool overwrite)
00197 {
00198     move (Path(target), overwrite);
00199 }
00200 
00201 
00202 
00203 } //# NAMESPACE CASA - END
00204 
00205 #endif