Implement media doesFileExists().
[platform/upstream/libzypp.git] / zypp / media / MediaAccess.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaAccess.cc
10  *
11 */
12
13 #include <ctype.h>
14
15 #include <iostream>
16
17 #include "zypp/base/Logger.h"
18
19 #include "zypp/media/MediaException.h"
20 #include "zypp/media/MediaAccess.h"
21 #include "zypp/media/MediaHandler.h"
22
23 #include "zypp/media/MediaNFS.h"
24 #include "zypp/media/MediaCD.h"
25 #include "zypp/media/MediaDIR.h"
26 #include "zypp/media/MediaDISK.h"
27 #include "zypp/media/MediaSMB.h"
28 #include "zypp/media/MediaCIFS.h"
29 #include "zypp/media/MediaCurl.h"
30 #include "zypp/media/MediaISO.h"
31
32 using namespace std;
33
34 namespace zypp {
35   namespace media {
36
37 ///////////////////////////////////////////////////////////////////
38 //
39 //      CLASS NAME : MediaAccess
40 //
41 ///////////////////////////////////////////////////////////////////
42
43 const Pathname MediaAccess::_noPath; // empty path
44
45 ///////////////////////////////////////////////////////////////////
46 // constructor
47 MediaAccess::MediaAccess ()
48     : _handler (0)
49 {
50 }
51
52 // destructor
53 MediaAccess::~MediaAccess()
54 {
55   try
56     {
57       close(); // !!! make sure handler gets properly deleted.
58     }
59   catch(...) {}
60 }
61
62 AttachedMedia
63 MediaAccess::attachedMedia() const
64 {
65         return _handler ? _handler->attachedMedia()
66                         : AttachedMedia();
67 }
68
69 bool
70 MediaAccess::isSharedMedia() const
71 {
72         return _handler ? _handler->isSharedMedia()
73                         : false;
74 }
75
76 void
77 MediaAccess::resetParentId()
78 {
79         if( _handler) _handler->resetParentId();
80 }
81
82 bool
83 MediaAccess::dependsOnParent() const
84 {
85         return _handler ? _handler->dependsOnParent() : false;
86 }
87
88 bool
89 MediaAccess::dependsOnParent(MediaAccessId parentId,
90                              bool exactIdMatch) const
91 {
92         return _handler ? _handler->dependsOnParent(parentId, exactIdMatch)
93                         : false;
94 }
95
96 // open URL
97 void
98 MediaAccess::open (const Url& url, const Pathname & preferred_attach_point)
99 {
100     if(!url.isValid()) {
101         MIL << "Url is not valid" << endl;
102         ZYPP_THROW(MediaBadUrlException(url));
103     }
104
105     close();
106
107     std::string scheme = url.getScheme();
108
109     MIL << "Trying scheme '" << scheme << "'" << endl;
110
111     /*
112     ** WARNING: Don't forget to update MediaAccess::downloads(url)
113     **          if you are adding a new url scheme / handler!
114     */
115     if (scheme == "cd" || scheme == "dvd")
116         _handler = new MediaCD (url,preferred_attach_point);
117     else if (scheme == "nfs")
118         _handler = new MediaNFS (url,preferred_attach_point);
119     else if (scheme == "iso")
120         _handler = new MediaISO (url,preferred_attach_point);
121     else if (scheme == "file" || scheme == "dir")
122         _handler = new MediaDIR (url,preferred_attach_point);
123     else if (scheme == "hd")
124         _handler = new MediaDISK (url,preferred_attach_point);
125     else if (scheme == "smb")
126         _handler = new MediaSMB (url,preferred_attach_point);
127     else if (scheme == "cifs")
128         _handler = new MediaCIFS (url,preferred_attach_point);
129     else if (scheme == "ftp" || scheme == "http" || scheme == "https")
130         _handler = new MediaCurl (url,preferred_attach_point);
131     else
132     {
133         ZYPP_THROW(MediaUnsupportedUrlSchemeException(url));
134     }
135
136     // check created handler
137     if ( !_handler ){
138       ERR << "Failed to create media handler" << endl;
139       ZYPP_THROW(MediaSystemException(url, "Failed to create media handler"));
140     }
141
142     MIL << "Opened: " << *this << endl;
143 }
144
145 // STATIC
146 bool
147 MediaAccess::downloads(const Url &url)
148 {
149     std::string scheme( url.getScheme());
150     return (scheme == "ftp" || scheme == "http" || scheme == "https");
151 }
152
153 // STATIC
154 bool
155 MediaAccess::canBeVolatile(const Url &url)
156 {
157     std::string scheme( url.getScheme());
158     return ! (scheme == "cd" || scheme == "dvd");
159 }
160
161 // Type of media if open, otherwise NONE.
162 std::string
163 MediaAccess::protocol() const
164 {
165   if ( !_handler )
166     return "unknown";
167
168   return _handler->protocol();
169 }
170
171 bool
172 MediaAccess::downloads() const
173 {
174         return _handler ? _handler->downloads() : false;
175 }
176
177 ///////////////////////////////////////////////////////////////////
178 //
179 //
180 //      METHOD NAME : MediaAccess::url
181 //      METHOD TYPE : Url
182 //
183 Url MediaAccess::url() const
184 {
185   if ( !_handler )
186     return Url();
187
188   return _handler->url();
189 }
190
191 // close handler
192 void
193 MediaAccess::close ()
194 {
195   ///////////////////////////////////////////////////////////////////
196   // !!! make shure handler gets properly deleted.
197   // I.e. release attached media before deleting the handler.
198   ///////////////////////////////////////////////////////////////////
199   if ( _handler ) {
200     try {
201       _handler->release();
202     }
203     catch (const MediaException & excpt_r)
204     {
205       ZYPP_CAUGHT(excpt_r);
206       WAR << "Close: " << *this << " (" << excpt_r << ")" << endl;
207       ZYPP_RETHROW(excpt_r);
208     }
209     MIL << "Close: " << *this << " (OK)" << endl;
210     delete _handler;
211     _handler = 0;
212   }
213 }
214
215
216 // attach media
217 void MediaAccess::attach (bool next)
218 {
219   if ( !_handler ) {
220     ZYPP_THROW(MediaNotOpenException("attach"));
221   }
222   _handler->attach(next);
223 }
224
225 // True if media is open and attached.
226 bool
227 MediaAccess::isAttached() const
228 {
229   return( _handler && _handler->isAttached() );
230 }
231
232 // local directory that corresponds to medias url
233 // If media is not open an empty pathname.
234 Pathname
235 MediaAccess::localRoot() const
236 {
237   if ( !_handler )
238     return _noPath;
239
240   return _handler->localRoot();
241 }
242
243 // Short for 'localRoot() + pathname', but returns an empty
244 // * pathname if media is not open.
245 Pathname
246 MediaAccess::localPath( const Pathname & pathname ) const
247 {
248   if ( !_handler )
249     return _noPath;
250
251   return _handler->localPath( pathname );
252 }
253
254 void
255 MediaAccess::disconnect()
256 {
257   if ( !_handler )
258     ZYPP_THROW(MediaNotOpenException("disconnect"));
259
260   _handler->disconnect();
261 }
262
263 // release attached media
264 void
265 MediaAccess::release( bool eject )
266 {
267   if ( !_handler )
268     return;
269
270   _handler->release( eject );
271 }
272
273
274 // provide file denoted by path to attach dir
275 //
276 // filename is interpreted relative to the attached url
277 // and a path prefix is preserved to destination
278 void
279 MediaAccess::provideFile( const Pathname & filename, bool cached, bool checkonly) const
280 {
281   if ( cached ) {
282     PathInfo pi( localPath( filename ) );
283     if ( pi.isExist() )
284       return;
285   }
286
287   if(checkonly)
288     ZYPP_THROW(MediaFileNotFoundException(url(), filename));
289
290   if ( !_handler ) {
291     ZYPP_THROW(MediaNotOpenException("provideFile(" + filename.asString() + ")"));
292   }
293
294   _handler->provideFile( filename );
295 }
296
297 void
298 MediaAccess::releaseFile( const Pathname & filename ) const
299 {
300   if ( !_handler )
301     return;
302
303   _handler->releaseFile( filename );
304 }
305
306 // provide directory tree denoted by path to attach dir
307 //
308 // dirname is interpreted relative to the attached url
309 // and a path prefix is preserved to destination
310 void
311 MediaAccess::provideDir( const Pathname & dirname ) const
312 {
313   if ( !_handler ) {
314     ZYPP_THROW(MediaNotOpenException("provideDir(" + dirname.asString() + ")"));
315   }
316
317   _handler->provideDir( dirname );
318 }
319
320 void
321 MediaAccess::provideDirTree( const Pathname & dirname ) const
322 {
323   if ( !_handler ) {
324     ZYPP_THROW(MediaNotOpenException("provideDirTree(" + dirname.asString() + ")"));
325   }
326
327   _handler->provideDirTree( dirname );
328 }
329
330 void
331 MediaAccess::releaseDir( const Pathname & dirname ) const
332 {
333   if ( !_handler )
334     return;
335
336   _handler->releaseDir( dirname );
337 }
338
339 void
340 MediaAccess::releasePath( const Pathname & pathname ) const
341 {
342   if ( !_handler )
343     return;
344
345   _handler->releasePath( pathname );
346 }
347
348 // Return content of directory on media
349 void
350 MediaAccess::dirInfo( list<string> & retlist, const Pathname & dirname, bool dots ) const
351 {
352   retlist.clear();
353
354   if ( !_handler ) {
355     ZYPP_THROW(MediaNotOpenException("dirInfo(" + dirname.asString() + ")"));
356   }
357
358   _handler->dirInfo( retlist, dirname, dots );
359 }
360
361 // Return content of directory on media
362 void
363 MediaAccess::dirInfo( filesystem::DirContent & retlist, const Pathname & dirname, bool dots ) const
364 {
365   retlist.clear();
366
367   if ( !_handler ) {
368     ZYPP_THROW(MediaNotOpenException("dirInfo(" + dirname.asString() + ")"));
369   }
370
371   _handler->dirInfo( retlist, dirname, dots );
372 }
373
374 // return if a file exists
375 bool 
376 MediaAccess::doesFileExist( const Pathname & filename ) const
377 {
378   if ( !_handler ) {
379     ZYPP_THROW(MediaNotOpenException("doesFileExist(" + filename.asString() + ")"));
380   }
381
382   return _handler->doesFileExist( filename );
383 }  
384
385 std::ostream &
386 MediaAccess::dumpOn( std::ostream & str ) const
387 {
388   if ( !_handler )
389     return str << "MediaAccess( closed )";
390
391   str << _handler->protocol() << "(" << *_handler << ")";
392   return str;
393 }
394
395 void MediaAccess::getFile( const Url &from, const Pathname &to )
396 {
397   DBG << "From: " << from << endl << "To: " << to << endl;
398
399   Pathname path = from.getPathData();
400   Pathname dir = path.dirname();
401   string base = path.basename();
402
403   Url u = from;
404   u.setPathData( dir.asString() );
405
406   MediaAccess media;
407
408   try {
409     media.open( u );
410     media.attach();
411     media._handler->provideFileCopy( base, to );
412     media.release();
413   }
414   catch (const MediaException & excpt_r)
415   {
416     ZYPP_RETHROW(excpt_r);
417   }
418 }
419     std::ostream & operator<<( std::ostream & str, const MediaAccess & obj )
420     { return obj.dumpOn( str ); }
421
422 ///////////////////////////////////////////////////////////////////
423   } // namespace media
424 } // namespace zypp