winix/core/mounts.cpp

175 lines
2.9 KiB
C++
Executable File

/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2009, Tomasz Sowa
* All rights reserved.
*
*/
#include "mounts.h"
#include "request.h"
#include "log.h"
#include "mountparser.h"
#include "db.h"
Mounts::Mounts()
{
pmount = 0;
}
void Mounts::SetDirs(Dirs * pdirs)
{
dirs = pdirs;
}
void Mounts::SetDb(Db * pdb)
{
db = pdb;
}
void Mounts::SetRequest(Request * prequest)
{
request = prequest;
}
// reading from 'mounts'
Error Mounts::ReadMounts(const std::string & mounts)
{
MountParser mp;
mp.SetDirs(dirs);
Error err = mp.Parse(mounts, mount_tab);
if( err != WINIX_ERR_OK )
{
log << log1 << "M: some problems with mountpoints (mountpoints table will be empty)" << logend;
mount_tab.clear();
}
CalcCurMount();
return err;
}
// reading from /etc/fstab
Error Mounts::ReadMounts()
{
static std::string file = "fstab";
Item * etc = dirs->GetEtcDir();
if( !etc )
{
log << log1 << "M: there is no /etc directory" << logend;
return WINIX_ERR_NO_ITEM;
}
Item fstab;
Error err = db->GetItem(etc->id, file, fstab);
if( err == WINIX_ERR_NO_ITEM )
{
log << log1 << "M: there is no /etc/fstab file" << logend;
return err;
}
if( err != WINIX_ERR_OK )
{
log << log1 << "M: cannot read /etc/fstab" << logend;
return err;
}
return ReadMounts(fstab.content);
}
void Mounts::MountCmsForRoot()
{
Mount mount;
mount.type = Mount::cms;
mount.fs = Mount::simplefs;
Item * proot = dirs->GetRootDir();
if( proot )
mount.dir_id = proot->id;
else
{
mount.dir_id = -1;
log << log1 << "M: there is no a root dir" << logend;
}
std::pair<MountTab::iterator, bool> res = mount_tab.insert( std::make_pair(mount.dir_id, mount) );
pmount = &(res.first->second);
}
void Mounts::CalcCurMount()
{
std::vector<Item*>::reverse_iterator i;
// when the program starts (when the dir_tab is empty()
// we don't want to call MountCmsForRoot()
if( request->dir_tab.empty() )
return;
for(i = request->dir_tab.rbegin() ; i!=request->dir_tab.rend() ; ++i)
{
std::map<long, Mount>::iterator m = mount_tab.find( (*i)->id );
if( m != mount_tab.end() )
{
pmount = &(m->second);
log << log2 << "M: current mount point is: " << pmount->TypeToStr()
<< ", fs: " << pmount->FsToStr() << logend;
return;
}
}
// if nothing was found
// we assume that 'cms' mount point is used
MountCmsForRoot();
log << log2 << "M: current mount point is: " << pmount->TypeToStr() << " (default)"
<< ", fs: " << pmount->FsToStr() << logend;
}
// can return null pointer
// and we don't assume cms as a default mount point if nothing is found
Mount * Mounts::CalcMount(long dir_id)
{
while( true )
{
Item * pdir = dirs->GetDir(dir_id);
if( !pdir )
return 0;
std::map<long, Mount>::iterator m = mount_tab.find( pdir->id );
if( m != mount_tab.end() )
return &(m->second);
dir_id = pdir->parent_id;
}
}
const Mounts::MountTab * Mounts::GetMountTab()
{
return &mount_tab;
}