make it compile
[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
153       accRef->open(url, preferred_attach_point);
154
155       MediaId nextId = m_impl->nextMediaId();
156
157       m_impl->mediaAccMap[nextId] = accRef;
158
159       return nextId;
160     }
161
162     // ---------------------------------------------------------------
163     void
164     MediaManager::close(MediaId mediaId)
165     {
166       MutexLock lock(g_Mutex);
167
168       if( !m_impl->hasMediaAcc( mediaId))
169         ZYPP_THROW(MediaException("Invalid media id"));
170
171       if( m_impl->hasVerifier( mediaId))
172         m_impl->mediaVfyMap.erase(mediaId);
173
174       m_impl->mediaAccMap[mediaId]->close();
175       m_impl->mediaAccMap.erase(mediaId);
176     }
177
178     // ---------------------------------------------------------------
179     bool
180     MediaManager::isOpen(MediaId mediaId) const
181     {
182       MutexLock lock(g_Mutex);
183
184       return m_impl->hasMediaAcc( mediaId);
185     }
186
187     // ---------------------------------------------------------------
188     std::string
189     MediaManager::protocol(MediaId mediaId) const
190     {
191       MutexLock lock(g_Mutex);
192
193       if( m_impl->hasMediaAcc( mediaId))
194         return m_impl->mediaAccMap[mediaId]->protocol();
195       else
196         return std::string("unknown");
197     }
198
199     // ---------------------------------------------------------------
200     Url
201     MediaManager::url(MediaId mediaId) const
202     {
203       MutexLock lock(g_Mutex);
204
205       if( m_impl->hasMediaAcc( mediaId))
206         return m_impl->mediaAccMap[mediaId]->url();
207       else
208         return Url();
209     }
210
211     // ---------------------------------------------------------------
212     void
213     MediaManager::addVerifier(MediaId mediaId, const MediaVerifierRef &ref)
214     {
215       MutexLock lock(g_Mutex);
216
217       if( !ref)
218         ZYPP_THROW(MediaException("Invalid (empty) verifier reference"));
219
220       if( !m_impl->hasMediaAcc( mediaId))
221         ZYPP_THROW(MediaException("Invalid media id"));
222
223       // FIXME: just replace?
224       if( m_impl->hasVerifier( mediaId))
225         ZYPP_THROW(MediaException("Remove verifier first"));
226
227       m_impl->mediaVfyMap[mediaId] = ref;
228     }
229
230     // ---------------------------------------------------------------
231     void
232     MediaManager::delVerifier(MediaId mediaId)
233     {
234       MutexLock lock(g_Mutex);
235
236       if( !m_impl->hasMediaAcc( mediaId))
237         ZYPP_THROW(MediaException("Invalid media id"));
238
239       if( m_impl->hasVerifier( mediaId))
240         m_impl->mediaVfyMap.erase(mediaId);
241     }
242
243     // ---------------------------------------------------------------
244     void
245     MediaManager::attach(MediaId mediaId, bool next)
246     {
247       MutexLock lock(g_Mutex);
248
249       if( !m_impl->hasMediaAcc( mediaId))
250       {
251         ZYPP_THROW(MediaNotOpenException(
252           "Invalid media id " + str::numstring(mediaId)
253         ));
254       }
255
256       if( !m_impl->hasVerifier( mediaId))
257         ZYPP_THROW(MediaException("Add a verifier first"));
258
259       m_impl->mediaAccMap[mediaId]->attach(next);
260     }
261
262     // ---------------------------------------------------------------
263     void
264     MediaManager::release(MediaId mediaId, bool eject)
265     {
266       MutexLock lock(g_Mutex);
267
268       if( !m_impl->hasMediaAcc( mediaId))
269       {
270         ZYPP_THROW(MediaNotOpenException(
271           "Invalid media id " + str::numstring(mediaId)
272         ));
273       }
274
275       m_impl->mediaAccMap[mediaId]->release(eject);
276     }
277
278     // ---------------------------------------------------------------
279     void
280     MediaManager::disconnect(MediaId mediaId)
281     {
282       MutexLock lock(g_Mutex);
283
284       if( !m_impl->hasMediaAcc( mediaId))
285       {
286         ZYPP_THROW(MediaNotOpenException(
287           "Invalid media id " + str::numstring(mediaId)
288         ));
289       }
290       return m_impl->mediaAccMap[mediaId]->disconnect();
291     }
292
293     // ---------------------------------------------------------------
294     bool
295     MediaManager::isAttached(MediaId mediaId) const
296     {
297       MutexLock lock(g_Mutex);
298
299       if( !m_impl->hasMediaAcc( mediaId))
300       {
301         // FIXME: throw or just return false?
302         ZYPP_THROW(MediaNotOpenException(
303           "Invalid media id " + str::numstring(mediaId)
304         ));
305       }
306       return m_impl->mediaAccMap[mediaId]->isAttached();
307     }
308
309     // ---------------------------------------------------------------
310     bool
311     MediaManager::isDesiredMedia(MediaId mediaId, MediaNr mediaNr) const
312     {
313       MutexLock lock(g_Mutex);
314
315       if( !isAttached(mediaId))
316         return false;
317
318       // FIXME: throw or just return false?
319       if( !m_impl->hasVerifier( mediaId))
320         ZYPP_THROW(MediaException("Add a verifier first"));
321
322       bool ok;
323       try {
324         ok = m_impl->mediaVfyMap[mediaId]->isDesiredMedia(
325           m_impl->mediaAccMap[mediaId], mediaNr
326         );
327       }
328       catch( ... ) { ok = false; }
329       return ok;
330     }
331
332     // ---------------------------------------------------------------
333     Pathname
334     MediaManager::localRoot(MediaId mediaId) const
335     {
336       MutexLock lock(g_Mutex);
337
338       if( !m_impl->hasMediaAcc( mediaId))
339       {
340         ZYPP_THROW(MediaNotOpenException(
341           "Invalid media id " + str::numstring(mediaId)
342         ));
343       }
344       Pathname path;
345       path = m_impl->mediaAccMap[mediaId]->localRoot();
346       return path;
347     }
348
349     // ---------------------------------------------------------------
350     Pathname
351     MediaManager::localPath(MediaId mediaId,
352                             const Pathname & pathname) const
353     {
354       MutexLock lock(g_Mutex);
355
356       if( !m_impl->hasMediaAcc( mediaId))
357       {
358         ZYPP_THROW(MediaNotOpenException(
359           "Invalid media id " + str::numstring(mediaId)
360         ));
361       }
362       Pathname path;
363       path = m_impl->mediaAccMap[mediaId]->localPath(pathname);
364       return path;
365     }
366
367     // ---------------------------------------------------------------
368     void
369     MediaManager::provideFile(MediaId mediaId, MediaNr mediaNr,
370                               const Pathname &filename,
371                               bool cached, bool checkonly) const
372     {
373       MutexLock lock(g_Mutex);
374
375       if( !isDesiredMedia(mediaId, mediaNr))
376       {
377         ZYPP_THROW(MediaNotDesiredException(
378           m_impl->mediaAccMap[mediaId]->url(), mediaNr
379         ));
380       }
381
382       m_impl->mediaAccMap[mediaId]->provideFile(filename, cached, checkonly);
383     }
384
385     // ---------------------------------------------------------------
386     void
387     MediaManager::provideDir(MediaId mediaId,
388                              MediaNr mediaNr,
389                              const Pathname & dirname ) const
390     {
391       MutexLock lock(g_Mutex);
392
393       if( !isDesiredMedia(mediaId, mediaNr))
394       {
395         ZYPP_THROW(MediaNotDesiredException(
396           m_impl->mediaAccMap[mediaId]->url(), mediaNr
397         ));
398       }
399
400       m_impl->mediaAccMap[mediaId]->provideDir(dirname);
401     }
402
403     // ---------------------------------------------------------------
404     void
405     MediaManager::provideDirTree(MediaId mediaId,
406                                  MediaNr mediaNr,
407                                  const Pathname & dirname ) const
408     {
409       MutexLock lock(g_Mutex);
410
411       if( !isDesiredMedia(mediaId, mediaNr))
412       {
413         ZYPP_THROW(MediaNotDesiredException(
414           m_impl->mediaAccMap[mediaId]->url(), mediaNr
415         ));
416       }
417
418       m_impl->mediaAccMap[mediaId]->provideDirTree(dirname);
419     }
420
421     // ---------------------------------------------------------------
422     void
423     MediaManager::releaseFile(MediaId mediaId,
424                               const Pathname & filename) const
425     {
426       MutexLock lock(g_Mutex);
427
428       if( !m_impl->hasMediaAcc( mediaId))
429       {
430         ZYPP_THROW(MediaNotOpenException(
431           "Invalid media id " + str::numstring(mediaId)
432         ));
433       }
434
435       m_impl->mediaAccMap[mediaId]->releaseFile(filename);
436     }
437
438     // ---------------------------------------------------------------
439     void
440     MediaManager::releaseDir(MediaId mediaId,
441                              const Pathname & dirname) const
442     {
443       MutexLock lock(g_Mutex);
444
445       if( !m_impl->hasMediaAcc( mediaId))
446       {
447         ZYPP_THROW(MediaNotOpenException(
448           "Invalid media id " + str::numstring(mediaId)
449         ));
450       }
451
452       m_impl->mediaAccMap[mediaId]->releaseDir(dirname);
453     }
454
455
456     // ---------------------------------------------------------------
457     void
458     MediaManager::releasePath(MediaId mediaId,
459                               const Pathname & pathname) const
460     {
461       MutexLock lock(g_Mutex);
462
463       if( !m_impl->hasMediaAcc( mediaId))
464       {
465         ZYPP_THROW(MediaNotOpenException(
466           "Invalid media id " + str::numstring(mediaId)
467         ));
468       }
469
470       m_impl->mediaAccMap[mediaId]->releasePath(pathname);
471     }
472
473     // ---------------------------------------------------------------
474     void
475     MediaManager::dirInfo(MediaId mediaId,
476                           std::list<std::string> & retlist,
477                           const Pathname & dirname, bool dots) const
478     {
479       MutexLock lock(g_Mutex);
480
481       if( !m_impl->hasMediaAcc( mediaId))
482       {
483         ZYPP_THROW(MediaNotOpenException(
484           "Invalid media id " + str::numstring(mediaId)
485         ));
486       }
487
488       m_impl->mediaAccMap[mediaId]->dirInfo(retlist, dirname, dots);
489     }
490
491     // ---------------------------------------------------------------
492     void
493     MediaManager::dirInfo(MediaId mediaId,
494                           filesystem::DirContent & retlist,
495                           const Pathname & dirname, bool dots) const
496     {
497       MutexLock lock(g_Mutex);
498
499       if( !m_impl->hasMediaAcc( mediaId))
500       {
501         ZYPP_THROW(MediaNotOpenException(
502           "Invalid media id " + str::numstring(mediaId)
503         ));
504       }
505
506       m_impl->mediaAccMap[mediaId]->dirInfo(retlist, dirname, dots);
507     }
508
509     //////////////////////////////////////////////////////////////////
510   } // namespace media
511   ////////////////////////////////////////////////////////////////////
512
513   ////////////////////////////////////////////////////////////////////
514 } // namespace zypp
515 //////////////////////////////////////////////////////////////////////
516 /*
517 ** vim: set ts=2 sts=2 sw=2 ai et:
518 */