413 lines
6.2 KiB
C++
Executable File
413 lines
6.2 KiB
C++
Executable File
/*
|
|
* This file is a part of Winix
|
|
* and is not publicly distributed
|
|
*
|
|
* Copyright (c) 2010, Tomasz Sowa
|
|
* All rights reserved.
|
|
*
|
|
*/
|
|
|
|
#include "mountparser.h"
|
|
#include "log.h"
|
|
#include "misc.h"
|
|
|
|
|
|
MountParser::MountParser()
|
|
{
|
|
dirs = 0;
|
|
mount_type_tab = 0;
|
|
mount_fs_tab = 0;
|
|
mount_par_tab = 0;
|
|
}
|
|
|
|
|
|
void MountParser::SetDirs(Dirs * pdirs)
|
|
{
|
|
dirs = pdirs;
|
|
}
|
|
|
|
|
|
void MountParser::SetMountTypeTab(const std::vector<std::wstring> & tab)
|
|
{
|
|
mount_type_tab = &tab;
|
|
}
|
|
|
|
|
|
void MountParser::SetMountFsTab(const std::vector<std::wstring> & tab)
|
|
{
|
|
mount_fs_tab = &tab;
|
|
}
|
|
|
|
|
|
void MountParser::SetMountParTab(const std::vector<std::wstring> & tab)
|
|
{
|
|
mount_par_tab = &tab;
|
|
}
|
|
|
|
|
|
|
|
bool MountParser::IsWhite(int c)
|
|
{
|
|
if( c==' ' || c=='\t' || c==13 || c==160 )
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
void MountParser::SkipWhite()
|
|
{
|
|
while( IsWhite(*pinput) )
|
|
++pinput;
|
|
}
|
|
|
|
|
|
void MountParser::SkipLine()
|
|
{
|
|
while( *pinput && *pinput != 10 )
|
|
++pinput;
|
|
|
|
if( *pinput == 10 )
|
|
++pinput;
|
|
}
|
|
|
|
|
|
void MountParser::ReadWordQuote(std::wstring & res)
|
|
{
|
|
++pinput;
|
|
|
|
while( *pinput && *pinput!=10 && *pinput!='\"' )
|
|
{
|
|
if( pinput[0]=='\\' && pinput[1]=='\"' )
|
|
{
|
|
res += '\"';
|
|
pinput += 2;
|
|
}
|
|
else
|
|
if( pinput[0]=='\\' && pinput[1]=='\\' )
|
|
{
|
|
res += '\\';
|
|
pinput += 2;
|
|
}
|
|
else
|
|
{
|
|
res += *pinput;
|
|
pinput += 1;
|
|
}
|
|
}
|
|
|
|
if( *pinput == '"' )
|
|
++pinput;
|
|
}
|
|
|
|
|
|
// a white character is the separator
|
|
void MountParser::ReadWordWhite(std::wstring & res)
|
|
{
|
|
while( *pinput && *pinput!=10 && !IsWhite(*pinput) )
|
|
{
|
|
res += *pinput;
|
|
++pinput;
|
|
}
|
|
}
|
|
|
|
|
|
// the comma or the second bracket ')' are the separators
|
|
void MountParser::ReadWordComma(std::wstring & res)
|
|
{
|
|
while( *pinput && *pinput!=10 && *pinput!=',' && *pinput!=')' )
|
|
{
|
|
res += *pinput;
|
|
++pinput;
|
|
}
|
|
|
|
// trimming last white characters
|
|
// (white characters can be in the middle of the string)
|
|
TrimWhite(res);
|
|
}
|
|
|
|
|
|
void MountParser::ReadWord(std::wstring & res, bool comma_bracket_separator)
|
|
{
|
|
res.clear();
|
|
SkipWhite();
|
|
|
|
if( *pinput == '"' )
|
|
{
|
|
ReadWordQuote(res);
|
|
}
|
|
else
|
|
if( comma_bracket_separator )
|
|
{
|
|
ReadWordComma(res);
|
|
}
|
|
else
|
|
{
|
|
ReadWordWhite(res);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void MountParser::ReadParamArgsLoop(Mount::ParamRow::ParamArg & args)
|
|
{
|
|
SkipWhite();
|
|
|
|
while( *pinput && *pinput!=10 && *pinput!=')' )
|
|
{
|
|
ReadWord(temp_arg, true);
|
|
|
|
if( !temp_arg.empty() )
|
|
args.push_back(temp_arg);
|
|
|
|
if( *pinput == ',' )
|
|
++pinput;
|
|
}
|
|
}
|
|
|
|
|
|
void MountParser::ReadParamArgs(Mount::ParamRow::ParamArg & args)
|
|
{
|
|
SkipWhite();
|
|
args.clear();
|
|
|
|
|
|
if( *pinput == '(' )
|
|
{
|
|
++pinput;
|
|
ReadParamArgsLoop(args);
|
|
|
|
if( *pinput != ')' )
|
|
{
|
|
// there should be ')' at the end
|
|
// temporarily we do nothing
|
|
}
|
|
else
|
|
{
|
|
++pinput;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void MountParser::ReadParamName(std::wstring & res)
|
|
{
|
|
SkipWhite();
|
|
res.clear();
|
|
|
|
while( *pinput && *pinput!=10 && *pinput!=',' && *pinput!='(' && !IsWhite(*pinput) )
|
|
{
|
|
res += *pinput;
|
|
++pinput;
|
|
}
|
|
}
|
|
|
|
|
|
void MountParser::ReadParam(std::wstring & res, Mount::ParamRow::ParamArg & args)
|
|
{
|
|
ReadParamName(res);
|
|
|
|
if( res.empty() )
|
|
return;
|
|
|
|
ReadParamArgs(args);
|
|
|
|
SkipWhite();
|
|
|
|
if( *pinput == ',' )
|
|
++pinput;
|
|
}
|
|
|
|
|
|
int MountParser::FindIndex(const std::vector<std::wstring> * tab, const std::wstring & value)
|
|
{
|
|
for(size_t i=0 ; i < tab->size() ; ++i)
|
|
{
|
|
if( (*tab)[i] == value )
|
|
return static_cast<int>(i);
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
void MountParser::ReadMountType()
|
|
{
|
|
ReadWord(temp);
|
|
|
|
if( temp.empty() )
|
|
{
|
|
// an empty line (some white characters only)
|
|
err = WINIX_ERR_EMPTY;
|
|
return;
|
|
}
|
|
|
|
mount.type = FindIndex(mount_type_tab, temp);
|
|
|
|
if( mount.type != -1 )
|
|
{
|
|
log << log3 << "MP: mount type: " << (*mount_type_tab)[mount.type] << logend;
|
|
}
|
|
else
|
|
{
|
|
err = WINIX_ERR_MOUNT_UNKNOWN;
|
|
log << log1 << "MP: unknown mount type: " << temp << logend;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void MountParser::ReadMountPoint()
|
|
{
|
|
ReadWord(temp);
|
|
|
|
pdir = dirs->GetDir(temp);
|
|
|
|
if( pdir )
|
|
{
|
|
mount.dir_id = pdir->id;
|
|
log << log3 << "MP: mount point (directory): " << temp << logend;
|
|
}
|
|
else
|
|
{
|
|
err = WINIX_ERR_NO_MOUNTPOINT;
|
|
log << log1 << "MP: there is no such a mount point (directory): " << temp << logend;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void MountParser::ReadFs()
|
|
{
|
|
ReadWord(temp);
|
|
mount.fs = FindIndex(mount_fs_tab, temp);
|
|
|
|
if( mount.fs != -1 )
|
|
{
|
|
log << log2 << "MP: file system: " << (*mount_fs_tab)[mount.fs] << logend;
|
|
}
|
|
else
|
|
{
|
|
err = WINIX_ERR_UNKNOWN_FILESYSTEM;
|
|
log << log1 << "MP: unknown filesystem: " << temp << logend;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void MountParser::LogMountParams()
|
|
{
|
|
size_t i;
|
|
|
|
log << log3 << "MP: mount param: " << temp << "(";
|
|
|
|
for(i=0 ; i<param_args.size() ; ++i)
|
|
{
|
|
log << param_args[i];
|
|
|
|
if( i != param_args.size()-1 )
|
|
log << ",";
|
|
}
|
|
|
|
log << ")" << logend;
|
|
}
|
|
|
|
|
|
|
|
void MountParser::ReadMountParams()
|
|
{
|
|
mount.ClearParams();
|
|
|
|
for( ReadParam(temp, param_args) ; !temp.empty() ; ReadParam(temp, param_args) )
|
|
{
|
|
int code = FindIndex(mount_par_tab, temp);
|
|
|
|
if( code != -1 )
|
|
{
|
|
mount.param[code].defined = true;
|
|
mount.param[code].arg = param_args;
|
|
LogMountParams();
|
|
}
|
|
else
|
|
{
|
|
log << log1 << "MP: unknown mount param: " << temp << " (skipped)" << logend;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void MountParser::ReadRow(std::map<long, Mount> & output)
|
|
{
|
|
ReadMountType();
|
|
|
|
if( err == WINIX_ERR_EMPTY )
|
|
{
|
|
err = WINIX_ERR_OK;
|
|
SkipLine();
|
|
return;
|
|
}
|
|
|
|
if( err == WINIX_ERR_OK )
|
|
ReadMountPoint();
|
|
|
|
if( err == WINIX_ERR_OK )
|
|
ReadFs();
|
|
|
|
if( err == WINIX_ERR_OK )
|
|
ReadMountParams();
|
|
|
|
if( err == WINIX_ERR_OK )
|
|
{
|
|
std::pair<std::map<long, Mount>::iterator, bool> res = output.insert( std::make_pair(mount.dir_id, mount) );
|
|
|
|
if( !res.second )
|
|
log << log1 << "MP: this mount point exists (skipped)" << logend;
|
|
}
|
|
|
|
SkipLine();
|
|
}
|
|
|
|
|
|
|
|
|
|
Error MountParser::Parse(const std::wstring & input, std::map<long, Mount> & output)
|
|
{
|
|
if( !dirs || !mount_type_tab || !mount_fs_tab || !mount_par_tab )
|
|
{
|
|
log << log1 << "pdir: " << pdir << logend;
|
|
log << log1 << "type: " << mount_type_tab << logend;
|
|
log << log1 << "fs: " << mount_fs_tab << logend;
|
|
log << log1 << "par: " << mount_par_tab << logend;
|
|
|
|
log << log1 << "MP: input tables not set" << logend;
|
|
return WINIX_NOTHING_TO_DO; // !! may a better code?
|
|
}
|
|
|
|
pinput = input.c_str();
|
|
err = WINIX_ERR_OK;
|
|
|
|
mount.param.resize(mount_par_tab->size());
|
|
mount.ClearParams();
|
|
|
|
output.clear();
|
|
|
|
while( *pinput && err == WINIX_ERR_OK )
|
|
ReadRow(output);
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|