Compare commits

...

17 commits

Author SHA1 Message Date
5799216ea4 feat(home): Setup mu4e 2025-11-25 14:26:48 +01:00
3885f59083 chore: Update inputs 2025-11-25 14:24:48 +01:00
f1c0789571 feat(emacs): Add support packages to denote 2025-11-25 14:24:48 +01:00
c4ce3cf246 feat(docs): Enable Tika support for paperless 2025-11-25 14:24:48 +01:00
0d59442168 chore: Update inputs 2025-11-25 14:24:48 +01:00
65b164997a home(alex): configure zsh 2025-11-25 14:24:48 +01:00
53efeef9c4 home(alex): fix tramp connection 2025-11-25 14:24:48 +01:00
8c684af604 emacs: do not pin transient package 2025-11-25 14:24:48 +01:00
370d124efc home(alex): do not provide .config/doom 2025-11-25 14:24:48 +01:00
9d0eba39ba home(alex): enable ssh master control 2025-11-25 14:24:48 +01:00
f0707aacdd home(alex): enable gnome paperwm extension 2025-11-25 14:24:48 +01:00
0f31a3e560 modules(wm): disable XFCE desktop environment 2025-11-25 14:24:48 +01:00
49b169f473 chore: Update inputs 2025-11-25 14:24:48 +01:00
efa99d6331 dregil: Use gnome for now by default 2025-11-25 14:24:48 +01:00
2e7fa6eb14 chore: Update inputs 2025-11-25 14:24:48 +01:00
57a942b525 feat(home): Enable signal desktop 2025-11-25 14:24:48 +01:00
853d6aaa17 feat(home): Fix mu4e setup 2025-11-25 14:24:48 +01:00
19 changed files with 379 additions and 139 deletions

134
flake.lock generated
View file

@ -10,11 +10,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1745630506,
"narHash": "sha256-bHCFgGeu8XjWlVuaWzi3QONjDW3coZDqSHvnd4l7xus=",
"lastModified": 1762618334,
"narHash": "sha256-wyT7Pl6tMFbFrs8Lk/TlEs81N6L+VSybPfiIgzU8lbQ=",
"owner": "ryantm",
"repo": "agenix",
"rev": "96e078c646b711aee04b82ba01aefbff87004ded",
"rev": "fcdea223397448d35d9b31f798479227e80183f6",
"type": "github"
},
"original": {
@ -68,11 +68,11 @@
]
},
"locked": {
"lastModified": 1746695594,
"narHash": "sha256-pAAWYs3S+/tY65vemHZdVSXpeIz4JINEJZoPoBjr8JU=",
"lastModified": 1763651264,
"narHash": "sha256-8vvwZbw0s7YvBMJeyPVpWke6lg6ROgtts5N2/SMCcv4=",
"owner": "nix-community",
"repo": "disko",
"rev": "6bb82b77ce140137177e30df067759931ab60a73",
"rev": "e86a89079587497174ccab6d0d142a65811a4fd9",
"type": "github"
},
"original": {
@ -105,11 +105,11 @@
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"lastModified": 1747046372,
"narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885",
"type": "github"
},
"original": {
@ -121,11 +121,11 @@
"flake-compat_2": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"lastModified": 1761588595,
"narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5",
"type": "github"
},
"original": {
@ -152,6 +152,32 @@
"type": "github"
}
},
"git-hooks": {
"inputs": {
"flake-compat": [
"snm",
"flake-compat"
],
"gitignore": "gitignore_2",
"nixpkgs": [
"snm",
"nixpkgs"
]
},
"locked": {
"lastModified": 1763319842,
"narHash": "sha256-YG19IyrTdnVn0l3DvcUYm85u3PaqBt6tI6VvolcuHnA=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "7275fa67fbbb75891c16d9dee7d88e58aea2d761",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
@ -173,6 +199,28 @@
"type": "github"
}
},
"gitignore_2": {
"inputs": {
"nixpkgs": [
"snm",
"git-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
@ -201,11 +249,11 @@
]
},
"locked": {
"lastModified": 1746719124,
"narHash": "sha256-KOL73WIjO00ds1oIe+5HAcGcpd/TfE6dymmmYbiSlYM=",
"lastModified": 1763906693,
"narHash": "sha256-inm7paa3myo8gE4TzjM8OPvsEg8xocWreIZBgBPEKgo=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "3c59c5132b64e885faca381e713b579dcbddba75",
"rev": "3d6c1c8fa0bea3a1a7ba23d6fa5993116766073b",
"type": "github"
},
"original": {
@ -286,11 +334,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1746461020,
"narHash": "sha256-7+pG1I9jvxNlmln4YgnlW4o+w0TZX24k688mibiFDUE=",
"lastModified": 1763678758,
"narHash": "sha256-+hBiJ+kG5IoffUOdlANKFflTT5nO3FrrR2CA3178Y5s=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "3730d8a308f94996a9ba7c7138ede69c1b9ac4ae",
"rev": "117cc7f94e8072499b0a7aa4c52084fa4e11cc9b",
"type": "github"
},
"original": {
@ -300,21 +348,6 @@
"type": "github"
}
},
"nixpkgs-24_11": {
"locked": {
"lastModified": 1734083684,
"narHash": "sha256-5fNndbndxSx5d+C/D0p/VF32xDiJCJzyOqorOYW4JEo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "314e12ba369ccdb9b352a4db26ff419f7c49fa84",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-24.11",
"type": "indirect"
}
},
"nixpkgs-docs": {
"locked": {
"lastModified": 1705957679,
@ -365,17 +398,18 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1732014248,
"narHash": "sha256-y/MEyuJ5oBWrWAic/14LaIr/u5E0wRVzyYsouYY3W6w=",
"lastModified": 1763553727,
"narHash": "sha256-4aRqRkYHplWk0mrtoF5i3Uo73E3niOWiUZU8kmPm9hQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "23e89b7da85c3640bbc2173fe04f4bd114342367",
"rev": "094318ea16502a7a81ce90dd3638697020f030a2",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-unstable",
"type": "indirect"
"owner": "NixOS",
"ref": "nixos-unstable-small",
"repo": "nixpkgs",
"type": "github"
}
},
"nmd": {
@ -441,11 +475,11 @@
]
},
"locked": {
"lastModified": 1746537231,
"narHash": "sha256-Wb2xeSyOsCoTCTj7LOoD6cdKLEROyFAArnYoS+noCWo=",
"lastModified": 1763741496,
"narHash": "sha256-uIRqs/H18YEtMOn1OkbnPH+aNTwXKx+iU3qnxEkVUd0=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "fa466640195d38ec97cf0493d6d6882bc4d14969",
"rev": "20e71a403c5de9ce5bd799031440da9728c1cda1",
"type": "github"
},
"original": {
@ -488,15 +522,15 @@
"inputs": {
"blobs": "blobs",
"flake-compat": "flake-compat_2",
"nixpkgs": "nixpkgs_2",
"nixpkgs-24_11": "nixpkgs-24_11"
"git-hooks": "git-hooks",
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1746637515,
"narHash": "sha256-bUq2uHmsfY3SpJrR4dpncITykufTiD2320JsOKgIYl0=",
"lastModified": 1763564778,
"narHash": "sha256-HSWMOylEaTtVgzIjpTbjcjVLXHDwNyV081eVUBfAcMs=",
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"rev": "a7d2b05a9920d90f5eb8076f449acdb6c1ad79ca",
"rev": "4987d275a90392347f84923cd4cd8efcf0aa7a22",
"type": "gitlab"
},
"original": {
@ -508,11 +542,11 @@
},
"stable": {
"locked": {
"lastModified": 1746557022,
"narHash": "sha256-QkNoyEf6TbaTW5UZYX0OkwIJ/ZMeKSSoOMnSDPQuol0=",
"lastModified": 1751274312,
"narHash": "sha256-/bVBlRpECLVzjV19t5KMdMFWSwKLtb5RyXdjz3LJT+g=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "1d3aeb5a193b9ff13f63f4d9cc169fb88129f860",
"rev": "50ab793786d9de88ee30ec4e4c24fb4236fc2674",
"type": "github"
},
"original": {

View file

@ -28,16 +28,6 @@
inputs.nixpkgs.follows = "nixpkgs-droid";
};
# emacs = {
# url = "github:nix-community/emacs-overlay";
# inputs.nixpkgs.follows = "nixpkgs";
# };
#
# simplex-chat = {
# url = "github:simplex-chat/simplex-chat";
# inputs.nixpkgs.follows = "nixpkgs";
# };
# age for nix to store encrypted passwords conveniently
agenix = {
url = "github:ryantm/agenix";
@ -129,6 +119,10 @@
modules = [ ./hosts/igor ];
};
homeConfigurations."alex@dregil" = home-manager.lib.homeManagerConfiguration {
};
nixOnDroidConfigurations.default =
with inputs;
nix-on-droid.lib.nixOnDroidConfiguration {

View file

@ -186,7 +186,16 @@ in
};
};
ssh.enable = true;
ssh = {
enable = true;
enableDefaultConfig = false;
matchBlocks = {
"*" = {
controlMaster = "auto";
controlPersist = "10m";
};
};
};
texlive.enable = true;
};

View file

@ -5,9 +5,6 @@
inputs,
...
}:
let
electron-overlay = final: prev: { electron = final.electron_25; };
in
{
imports = [ ];

View file

@ -9,19 +9,19 @@
imports = [
./cli.nix
./programs/rofi
./programs/xmonad
#./programs/i3
# ./programs/xmonad
# ./programs/i3
./programs/jitsi-meet
./programs/simplex-chat
./programs/zathura
./programs/autorandr
./services/polybar
./services/dunst
./services/udiskie
# ./services/polybar
# ./services/dunst
# ./services/udiskie
# ./services/picom
./services/screen-locker
./services/blueman-applet
./services/network-manager
# ./services/screen-locker
# ./services/blueman-applet
# ./services/network-manager
./services/syncthing
./services/git-sync
./modules/email.nix
@ -45,6 +45,7 @@
# social
discord # talk to other people
google-chrome
signal-desktop
# system tools
uhk-agent # my keyboard
@ -53,6 +54,8 @@
parallel-disk-usage
gdu
gnomeExtensions.paperwm
# gaming support
stable.bottles
wine64Packages.stagingFull
@ -99,7 +102,7 @@
{
enable = true;
loginExtra = auth-socket-env;
initExtra = auth-socket-env;
initContent = auth-socket-env;
};
};

View file

@ -35,6 +35,9 @@ in
enable = true;
hooks.preNew = "mbsync --all";
};
programs.mu = {
enable = true;
};
accounts.email = {
accounts.failco = mkAccount "me@failco.de" // {

View file

@ -15,7 +15,11 @@ in
programs.emacs = {
enable = true;
extraPackages = epkgs: with epkgs; [ vterm ];
extraPackages =
epkgs: with epkgs; [
vterm
mu4e
];
};
services.emacs = {
@ -23,9 +27,4 @@ in
defaultEditor = true;
startWithUserSession = true;
};
xdg.configFile.doom = {
target = "doom";
source = ./doom;
};
}

View file

@ -321,6 +321,18 @@
(("C-c n d" . #'denote-open-or-create-with-command))
)
(use-package! denote-org
:after denote)
(use-package! denote-journal
:after denote)
(use-package! denote-menu
:after denote)
(use-package! denote-sequence
:after denote)
(use-package! org-super-agenda
:after org-agenda
:init
@ -375,7 +387,7 @@
:after denote)
(use-package! cov)
(use-package! casual-suite)
;(use-package! casual-suite)
(map! :desc "Move workspace to the left" :leader :n "TAB <" #'+workspace/swap-left)
(map! :desc "Move workspace to the left" :leader :n "TAB >" #'+workspace/swap-right)

View file

@ -177,8 +177,8 @@
(zig +lsp +tree-sitter) ; C, but simpler
:email
;; (mu4e +org +gmail)
(notmuch +org +afew)
(mu4e +org +gmail +mbsync)
;; (notmuch +org +afew)
;;(wanderlust +gmail)
:app

View file

@ -53,8 +53,10 @@
;; :recipe (:host github :repo "username/repo"
;; :files ("some-file.el" "src/lisp/*.el")))
(unpin! compat)
;(unpin! with-editor ghub)
;;(unpin! compat)
;;(unpin! with-editor ghub)
;;(package! transient :pin "25b994a565ce8035330b0a3071ee430c0282349e") ; 0.8.8
(package! ormolu)
(package! org-gtd
@ -68,7 +70,13 @@
(package! emacsql-sqlite3)
(package! nov)
(package! org-present)
(package! denote)
(package! denote-org)
(package! denote-journal)
(package! denote-menu)
(package! denote-sequence)
(package! org-super-agenda)
(package! org-modern)
(package! org-ql)

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
{
programs.git = {
@ -17,48 +22,62 @@
key = "41A6D13FECA21280";
signByDefault = false;
};
delta = { enable = true; };
# TODO create option for my own account meta data
userEmail = "me@failco.de";
userName = "Alexander Kobjolke";
extraConfig = {
pull = { rebase = true; };
merge = { conflictstyle = "diff3"; };
submodule = { recurse = true; };
};
settings = {
pull = {
rebase = true;
};
merge = {
conflictstyle = "diff3";
};
submodule = {
recurse = true;
};
user = {
# TODO create option for my own account meta data
email = "me@failco.de";
name = "Alexander Kobjolke";
};
alias = {
a = "add";
c = "commit";
ca = "commit --amend";
can = "commit --amend --no-edit";
cl = "clone";
cm = "commit -m";
co = "checkout";
cp = "cherry-pick";
cpx = "cherry-pick -x";
d = "diff";
f = "fetch";
fo = "fetch origin";
fu = "fetch upstream";
lol = "log --graph --decorate --pretty=oneline --abbrev-commit";
lola = "log --graph --decorate --pretty=oneline --abbrev-commit --all";
pl = "pull";
pr = "pull -r";
ps = "push";
psf = "push -f";
rb = "rebase";
rbi = "rebase -i";
r = "remote";
ra = "remote add";
rr = "remote rm";
rv = "remote -v";
rs = "remote show";
st = "status";
};
aliases = {
a = "add";
c = "commit";
ca = "commit --amend";
can = "commit --amend --no-edit";
cl = "clone";
cm = "commit -m";
co = "checkout";
cp = "cherry-pick";
cpx = "cherry-pick -x";
d = "diff";
f = "fetch";
fo = "fetch origin";
fu = "fetch upstream";
lol = "log --graph --decorate --pretty=oneline --abbrev-commit";
lola = "log --graph --decorate --pretty=oneline --abbrev-commit --all";
pl = "pull";
pr = "pull -r";
ps = "push";
psf = "push -f";
rb = "rebase";
rbi = "rebase -i";
r = "remote";
ra = "remote add";
rr = "remote rm";
rv = "remote -v";
rs = "remote show";
st = "status";
init.defaultBranch = "main";
};
extraConfig = { init.defaultBranch = "main"; };
};
programs.git-cliff = { enable = true; };
programs.delta = {
enable = true;
enableGitIntegration = true;
};
programs.git-cliff = {
enable = true;
};
}

View file

@ -9,8 +9,8 @@
programs.jujutsu = {
enable = true;
settings = {
user.name = config.programs.git.userName;
user.email = config.programs.git.userEmail;
user.name = config.programs.git.settings.user.name;
user.email = config.programs.git.settings.user.email;
ui.default-command = "log";
aliases.init = [
"git"

View file

@ -14,7 +14,14 @@
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
initContent = ''
[ $TERM = "dumb" ] && unsetopt zle && PS1='$ '
'';
oh-my-zsh = {
enable = true;
plugins = [

View file

@ -1,5 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
{
config.xsession.windowManager.xmonad = {
enable = true;
@ -8,5 +12,8 @@
};
# control backlight
config.home.packages = [ pkgs.xorg.xbacklight pkgs.scrot ];
config.home.packages = [
pkgs.xorg.xbacklight
pkgs.scrot
];
}

View file

@ -50,11 +50,7 @@ in
extraLocaleSettings = {
TIME_STYLE = "iso";
};
supportedLocales = [
"C.UTF-8/UTF-8"
"en_US.UTF-8/UTF-8"
"de_DE.UTF-8/UTF-8"
];
extraLocales = "all";
};
console = {

View file

@ -324,6 +324,7 @@ in
address = "127.0.0.1";
port = 3002;
consumptionDirIsPublic = true;
configureTika = true;
settings = {
PAPERLESS_OCR_LANGUAGE = "deu+eng";
PAPERLESS_OCR_USER_ARGS = ''{"invalidate_digital_signatures": true}'';
@ -412,6 +413,7 @@ in
mailserver = {
enable = true;
stateVersion = 3;
fqdn = "thrall.failco.de";
domains = [
"failco.de"
@ -459,6 +461,9 @@ in
];
"anne@kobjolke.de" = "anne.kobjolke@gmail.com";
"alexander@kobjolke.de" = "alex@kobjolke.de";
"ida@kobjolke.de" = "alex@kobjolke.de";
"klara@kobjolke.de" = "alex@kobjolke.de";
"charlie@kobjolke.de" = "alex@kobjolke.de";
};
certificateScheme = "acme-nginx";

View file

@ -26,8 +26,14 @@
keep-outputs = true;
keep-derivations = true;
trusted-substituters = [ "https://devenv.cachix.org" ];
trusted-public-keys = [ "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" ];
trusted-substituters = [
"https://devenv.cachix.org"
"https://nixcache.reflex-frp.org"
];
trusted-public-keys = [
"devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw="
"ryantrinkle.com-1:JJiAKaRv9mWgpVAz8dwewnZe0AzzEAzPkagE9SP5NWI="
];
trusted-users = [
"root"
"alex"

View file

@ -26,11 +26,10 @@
enable = true;
greeters.slick.enable = true;
};
desktopManager.xfce.enable = true;
desktopManager.gnome.enable = true;
};
desktopManager.gnome.enable = true;
# Enable touchpad support (enabled default in most desktopManager).
libinput = {
enable = true;

View file

@ -0,0 +1,142 @@
#!/usr/bin/env nix-shell
#!nix-shell -i python3 -p python3
import argparse
import os
import shutil
import sys
from enum import Enum
from pathlib import Path
from pwd import getpwnam
class FolderLayout(Enum):
Default = 1
Folder = 2
def check_user(vmail_root: Path):
owner = vmail_root.owner()
owner_uid = getpwnam(owner).pw_uid
if os.geteuid() == owner_uid:
return
try:
print(
f"Trying to switch effective user id to {owner_uid} ({owner})",
file=sys.stderr,
)
os.seteuid(owner_uid)
return
except PermissionError:
print(
f"Failed switching to virtual mail user. Please run this script under it, for example by using `sudo -u {owner}`)",
file=sys.stderr,
)
sys.exit(1)
def is_maildir_related(path: Path, layout: FolderLayout) -> bool:
if path.name in [
"subscriptions"
# https://doc.dovecot.org/2.3/admin_manual/mailbox_formats/maildir/#imap-uid-mapping
"dovecot-uidlist",
# https://doc.dovecot.org/2.3/admin_manual/mailbox_formats/maildir/#imap-keywords
"dovecot-keywords",
]:
return True
if not path.is_dir():
return False
if path.name in ["cur", "new", "tmp"]:
return True
if layout is FolderLayout.Default and path.name.startswith("."):
return True
if layout is FolderLayout.Folder:
if path.name in ["mail"]:
return False
return True
return False
def mkdir(dst: Path, dry_run: bool = True):
print(f'mkdir "{dst}"')
if not dry_run:
# u+rwx, setgid
dst.mkdir(mode=0o2700)
def move(src: Path, dst: Path, dry_run: bool = True):
print(f'mv "{src}" "{dst}"')
if not dry_run:
src.rename(dst)
def delete(dst: Path, dry_run: bool = True):
if not dst.exists():
return
if dst.is_dir():
print(f'rm --recursive "{dst}"')
if not dry_run:
shutil.rmtree(dst)
else:
print(f'rm "{dst}"')
if not dry_run:
dst.unlink()
def main(vmail_root: Path, layout: FolderLayout, dry_run: bool = True):
maildirs = {path.parent for path in vmail_root.glob("*/*/cur")}
maybe_delete = []
# The old maildir will be the new home directory
for homedir in maildirs:
maildir = homedir / "mail"
mkdir(maildir, dry_run)
for path in homedir.iterdir():
if is_maildir_related(path, layout):
move(path, maildir / path.name, dry_run)
else:
maybe_delete.append(path)
# Files that are part of the previous home directory, but now obsolete
for path in [
vmail_root / ".dovecot.lda-dupes",
vmail_root / ".dovecot.lda-dupes.locks",
]:
delete(path, dry_run)
# The remaining files are likely obsolete, but should still be checked with care
for path in maybe_delete:
print(f"# rm {str(path)}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="""
NixOS Mailserver Migration #3: Dovecot mail directory migration
(https://nixos-mailserver.readthedocs.io/en/latest/migrations.html#dovecot-mail-directory-migration)
"""
)
parser.add_argument(
"vmail_root", type=Path, help="Path to the `mailserver.mailDirectory`"
)
parser.add_argument(
"--layout",
choices=["default", "folder"],
required=True,
help="Folder layout: 'default' unless `mailserver.useFsLayout` was enabled, then'folder'",
)
parser.add_argument(
"--execute", action="store_true", help="Actually perform changes"
)
args = parser.parse_args()
layout = FolderLayout.Default if args.layout == "default" else FolderLayout.Folder
check_user(args.vmail_root)
main(args.vmail_root, layout, not args.execute)