/* * This file is a part of Winix * and is distributed under the 2-Clause BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2009-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include "mounts.h" #include "request.h" #include "log.h" #include "db/db.h" #include "cur.h" namespace Winix { Mounts::Mounts() { pmount = &empty_mount; skip_static = false; } void Mounts::SkipStaticDirs(bool skip) { skip_static = skip; } void Mounts::CreateMountType() { mount_type_cms = AddMountType(L"cms"); mount_type_static = AddMountType(L"static"); } void Mounts::CreateMountFs() { mount_fs_simplefs = AddMountFs(L"simplefs"); mount_fs_hashfs = AddMountFs(L"hashfs"); } void Mounts::CreateMountPar() { mount_par_page = AddMountPar(L"page"); mount_par_thumb_size = AddMountPar(L"thumb_size"); mount_par_thumb_mode = AddMountPar(L"thumb_mode"); mount_par_thumb_quality = AddMountPar(L"thumb_quality"); mount_par_image_size = AddMountPar(L"image_size"); mount_par_image_mode = AddMountPar(L"image_mode"); mount_par_image_quality = AddMountPar(L"image_quality"); mount_par_emacs_on = AddMountPar(L"emacs_on"); mount_par_mkdir_on = AddMountPar(L"mkdir_on"); mount_par_app = AddMountPar(L"app"); mount_par_html_template = AddMountPar(L"html_template"); mount_par_change_template = AddMountPar(L"change_template"); mount_par_static = AddMountPar(L"static"); mount_par_css = AddMountPar(L"css"); mount_par_lang = AddMountPar(L"lang"); } void Mounts::CreateMounts() { CreateMountType(); CreateMountFs(); CreateMountPar(); plugin->Call((Session*)0, WINIX_ADD_MOUNTS); empty_mount.param.resize(mount_par_tab.size()); empty_mount.ClearParams(); } void Mounts::SetDirs(Dirs * pdirs) { dirs = pdirs; } void Mounts::SetDb(Db * pdb) { db = pdb; } void Mounts::SetCur(Cur * pcur) { cur = pcur; } int Mounts::AddMountType(const wchar_t * type) { mount_type_tab.push_back(type); return static_cast(mount_type_tab.size()) - 1; } int Mounts::AddMountType(const std::wstring & type) { return AddMountType(type.c_str()); } int Mounts::AddMountFs(const wchar_t * fs) { mount_fs_tab.push_back(fs); return static_cast(mount_fs_tab.size()) - 1; } const std::wstring & Mounts::GetMountType(int id) { if( id < 0 || id >= (int)mount_type_tab.size() ) return empty_str; return mount_type_tab[id]; } int Mounts::FindMountType(const std::wstring & type) { for(size_t i=0 ; i= (int)mount_fs_tab.size() ) return empty_str; return mount_fs_tab[id]; } int Mounts::AddMountPar(const wchar_t * par) { mount_par_tab.push_back(par); return static_cast(mount_par_tab.size()) - 1; } int Mounts::AddMountPar(const std::wstring & par) { return AddMountPar(par.c_str()); } const std::wstring & Mounts::GetMountPar(int id) { if( id < 0 || id >= (int)mount_par_tab.size() ) return empty_str; return mount_par_tab[id]; } // reading from 'mounts' void Mounts::ReadMounts(const std::wstring & mounts) { mount_parser.set_dependency(this); mount_parser.SkipStaticDirs(skip_static); mount_parser.SetStaticMountId(mount_type_static); mount_parser.SetDirs(dirs); mount_parser.SetMountTypeTab(mount_type_tab); mount_parser.SetMountFsTab(mount_fs_tab); mount_parser.SetMountParTab(mount_par_tab); mount_parser.Parse(mounts, mount_tab); CalcCurMount(); // IMPROVE ME // cur->mount is pointing to the empty mount (it is set in functions.cpp in CheckSpecialFile method) // may would be better to call WINIX_FSTAB_CHANGED after the cur->mount is set? // some plugins are using 'cur' object plugin->Call((Session*)0, WINIX_FSTAB_CHANGED); } // reading from /etc/fstab void Mounts::ReadMounts() { static std::wstring file = L"fstab"; Item * etc = dirs->GetEtcDir(); if( !etc ) { log << log1 << "M: there is no /etc directory" << logend; return; } morm::Finder finder(model_connector); Item fstab = finder.select().where().eq(L"parent_id", etc->id).eq(L"url", file).get(); // Error err = db->GetItem(etc->id, file, fstab); if( !fstab.found() ) { log << log1 << "M: there is no /etc/fstab file" << logend; return; } // if( err != WINIX_ERR_OK ) // { // log << log1 << "M: cannot read /etc/fstab" << logend; // return err; // } ReadMounts(fstab.item_content.content_raw); } void Mounts::MountCmsForRoot() { Mount mount; mount.type = MountTypeCms(); mount.fs = MountFsSimplefs(); 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; } mount.param.resize(mount_par_tab.size()); mount.ClearParams(); std::pair res = mount_tab.insert( std::make_pair(mount.dir_id, mount) ); pmount = &(res.first->second); } Mount * Mounts::CalcCurMount() { std::vector::reverse_iterator i; pmount = &empty_mount; // when the program starts (when the dir_tab is empty() // we don't want to call MountCmsForRoot() if( cur->request->dir_tab.empty() ) return pmount; for(i = cur->request->dir_tab.rbegin() ; i!=cur->request->dir_tab.rend() ; ++i) { std::map::iterator m = mount_tab.find( (*i)->id ); if( m != mount_tab.end() ) { pmount = &(m->second); log << log2 << "M: current mount point is: " << GetMountType(pmount->type) << ", fs: " << GetMountFs(pmount->fs) << logend; return pmount; } } // if nothing was found // we assume that 'cms' mount point is used MountCmsForRoot(); log << log2 << "M: current mount point is: " << GetMountType(pmount->type) << " (default)" << ", fs: " << GetMountFs(pmount->fs) << logend; return pmount; } // 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::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; } Mount * Mounts::GetEmptyMount() { return &empty_mount; } } // namespace Winix