replace file_set_contents with replace_file
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
		@ -12,7 +12,8 @@ use proxmox::api::{http_err, list_subdirs_api_method};
 | 
				
			|||||||
use proxmox::api::{ApiResponseFuture, ApiHandler, ApiMethod, Router, RpcEnvironment, RpcEnvironmentType};
 | 
					use proxmox::api::{ApiResponseFuture, ApiHandler, ApiMethod, Router, RpcEnvironment, RpcEnvironmentType};
 | 
				
			||||||
use proxmox::api::router::SubdirMap;
 | 
					use proxmox::api::router::SubdirMap;
 | 
				
			||||||
use proxmox::api::schema::*;
 | 
					use proxmox::api::schema::*;
 | 
				
			||||||
use proxmox::tools::{try_block, fs::file_get_contents, fs::file_set_contents};
 | 
					use proxmox::tools::try_block;
 | 
				
			||||||
 | 
					use proxmox::tools::fs::{file_get_contents, replace_file, CreateOptions};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::api2::types::*;
 | 
					use crate::api2::types::*;
 | 
				
			||||||
use crate::backup::*;
 | 
					use crate::backup::*;
 | 
				
			||||||
@ -583,7 +584,7 @@ fn upload_backup_log(
 | 
				
			|||||||
        // always verify CRC at server side
 | 
					        // always verify CRC at server side
 | 
				
			||||||
        blob.verify_crc()?;
 | 
					        blob.verify_crc()?;
 | 
				
			||||||
        let raw_data = blob.raw_data();
 | 
					        let raw_data = blob.raw_data();
 | 
				
			||||||
        file_set_contents(&path, raw_data, None)?;
 | 
					        replace_file(&path, raw_data, CreateOptions::new())?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // fixme: use correct formatter
 | 
					        // fixme: use correct formatter
 | 
				
			||||||
        Ok(crate::server::formatter::json_response(Ok(Value::Null)))
 | 
					        Ok(crate::server::formatter::json_response(Ok(Value::Null)))
 | 
				
			||||||
 | 
				
			|||||||
@ -4,10 +4,8 @@ use std::collections::HashMap;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use serde_json::Value;
 | 
					use serde_json::Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use proxmox::tools::{
 | 
					use proxmox::tools::digest_to_hex;
 | 
				
			||||||
    digest_to_hex,
 | 
					use proxmox::tools::fs::{replace_file, CreateOptions};
 | 
				
			||||||
    fs::file_set_contents,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
use proxmox::api::{RpcEnvironment, RpcEnvironmentType};
 | 
					use proxmox::api::{RpcEnvironment, RpcEnvironmentType};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::server::WorkerTask;
 | 
					use crate::server::WorkerTask;
 | 
				
			||||||
@ -415,7 +413,7 @@ impl BackupEnvironment {
 | 
				
			|||||||
        blob.verify_crc()?;
 | 
					        blob.verify_crc()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let raw_data = blob.raw_data();
 | 
					        let raw_data = blob.raw_data();
 | 
				
			||||||
        file_set_contents(&path, raw_data, None)?;
 | 
					        replace_file(&path, raw_data, CreateOptions::new())?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.log(format!("add blob {:?} ({} bytes, comp: {})", path, orig_len, blob_len));
 | 
					        self.log(format!("add blob {:?} ({} bytes, comp: {})", path, orig_len, blob_len));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -9,7 +9,7 @@ use serde_json::{json, Value};
 | 
				
			|||||||
use proxmox::{sortable, identity};
 | 
					use proxmox::{sortable, identity};
 | 
				
			||||||
use proxmox::api::{ApiHandler, ApiMethod, Router, RpcEnvironment};
 | 
					use proxmox::api::{ApiHandler, ApiMethod, Router, RpcEnvironment};
 | 
				
			||||||
use proxmox::api::schema::*;
 | 
					use proxmox::api::schema::*;
 | 
				
			||||||
use proxmox::tools::fs::{file_get_contents, file_set_contents};
 | 
					use proxmox::tools::fs::{file_get_contents, replace_file, CreateOptions};
 | 
				
			||||||
use proxmox::tools::*; // required to use IPRE!() macro ???
 | 
					use proxmox::tools::*; // required to use IPRE!() macro ???
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::api2::types::*;
 | 
					use crate::api2::types::*;
 | 
				
			||||||
@ -91,7 +91,7 @@ fn update_dns(
 | 
				
			|||||||
        data.push('\n');
 | 
					        data.push('\n');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    file_set_contents(RESOLV_CONF_FN, data.as_bytes(), None)?;
 | 
					    replace_file(RESOLV_CONF_FN, data.as_bytes(), CreateOptions::new())?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(Value::Null)
 | 
					    Ok(Value::Null)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,7 @@ use serde_json::{json, Value};
 | 
				
			|||||||
use proxmox::{sortable, identity};
 | 
					use proxmox::{sortable, identity};
 | 
				
			||||||
use proxmox::api::{ApiHandler, ApiMethod, Router, RpcEnvironment};
 | 
					use proxmox::api::{ApiHandler, ApiMethod, Router, RpcEnvironment};
 | 
				
			||||||
use proxmox::api::schema::*;
 | 
					use proxmox::api::schema::*;
 | 
				
			||||||
use proxmox::tools::fs::{file_read_firstline, file_set_contents};
 | 
					use proxmox::tools::fs::{file_read_firstline, replace_file, CreateOptions};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::api2::types::*;
 | 
					use crate::api2::types::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -71,7 +71,7 @@ fn set_timezone(
 | 
				
			|||||||
        bail!("No such timezone.");
 | 
					        bail!("No such timezone.");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    file_set_contents("/etc/timezone", timezone.as_bytes(), None)?;
 | 
					    replace_file("/etc/timezone", timezone.as_bytes(), CreateOptions::new())?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let _ = std::fs::remove_file("/etc/localtime");
 | 
					    let _ = std::fs::remove_file("/etc/localtime");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -9,7 +9,7 @@ use std::path::PathBuf;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use proxmox::tools::{
 | 
					use proxmox::tools::{
 | 
				
			||||||
    try_block,
 | 
					    try_block,
 | 
				
			||||||
    fs::{file_get_contents, file_set_contents, file_set_contents_full},
 | 
					    fs::{file_get_contents, replace_file, CreateOptions},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn compute_csrf_secret_digest(
 | 
					fn compute_csrf_secret_digest(
 | 
				
			||||||
@ -98,11 +98,15 @@ pub fn generate_csrf_key() -> Result<(), Error> {
 | 
				
			|||||||
    use nix::sys::stat::Mode;
 | 
					    use nix::sys::stat::Mode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let (_, backup_gid) = crate::tools::getpwnam_ugid("backup")?;
 | 
					    let (_, backup_gid) = crate::tools::getpwnam_ugid("backup")?;
 | 
				
			||||||
    let uid = Some(nix::unistd::ROOT);
 | 
					 | 
				
			||||||
    let gid = Some(nix::unistd::Gid::from_raw(backup_gid));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    file_set_contents_full(
 | 
					    replace_file(
 | 
				
			||||||
        &path, &pem, Some(Mode::from_bits_truncate(0o0640)), uid, gid)?;
 | 
					        &path,
 | 
				
			||||||
 | 
					        &pem,
 | 
				
			||||||
 | 
					        CreateOptions::new()
 | 
				
			||||||
 | 
					            .perm(Mode::from_bits_truncate(0o0640))
 | 
				
			||||||
 | 
					            .owner(nix::unistd::ROOT)
 | 
				
			||||||
 | 
					            .group(nix::unistd::Gid::from_raw(backup_gid)),
 | 
				
			||||||
 | 
					    )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -122,18 +126,21 @@ pub fn generate_auth_key() -> Result<(), Error> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    use nix::sys::stat::Mode;
 | 
					    use nix::sys::stat::Mode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    file_set_contents(
 | 
					    replace_file(
 | 
				
			||||||
        &priv_path, &priv_pem, Some(Mode::from_bits_truncate(0o0600)))?;
 | 
					        &priv_path, &priv_pem, CreateOptions::new().perm(Mode::from_bits_truncate(0o0600)))?;
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let public_pem = rsa.public_key_to_pem()?;
 | 
					    let public_pem = rsa.public_key_to_pem()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let (_, backup_gid) = crate::tools::getpwnam_ugid("backup")?;
 | 
					    let (_, backup_gid) = crate::tools::getpwnam_ugid("backup")?;
 | 
				
			||||||
    let uid = Some(nix::unistd::ROOT);
 | 
					 | 
				
			||||||
    let gid = Some(nix::unistd::Gid::from_raw(backup_gid));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    file_set_contents_full(
 | 
					    replace_file(
 | 
				
			||||||
        &public_path, &public_pem, Some(Mode::from_bits_truncate(0o0640)), uid, gid)?;
 | 
					        &public_path,
 | 
				
			||||||
 | 
					        &public_pem,
 | 
				
			||||||
 | 
					        CreateOptions::new()
 | 
				
			||||||
 | 
					            .perm(Mode::from_bits_truncate(0o0640))
 | 
				
			||||||
 | 
					            .owner(nix::unistd::ROOT)
 | 
				
			||||||
 | 
					            .group(nix::unistd::Gid::from_raw(backup_gid)),
 | 
				
			||||||
 | 
					    )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,7 @@ use chrono::{Local, TimeZone, DateTime};
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use proxmox::tools::{
 | 
					use proxmox::tools::{
 | 
				
			||||||
    try_block,
 | 
					    try_block,
 | 
				
			||||||
    fs::{file_get_contents, file_set_contents},
 | 
					    fs::{file_get_contents, replace_file, CreateOptions},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Deserialize, Serialize, Debug)]
 | 
					#[derive(Deserialize, Serialize, Debug)]
 | 
				
			||||||
@ -84,7 +84,7 @@ pub fn store_key_config(
 | 
				
			|||||||
    try_block!({
 | 
					    try_block!({
 | 
				
			||||||
        if replace {
 | 
					        if replace {
 | 
				
			||||||
            let mode = nix::sys::stat::Mode::S_IRUSR | nix::sys::stat::Mode::S_IWUSR;
 | 
					            let mode = nix::sys::stat::Mode::S_IRUSR | nix::sys::stat::Mode::S_IWUSR;
 | 
				
			||||||
            file_set_contents(&path, data.as_bytes(), Some(mode))?;
 | 
					            replace_file(&path, data.as_bytes(), CreateOptions::new().perm(mode))?;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            use std::os::unix::fs::OpenOptionsExt;
 | 
					            use std::os::unix::fs::OpenOptionsExt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -9,7 +9,7 @@ use std::io::{Write, Seek, SeekFrom};
 | 
				
			|||||||
use std::os::unix::fs::OpenOptionsExt;
 | 
					use std::os::unix::fs::OpenOptionsExt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use proxmox::{sortable, identity};
 | 
					use proxmox::{sortable, identity};
 | 
				
			||||||
use proxmox::tools::fs::{file_get_contents, file_get_json, file_set_contents, image_size};
 | 
					use proxmox::tools::fs::{file_get_contents, file_get_json, replace_file, CreateOptions, image_size};
 | 
				
			||||||
use proxmox::api::{ApiHandler, ApiMethod, RpcEnvironment};
 | 
					use proxmox::api::{ApiHandler, ApiMethod, RpcEnvironment};
 | 
				
			||||||
use proxmox::api::schema::*;
 | 
					use proxmox::api::schema::*;
 | 
				
			||||||
use proxmox::api::cli::*;
 | 
					use proxmox::api::cli::*;
 | 
				
			||||||
@ -134,7 +134,7 @@ fn record_repository(repo: &BackupRepository) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    let new_data = json!(map);
 | 
					    let new_data = json!(map);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let _ = file_set_contents(path, new_data.to_string().as_bytes(), None);
 | 
					    let _ = replace_file(path, new_data.to_string().as_bytes(), CreateOptions::new());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn complete_repository(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
 | 
					fn complete_repository(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
 | 
				
			||||||
@ -1181,7 +1181,7 @@ async fn restore(param: Value) -> Result<Value, Error> {
 | 
				
			|||||||
    if server_archive_name == MANIFEST_BLOB_NAME {
 | 
					    if server_archive_name == MANIFEST_BLOB_NAME {
 | 
				
			||||||
        let backup_index_data = manifest.into_json().to_string();
 | 
					        let backup_index_data = manifest.into_json().to_string();
 | 
				
			||||||
        if let Some(target) = target {
 | 
					        if let Some(target) = target {
 | 
				
			||||||
            file_set_contents(target, backup_index_data.as_bytes(), None)?;
 | 
					            replace_file(target, backup_index_data.as_bytes(), CreateOptions::new())?;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            let stdout = std::io::stdout();
 | 
					            let stdout = std::io::stdout();
 | 
				
			||||||
            let mut writer = stdout.lock();
 | 
					            let mut writer = stdout.lock();
 | 
				
			||||||
@ -1701,7 +1701,7 @@ fn key_import_master_pubkey(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    let target_path = master_pubkey_path()?;
 | 
					    let target_path = master_pubkey_path()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    file_set_contents(&target_path, &pem_data, None)?;
 | 
					    replace_file(&target_path, &pem_data, CreateOptions::new())?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    println!("Imported public master key to {:?}", target_path);
 | 
					    println!("Imported public master key to {:?}", target_path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1736,14 +1736,14 @@ fn key_create_master_key(
 | 
				
			|||||||
    let pub_key: Vec<u8> = pkey.public_key_to_pem()?;
 | 
					    let pub_key: Vec<u8> = pkey.public_key_to_pem()?;
 | 
				
			||||||
    let filename_pub = "master-public.pem";
 | 
					    let filename_pub = "master-public.pem";
 | 
				
			||||||
    println!("Writing public master key to {}", filename_pub);
 | 
					    println!("Writing public master key to {}", filename_pub);
 | 
				
			||||||
    file_set_contents(filename_pub, pub_key.as_slice(), None)?;
 | 
					    replace_file(filename_pub, pub_key.as_slice(), CreateOptions::new())?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let cipher = openssl::symm::Cipher::aes_256_cbc();
 | 
					    let cipher = openssl::symm::Cipher::aes_256_cbc();
 | 
				
			||||||
    let priv_key: Vec<u8> = pkey.private_key_to_pem_pkcs8_passphrase(cipher, new_pw.as_bytes())?;
 | 
					    let priv_key: Vec<u8> = pkey.private_key_to_pem_pkcs8_passphrase(cipher, new_pw.as_bytes())?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let filename_priv = "master-private.pem";
 | 
					    let filename_priv = "master-private.pem";
 | 
				
			||||||
    println!("Writing private master key to {}", filename_priv);
 | 
					    println!("Writing private master key to {}", filename_priv);
 | 
				
			||||||
    file_set_contents(filename_priv, priv_key.as_slice(), None)?;
 | 
					    replace_file(filename_priv, priv_key.as_slice(), CreateOptions::new())?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(Value::Null)
 | 
					    Ok(Value::Null)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,7 @@ use percent_encoding::percent_encode;
 | 
				
			|||||||
use xdg::BaseDirectories;
 | 
					use xdg::BaseDirectories;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use proxmox::tools::{
 | 
					use proxmox::tools::{
 | 
				
			||||||
    fs::{file_get_json, file_set_contents},
 | 
					    fs::{file_get_json, replace_file, CreateOptions},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use super::pipe_to_stream::PipeToSendStream;
 | 
					use super::pipe_to_stream::PipeToSendStream;
 | 
				
			||||||
@ -52,7 +52,7 @@ pub fn delete_ticket_info(server: &str, username: &str) -> Result<(), Error> {
 | 
				
			|||||||
        map.remove(username);
 | 
					        map.remove(username);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    file_set_contents(path, data.to_string().as_bytes(), Some(mode))?;
 | 
					    replace_file(path, data.to_string().as_bytes(), CreateOptions::new().perm(mode))?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -88,7 +88,7 @@ fn store_ticket_info(server: &str, username: &str, ticket: &str, token: &str) ->
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    file_set_contents(path, new_data.to_string().as_bytes(), Some(mode))?;
 | 
					    replace_file(path, new_data.to_string().as_bytes(), CreateOptions::new().perm(mode))?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,7 @@ use serde_json::{json, Value};
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use proxmox::tools::{
 | 
					use proxmox::tools::{
 | 
				
			||||||
    try_block,
 | 
					    try_block,
 | 
				
			||||||
    fs::{create_path, file_set_contents_full, CreateOptions},
 | 
					    fs::{create_path, replace_file, CreateOptions},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use super::UPID;
 | 
					use super::UPID;
 | 
				
			||||||
@ -202,11 +202,11 @@ pub struct TaskListInfo {
 | 
				
			|||||||
fn update_active_workers(new_upid: Option<&UPID>) -> Result<Vec<TaskListInfo>, Error> {
 | 
					fn update_active_workers(new_upid: Option<&UPID>) -> Result<Vec<TaskListInfo>, Error> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let (backup_uid, backup_gid) = crate::tools::getpwnam_ugid("backup")?;
 | 
					    let (backup_uid, backup_gid) = crate::tools::getpwnam_ugid("backup")?;
 | 
				
			||||||
    let uid = Some(nix::unistd::Uid::from_raw(backup_uid));
 | 
					    let uid = nix::unistd::Uid::from_raw(backup_uid);
 | 
				
			||||||
    let gid = Some(nix::unistd::Gid::from_raw(backup_gid));
 | 
					    let gid = nix::unistd::Gid::from_raw(backup_gid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let lock = crate::tools::open_file_locked(PROXMOX_BACKUP_TASK_LOCK_FN, std::time::Duration::new(10, 0))?;
 | 
					    let lock = crate::tools::open_file_locked(PROXMOX_BACKUP_TASK_LOCK_FN, std::time::Duration::new(10, 0))?;
 | 
				
			||||||
    nix::unistd::chown(PROXMOX_BACKUP_TASK_LOCK_FN, uid, gid)?;
 | 
					    nix::unistd::chown(PROXMOX_BACKUP_TASK_LOCK_FN, Some(uid), Some(gid))?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let reader = match File::open(PROXMOX_BACKUP_ACTIVE_TASK_FN) {
 | 
					    let reader = match File::open(PROXMOX_BACKUP_ACTIVE_TASK_FN) {
 | 
				
			||||||
        Ok(f) => Some(BufReader::new(f)),
 | 
					        Ok(f) => Some(BufReader::new(f)),
 | 
				
			||||||
@ -301,7 +301,13 @@ fn update_active_workers(new_upid: Option<&UPID>) -> Result<Vec<TaskListInfo>, E
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    file_set_contents_full(PROXMOX_BACKUP_ACTIVE_TASK_FN, raw.as_bytes(), None, uid, gid)?;
 | 
					    replace_file(
 | 
				
			||||||
 | 
					        PROXMOX_BACKUP_ACTIVE_TASK_FN,
 | 
				
			||||||
 | 
					        raw.as_bytes(),
 | 
				
			||||||
 | 
					        CreateOptions::new()
 | 
				
			||||||
 | 
					            .owner(uid)
 | 
				
			||||||
 | 
					            .group(gid),
 | 
				
			||||||
 | 
					    )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    drop(lock);
 | 
					    drop(lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user