- Added preferred_attach_point to MediaManager::open()
[platform/upstream/libzypp.git] / zypp / media / MediaManager.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaManager.cc
10  *
11 */
12 #include <zypp/media/MediaException.h>
13 #include <zypp/media/MediaManager.h>
14 //#include <zypp/media/Mount.h>
15 //#include <zypp/media/Hal.h>
16 #include <zypp/thread/Mutex.h>
17 #include <zypp/thread/MutexLock.h>
18
19 #include <zypp/base/String.h>
20 #include <zypp/base/Logger.h>
21 #include <zypp/Pathname.h>
22 #include <zypp/PathInfo.h>
23
24 #include <map>
25 #include <list>
26 #include <iostream>
27
28
29 //////////////////////////////////////////////////////////////////////
30 namespace zypp
31 { ////////////////////////////////////////////////////////////////////
32
33   ////////////////////////////////////////////////////////////////////
34   namespace media
35   { //////////////////////////////////////////////////////////////////
36
37     using zypp::thread::Mutex;
38     using zypp::thread::MutexLock;
39
40     //////////////////////////////////////////////////////////////////
41     namespace // anonymous
42     { ////////////////////////////////////////////////////////////////
43
44
45       // -------------------------------------------------------------
46       // STATIC
47       static Mutex  g_Mutex;
48
49       typedef std::map<MediaId, MediaVerifierRef> MediaVfyMap;
50       typedef std::map<MediaId, MediaAccessRef>   MediaAccMap;
51
52
53       ////////////////////////////////////////////////////////////////
54     } // anonymous
55     //////////////////////////////////////////////////////////////////
56
57
58     // ---------------------------------------------------------------
59     class MediaManager::Impl
60     {
61     private:
62     /*
63       time_t       mtab_mtime;
64       MountEntries mtab_table;
65     */
66       MediaId      last_mediaid;
67
68     public:
69       MediaVfyMap  mediaVfyMap;
70       MediaAccMap  mediaAccMap;
71
72       Impl()
73         : /* mtab_mtime(0)
74         , */ last_mediaid(0)
75       {}
76
77       ~Impl()
78       {}
79
80       MediaId
81       nextMediaId()
82       {
83         return last_mediaid++;
84       }
85
86       bool hasMediaAcc(MediaId mediaId) const
87       {
88         return mediaAccMap.find(mediaId) != mediaAccMap.end();
89       }
90
91       bool hasVerifier(MediaId mediaId) const
92       {
93         return mediaVfyMap.find(mediaId) != mediaVfyMap.end();
94       }
95
96       /*
97       MountEntries
98       getMountEntries()
99       {
100         if( mtab_mtime == 0 ||
101             mtab_mtime != zypp::PathInfo("/etc/mtab").mtime())
102         {
103           mtab_table = Mount::getEntries("/etc/mtab");
104         }
105         return mtab_table;
106       }
107       */
108     };
109
110
111     // ---------------------------------------------------------------
112     // STATIC
113     zypp::RW_pointer<MediaManager::Impl> MediaManager::m_impl(NULL);
114
115
116     // ---------------------------------------------------------------
117     MediaManager::MediaManager()
118     {
119       MutexLock lock(g_Mutex);
120       if( !m_impl)
121       {
122         m_impl.reset( new MediaManager::Impl());
123       }
124     }
125
126     // ---------------------------------------------------------------
127     MediaManager::~MediaManager()
128     {
129     }
130
131     // ---------------------------------------------------------------
132     MediaId
133     MediaManager::open(const Url &url, const Pathname &preferred_attach_point)
134     {
135       MutexLock lock(g_Mutex);
136
137       // check if we already have this url
138       MediaAccMap::const_iterator a(m_impl->mediaAccMap.begin());
139       for( ; a != m_impl->mediaAccMap.end(); ++a)
140       {
141         // FIXME: not sufficient. each handler should provide
142         //        method to compare its type of media url
143         //        and MediaAccess to choose right handler...
144         if( a->second->url().asString() == url.asString())
145         {
146           return a->first;
147         }
148       }
149
150       // create new access handler for it
151       MediaAccessRef accRef( new MediaAccess());
152       MediaId        nextId( m_impl->nextMediaId());
153
154       m_impl->mediaAccMap[nextId] = accRef;
155
156       accRef->open(url, preferred_attach_point);
157
158       return nextId;
159     }
160
161     // ---------------------------------------------------------------
162     void
163     MediaManager::close(MediaId mediaId)
164     {
165       MutexLock lock(g_Mutex);
166
167       if( !m_impl->hasMediaAcc( mediaId))
168         ZYPP_THROW(MediaException("Invalid media id"));
169
170       if( m_impl->hasVerifier( mediaId))
171         m_impl->mediaVfyMap.erase(mediaId);
172
173       m_impl->mediaAccMap[mediaId]->close();
174       m_impl->mediaAccMap.erase(mediaId);
175     }
176
177     // ---------------------------------------------------------------
178     bool
179     MediaManager::isOpen(MediaId mediaId) const
180     {
181       MutexLock lock(g_Mutex);
182
183       return m_impl->hasMediaAcc( mediaId);
184     }
185
186     // ---------------------------------------------------------------
187     std::string
188     MediaManager::protocol(MediaId mediaId) const
189     {
190       MutexLock lock(g_Mutex);
191
192       if( m_impl->hasMediaAcc( mediaId))
193         return m_impl->mediaAccMap[mediaId]->protocol();
194       else
195         return std::string("unknown");
196     }
197
198     // ---------------------------------------------------------------
199     Url
200     MediaManager::url(MediaId mediaId) const
201     {
202       MutexLock lock(g_Mutex);
203
204       if( m_impl->hasMediaAcc( mediaId))
205         return m_impl->mediaAccMap[mediaId]->url();
206       else
207         return Url();
208     }
209
210     // ---------------------------------------------------------------
211     void
212     MediaManager::addVerifier(MediaId mediaId, const MediaVerifierRef &ref)
213     {
214       MutexLock lock(g_Mutex);
215
216       if( !ref)
217         ZYPP_THROW(MediaException("Invalid (empty) verifier reference"));
218
219       if( !m_impl->hasMediaAcc( mediaId))
220         ZYPP_THROW(MediaException("Invalid media id"));
221
222       // FIXME: just replace?
223       if( m_impl->hasVerifier( mediaId))
224         ZYPP_THROW(MediaException("Remove verifier first"));
225
226       m_impl->mediaVfyMap[mediaId] = ref;
227     }
228
229     // ---------------------------------------------------------------
230     void
231     MediaManager::delVerifier(MediaId mediaId)
232     {
233       MutexLock lock(g_Mutex);
234
235       if( !m_impl->hasMediaAcc( mediaId))
236         ZYPP_THROW(MediaException("Invalid media id"));
237
238       if( m_impl->hasVerifier( mediaId))
239         m_impl->mediaVfyMap.erase(mediaId);
240     }
241
242     // ---------------------------------------------------------------
243     void
244     MediaManager::attach(MediaId mediaId, bool next)
245     {
246       MutexLock lock(g_Mutex);
247
248       if( !m_impl->hasMediaAcc( mediaId))
249       {
250         ZYPP_THROW(MediaNotOpenException(
251           "Invalid media id " + str::numstring(mediaId)
252         ));
253       }
254
255       if( !m_impl->hasVerifier( mediaId))
256         ZYPP_THROW(MediaException("Add a verifier first"));
257
258       m_impl->mediaAccMap[mediaId]->attach(next);
259     }
260
261     // ---------------------------------------------------------------
262     void
263     MediaManager::release(MediaId mediaId, bool eject)
264     {
265       MutexLock lock(g_Mutex);
266
267       if( !m_impl->hasMediaAcc( mediaId))
268       {
269         ZYPP_THROW(MediaNotOpenException(
270           "Invalid media id " + str::numstring(mediaId)
271         ));
272       }
273
274       m_impl->mediaAccMap[mediaId]->release(eject);
275     }
276
277     // ---------------------------------------------------------------
278     void
279     MediaManager::disconnect(MediaId mediaId)
280     {
281       MutexLock lock(g_Mutex);
282
283       if( !m_impl->hasMediaAcc( mediaId))
284       {
285         ZYPP_THROW(MediaNotOpenException(
286           "Invalid media id " + str::numstring(mediaId)
287         ));
288       }
289       return m_impl->mediaAccMap[mediaId]->disconnect();
290     }
291
292     // ---------------------------------------------------------------
293     bool
294     MediaManager::isAttached(MediaId mediaId) const
295     {
296       MutexLock lock(g_Mutex);
297
298       if( !m_impl->hasMediaAcc( mediaId))
299       {
300         // FIXME: throw or just return false?
301         ZYPP_THROW(MediaNotOpenException(
302           "Invalid media id " + str::numstring(mediaId)
303         ));
304       }
305       return m_impl->mediaAccMap[mediaId]->isAttached();
306     }
307
308     // ---------------------------------------------------------------
309     bool
310     MediaManager::isDesiredMedia(MediaId mediaId, MediaNr mediaNr) const
311     {
312       MutexLock lock(g_Mutex);
313
314       if( !isAttached(mediaId))
315         return false;
316
317       // FIXME: throw or just return false?
318       if( !m_impl->hasVerifier( mediaId))
319         ZYPP_THROW(MediaException("Add a verifier first"));
320
321       bool ok;
322       try {
323         ok = m_impl->mediaVfyMap[mediaId]->isDesiredMedia(
324           m_impl->mediaAccMap[mediaId], mediaNr
325         );
326       }
327       catch( ... ) { ok = false; }
328       return ok;
329     }
330
331     // ---------------------------------------------------------------
332     Pathname
333     MediaManager::localRoot(MediaId mediaId) const
334     {
335       MutexLock lock(g_Mutex);
336
337       if( !m_impl->hasMediaAcc( mediaId))
338       {
339         ZYPP_THROW(MediaNotOpenException(
340           "Invalid media id " + str::numstring(mediaId)
341         ));
342       }
343       Pathname path;
344       path = m_impl->mediaAccMap[mediaId]->localRoot();
345       return path;
346     }
347
348     // ---------------------------------------------------------------
349     Pathname
350     MediaManager::localPath(MediaId mediaId,
351                             const Pathname & pathname) const
352     {
353       MutexLock lock(g_Mutex);
354
355       if( !m_impl->hasMediaAcc( mediaId))
356       {
357         ZYPP_THROW(MediaNotOpenException(
358           "Invalid media id " + str::numstring(mediaId)
359         ));
360       }
361       Pathname path;
362       path = m_impl->mediaAccMap[mediaId]->localPath(pathname);
363       return path;
364     }
365
366     // ---------------------------------------------------------------
367     void
368     MediaManager::provideFile(MediaId mediaId, MediaNr mediaNr,
369                               const Pathname &filename,
370                               bool cached, bool checkonly) const
371     {
372       MutexLock lock(g_Mutex);
373
374       if( !isDesiredMedia(mediaId, mediaNr))
375       {
376         ZYPP_THROW(MediaNotDesiredException(
377           m_impl->mediaAccMap[mediaId]->url(), mediaNr
378         ));
379       }
380
381       m_impl->mediaAccMap[mediaId]->provideFile(filename, cached, checkonly);
382     }
383
384     // ---------------------------------------------------------------
385     void
386     MediaManager::provideDir(MediaId mediaId,
387                              MediaNr mediaNr,
388                              const Pathname & dirname ) const
389     {
390       MutexLock lock(g_Mutex);
391
392       if( !isDesiredMedia(mediaId, mediaNr))
393       {
394         ZYPP_THROW(MediaNotDesiredException(
395           m_impl->mediaAccMap[mediaId]->url(), mediaNr
396         ));
397       }
398
399       m_impl->mediaAccMap[mediaId]->provideDir(dirname);
400     }
401
402     // ---------------------------------------------------------------
403     void
404     MediaManager::provideDirTree(MediaId mediaId,
405                                  MediaNr mediaNr,
406                                  const Pathname & dirname ) const
407     {
408       MutexLock lock(g_Mutex);
409
410       if( !isDesiredMedia(mediaId, mediaNr))
411       {
412         ZYPP_THROW(MediaNotDesiredException(
413           m_impl->mediaAccMap[mediaId]->url(), mediaNr
414         ));
415       }
416
417       m_impl->mediaAccMap[mediaId]->provideDirTree(dirname);
418     }
419
420     // ---------------------------------------------------------------
421     void
422     MediaManager::releaseFile(MediaId mediaId,
423                               const Pathname & filename) const
424     {
425       MutexLock lock(g_Mutex);
426
427       if( !m_impl->hasMediaAcc( mediaId))
428       {
429         ZYPP_THROW(MediaNotOpenException(
430           "Invalid media id " + str::numstring(mediaId)
431         ));
432       }
433
434       m_impl->mediaAccMap[mediaId]->releaseFile(filename);
435     }
436
437     // ---------------------------------------------------------------
438     void
439     MediaManager::releaseDir(MediaId mediaId,
440                              const Pathname & dirname) const
441     {
442       MutexLock lock(g_Mutex);
443
444       if( !m_impl->hasMediaAcc( mediaId))
445       {
446         ZYPP_THROW(MediaNotOpenException(
447           "Invalid media id " + str::numstring(mediaId)
448         ));
449       }
450
451       m_impl->mediaAccMap[mediaId]->releaseDir(dirname);
452     }
453
454
455     // ---------------------------------------------------------------
456     void
457     MediaManager::releasePath(MediaId mediaId,
458                               const Pathname & pathname) const
459     {
460       MutexLock lock(g_Mutex);
461
462       if( !m_impl->hasMediaAcc( mediaId))
463       {
464         ZYPP_THROW(MediaNotOpenException(
465           "Invalid media id " + str::numstring(mediaId)
466         ));
467       }
468
469       m_impl->mediaAccMap[mediaId]->releasePath(pathname);
470     }
471
472     // ---------------------------------------------------------------
473     void
474     MediaManager::dirInfo(MediaId mediaId,
475                           std::list<std::string> & retlist,
476                           const Pathname & dirname, bool dots) const
477     {
478       MutexLock lock(g_Mutex);
479
480       if( !m_impl->hasMediaAcc( mediaId))
481       {
482         ZYPP_THROW(MediaNotOpenException(
483           "Invalid media id " + str::numstring(mediaId)
484         ));
485       }
486
487       m_impl->mediaAccMap[mediaId]->dirInfo(retlist, dirname, dots);
488     }
489
490     // ---------------------------------------------------------------
491     void
492     MediaManager::dirInfo(MediaId mediaId,
493                           filesystem::DirContent & retlist,
494                           const Pathname & dirname, bool dots) const
495     {
496       MutexLock lock(g_Mutex);
497
498       if( !m_impl->hasMediaAcc( mediaId))
499       {
500         ZYPP_THROW(MediaNotOpenException(
501           "Invalid media id " + str::numstring(mediaId)
502         ));
503       }
504
505       m_impl->mediaAccMap[mediaId]->dirInfo(retlist, dirname, dots);
506     }
507
508     //////////////////////////////////////////////////////////////////
509   } // namespace media
510   ////////////////////////////////////////////////////////////////////
511
512   ////////////////////////////////////////////////////////////////////
513 } // namespace zypp
514 //////////////////////////////////////////////////////////////////////
515 /*
516 ** vim: set ts=2 sts=2 sw=2 ai et:
517 */