/* * Copyright (c) 2021, Luca Fulchir * * This file is part of dfim. * * dfim is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * dfim is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with dfim. If not, see . */ pub mod cfg; pub mod s_trgt; use super::config; use ::std::io::Read; use ::std::io::Seek; /// Check if a device is empty. Meaning: no gpt/mbr, first and last MB all zeros pub fn is_empty(dev: &::udev::Device) -> Result { // MBR/GPT have headers in the first/last MB, // so checking those will guarantee us that there is no MBR/GPT let mut device = ::std::fs::File::open(dev.syspath())?; // 1MB buffer let mut buffer = Vec::::with_capacity(1024 * 1024); unsafe { buffer.set_len(buffer.capacity()) } let bytes = device.read(&mut buffer[..])?; if buffer[..bytes].iter().any(|&x| x != 0) { return Ok(false); } // check the end of file device.seek(::std::io::SeekFrom::End(0))?; let max_size = device.stream_position()?; if max_size > 1024 * 1024 { // else we have already checked it let to_end = ::std::cmp::max(max_size - 1024 * 1024, 1024 * 1024); device.seek(::std::io::SeekFrom::Start(to_end))?; let bytes = device.read(&mut buffer[..])?; if buffer[..bytes].iter().any(|&x| x != 0) { return Ok(false); } } Ok(true) } pub fn get( logger: &::slog::Logger, cfg: &cfg::Cfg, cfg_dev: &config::device::Device, cfg_target: &config::trgt::Target, dev: &::udev::Device, ) -> Result { // analyze a device, get the partition table and filesystem // to check if the current state and the destination coincide // // returns the target and its udev syspath for any children to be checked use crate::state::s_trgt::TargetApply; let mut check_target: s_trgt::Target = cfg_target.into(); let res = check_target.check(logger, cfg, cfg_dev, dev); // TODO: check recursively Ok(s_trgt::CheckStatus::DoNotApply) } pub fn set( logger: &::slog::Logger, cfg: &cfg::Cfg, cfg_dev: &config::device::Device, cfg_target: &config::trgt::Target, dev: &::udev::Device, ) -> Result<(), ::std::io::Error> { use crate::state::s_trgt::TargetApply; let mut apply_target: s_trgt::Target = cfg_target.into(); apply_target.apply(logger, cfg, cfg_dev, dev)?; Ok(()) }