- Create the cache directly from the schema (installed) file.
[platform/upstream/libzypp.git] / zypp / TmpPath.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/TmpPath.cc
10  *
11 */
12
13 #include <cstdlib>
14 #include <cstring>
15 #include <cerrno>
16
17 #include <iostream>
18
19 #include "zypp/base/ReferenceCounted.h"
20 #include "zypp/base/NonCopyable.h"
21 #include "zypp/base/Logger.h"
22 #include "zypp/PathInfo.h"
23 #include "zypp/TmpPath.h"
24
25 using namespace std;
26
27 namespace zypp {
28   namespace filesystem {
29
30     ///////////////////////////////////////////////////////////////////
31     //
32     //  CLASS NAME : TmpPath::Impl
33     /**
34      * Clean or delete a directory on destruction.
35      **/
36     class TmpPath::Impl : public base::ReferenceCounted, private base::NonCopyable
37     {
38       public:
39     
40         enum Flags
41           {
42             NoOp         = 0,
43             Autodelete   = 1L << 0,
44             KeepTopdir   = 1L << 1,
45             //
46             CtorDefault  = Autodelete
47           };
48     
49       public:
50     
51         Impl( const Pathname & path_r, Flags flags_r = CtorDefault )
52         : _path( path_r ), _flags( flags_r )
53         {}
54     
55         ~Impl()
56         {
57           if ( ! (_flags & Autodelete) || _path.empty() )
58             return;
59     
60           PathInfo p( _path, PathInfo::LSTAT );
61           if ( ! p.isExist() )
62             return;
63     
64           int res = 0;
65           if ( p.isDir() )
66             {
67               if ( _flags & KeepTopdir )
68                 res = clean_dir( _path );
69               else
70                 res = recursive_rmdir( _path );
71             }
72           else
73             res = unlink( _path );
74     
75           if ( res )
76             INT << "TmpPath cleanup error (" << res << ") " << p << endl;
77           else
78             DBG << "TmpPath cleaned up " << p << endl;
79         }
80     
81         const Pathname &
82         path() const
83         { return _path; }
84     
85       private:
86         Pathname _path;
87         Flags    _flags;
88     };
89     ///////////////////////////////////////////////////////////////////
90     
91     ///////////////////////////////////////////////////////////////////
92     //
93     //  CLASS NAME : TmpPath
94     //
95     ///////////////////////////////////////////////////////////////////
96     
97     ///////////////////////////////////////////////////////////////////
98     //
99     //  METHOD NAME : TmpPath::TmpPath
100     //  METHOD TYPE : Constructor
101     //
102     TmpPath::TmpPath()
103     :_impl( 0 ) // empty Pathname
104     {
105     }
106     
107     ///////////////////////////////////////////////////////////////////
108     //
109     //  METHOD NAME : TmpPath::TmpPath
110     //  METHOD TYPE : Constructor
111     //
112     TmpPath::TmpPath( const Pathname & tmpPath_r )
113     :_impl( tmpPath_r.empty() ? 0 : new Impl( tmpPath_r ) )
114     {
115     }
116     
117     ///////////////////////////////////////////////////////////////////
118     //
119     //  METHOD NAME : TmpPath::~TmpPath
120     //  METHOD TYPE : Destructor
121     //
122     TmpPath::~TmpPath()
123     {
124       // virtual not inlined dtor.
125     }
126    
127     ///////////////////////////////////////////////////////////////////
128     //
129     //      METHOD NAME : TmpPath::operator const void *const
130     //      METHOD TYPE :
131     //
132     TmpPath::operator const void *const() const
133     {
134       return _impl.get();
135     }
136  
137     ///////////////////////////////////////////////////////////////////
138     //
139     //  METHOD NAME : TmpPath::path
140     //  METHOD TYPE : Pathname
141     //
142     Pathname
143     TmpPath::path() const
144     {
145       return _impl.get() ? _impl->path() : Pathname();
146     }
147     
148     ///////////////////////////////////////////////////////////////////
149     //
150     //  METHOD NAME : TmpPath::defaultLocation
151     //  METHOD TYPE : const Pathname &
152     //
153     const Pathname &
154     TmpPath::defaultLocation()
155     {
156       static Pathname p( "/var/tmp" );
157       return p;
158     }
159     ///////////////////////////////////////////////////////////////////
160     //
161     //  CLASS NAME : TmpFile
162     //
163     ///////////////////////////////////////////////////////////////////
164     
165     
166     ///////////////////////////////////////////////////////////////////
167     //
168     //  METHOD NAME : TmpFile::TmpFile
169     //  METHOD TYPE : Constructor
170     //
171     TmpFile::TmpFile( const Pathname & inParentDir_r,
172                       const std::string & prefix_r )
173     {
174       // parent dir must exist
175       PathInfo p( inParentDir_r );
176       if ( ! p.isDir() )
177         {
178           ERR << "Parent directory does not exist: " << p << endl;
179           return;
180         }
181     
182       // create the temp file
183       Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX");
184       char * buf = ::strdup( tmpPath.asString().c_str() );
185       if ( ! buf )
186         {
187           ERR << "Out of memory" << endl;
188           return;
189         }
190     
191       int tmpFd = ::mkstemp( buf );
192       if ( tmpFd != -1 )
193         {
194           // success; create _impl
195           ::close( tmpFd );
196           _impl = RW_pointer<Impl>( new Impl( buf ) );
197         }
198       else
199         ERR << "Cant create '" << buf << "' " << ::strerror( errno ) << endl;
200     
201       ::free( buf );
202     }
203     
204     ///////////////////////////////////////////////////////////////////
205     //
206     //  METHOD NAME : TmpFile::defaultPrefix
207     //  METHOD TYPE : const std::string &
208     //
209     const std::string &
210     TmpFile::defaultPrefix()
211     {
212       static string p( "TmpFile." );
213       return p;
214     }
215     
216     ///////////////////////////////////////////////////////////////////
217     //
218     //  CLASS NAME : TmpDir
219     //
220     ///////////////////////////////////////////////////////////////////
221     
222     ///////////////////////////////////////////////////////////////////
223     //
224     //  METHOD NAME : TmpDir::TmpDir
225     //  METHOD TYPE : Constructor
226     //
227     TmpDir::TmpDir( const Pathname & inParentDir_r,
228                     const std::string & prefix_r )
229     {
230       // parent dir must exist
231       PathInfo p( inParentDir_r );
232       if ( ! p.isDir() )
233         {
234           ERR << "Parent directory does not exist: " << p << endl;
235           return;
236         }
237     
238       // create the temp dir
239       Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX");
240       char * buf = ::strdup( tmpPath.asString().c_str() );
241       if ( ! buf )
242         {
243           ERR << "Out of memory" << endl;
244           return;
245         }
246     
247       char * tmp = ::mkdtemp( buf );
248       if ( tmp )
249         // success; create _impl
250         _impl = RW_pointer<Impl>( new Impl( tmp ) );
251       else
252         ERR << "Cant create '" << tmpPath << "' " << ::strerror( errno ) << endl;
253     
254       ::free( buf );
255     }
256     
257     ///////////////////////////////////////////////////////////////////
258     //
259     //  METHOD NAME : TmpDir::defaultPrefix
260     //  METHOD TYPE : const std::string &
261     //
262     const std::string &
263     TmpDir::defaultPrefix()
264     {
265       static string p( "TmpDir." );
266       return p;
267     }
268
269   } // namespace filesystem
270 } // namespace zypp