feat: Added home manager module
This commit is contained in:
228
HOME-MANAGER.md
Normal file
228
HOME-MANAGER.md
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
# Home Manager Module for Hyprmonitors
|
||||||
|
|
||||||
|
This directory contains a Home Manager module for installing and configuring hyprmonitors, a Rust web server that provides an HTTP API for controlling Hyprland desktop monitors.
|
||||||
|
|
||||||
|
## What is Hyprmonitors?
|
||||||
|
|
||||||
|
Hyprmonitors is a lightweight web server that exposes a RESTful API to control your Hyprland monitors using `hyprctl dispatch dpms` commands. It allows you to:
|
||||||
|
|
||||||
|
- Turn all monitors on/off via HTTP requests
|
||||||
|
- Control individual monitors by name
|
||||||
|
- Get current monitor status
|
||||||
|
- Integrate monitor control into web applications or scripts
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Method 1: Direct Import
|
||||||
|
|
||||||
|
Add the module to your Home Manager configuration:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
/path/to/hyprmonitors/home-manager-module.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
# Enable Hyprland (required)
|
||||||
|
wayland.windowManager.hyprland.enable = true;
|
||||||
|
|
||||||
|
# Enable hyprmonitors service
|
||||||
|
services.hyprmonitors.enable = true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Method 2: As a Flake Input
|
||||||
|
|
||||||
|
Add hyprmonitors as a flake input in your `flake.nix`:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
home-manager.url = "github:nix-community/home-manager";
|
||||||
|
hyprmonitors.url = "path:/path/to/hyprmonitors";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { nixpkgs, home-manager, hyprmonitors, ... }: {
|
||||||
|
homeConfigurations.youruser = home-manager.lib.homeManagerConfiguration {
|
||||||
|
modules = [
|
||||||
|
hyprmonitors.homeManagerModules.default
|
||||||
|
{
|
||||||
|
wayland.windowManager.hyprland.enable = true;
|
||||||
|
services.hyprmonitors.enable = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Options
|
||||||
|
|
||||||
|
The module provides several configuration options:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
services.hyprmonitors = {
|
||||||
|
enable = true; # Enable the service
|
||||||
|
|
||||||
|
host = "127.0.0.1"; # Host to bind to (default: 127.0.0.1)
|
||||||
|
port = 3000; # Port to bind to (default: 3000)
|
||||||
|
|
||||||
|
logLevel = "info"; # Log level: error, warn, info, debug, trace
|
||||||
|
|
||||||
|
package = pkgs.hyprmonitors; # Override the package (optional)
|
||||||
|
|
||||||
|
environmentVariables = { # Additional environment variables
|
||||||
|
HYPRLAND_INSTANCE_SIGNATURE = "your-signature";
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = { # Future configuration options
|
||||||
|
timeout_seconds = 30;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Once installed and configured, the module provides several convenient tools:
|
||||||
|
|
||||||
|
### Shell Aliases
|
||||||
|
|
||||||
|
The module automatically adds these shell aliases:
|
||||||
|
|
||||||
|
- `hyprmonitors-start` - Start the service
|
||||||
|
- `hyprmonitors-stop` - Stop the service
|
||||||
|
- `hyprmonitors-restart` - Restart the service
|
||||||
|
- `hyprmonitors-status` - Check service status
|
||||||
|
- `hyprmonitors-logs` - View service logs
|
||||||
|
- `hyprmonitors-test` - Test if the API is responding
|
||||||
|
|
||||||
|
### API Helper Script
|
||||||
|
|
||||||
|
The `hyprmonitors-curl` script provides easy access to the API:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check if the service is running
|
||||||
|
hyprmonitors-curl health
|
||||||
|
|
||||||
|
# Get status of all monitors
|
||||||
|
hyprmonitors-curl status
|
||||||
|
|
||||||
|
# Turn all monitors on/off
|
||||||
|
hyprmonitors-curl on
|
||||||
|
hyprmonitors-curl off
|
||||||
|
|
||||||
|
# Control specific monitors
|
||||||
|
hyprmonitors-curl on DP-1
|
||||||
|
hyprmonitors-curl off HDMI-A-1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Manual API Access
|
||||||
|
|
||||||
|
You can also use curl directly:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Health check
|
||||||
|
curl http://localhost:3000/health
|
||||||
|
|
||||||
|
# Monitor status
|
||||||
|
curl http://localhost:3000/monitors/status
|
||||||
|
|
||||||
|
# Turn all monitors on/off
|
||||||
|
curl -X POST http://localhost:3000/monitors/on
|
||||||
|
curl -X POST http://localhost:3000/monitors/off
|
||||||
|
|
||||||
|
# Control specific monitors
|
||||||
|
curl -X POST http://localhost:3000/monitors/DP-1/on
|
||||||
|
curl -X POST http://localhost:3000/monitors/HDMI-A-1/off
|
||||||
|
```
|
||||||
|
|
||||||
|
## Service Management
|
||||||
|
|
||||||
|
The service is automatically managed by systemd:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check service status
|
||||||
|
systemctl --user status hyprmonitors.service
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
journalctl --user -u hyprmonitors.service -f
|
||||||
|
|
||||||
|
# Manual start/stop (if needed)
|
||||||
|
systemctl --user start hyprmonitors.service
|
||||||
|
systemctl --user stop hyprmonitors.service
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integration with Hyprland
|
||||||
|
|
||||||
|
You can integrate hyprmonitors with Hyprland keybinds:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
wayland.windowManager.hyprland.settings = {
|
||||||
|
bind = [
|
||||||
|
# Turn all monitors off/on
|
||||||
|
"SUPER SHIFT, M, exec, hyprmonitors-curl off"
|
||||||
|
"SUPER CTRL, M, exec, hyprmonitors-curl on"
|
||||||
|
|
||||||
|
# Control specific monitors
|
||||||
|
"SUPER SHIFT, 1, exec, hyprmonitors-curl off DP-1"
|
||||||
|
"SUPER SHIFT, 2, exec, hyprmonitors-curl off HDMI-A-1"
|
||||||
|
"SUPER CTRL, 1, exec, hyprmonitors-curl on DP-1"
|
||||||
|
"SUPER CTRL, 2, exec, hyprmonitors-curl on HDMI-A-1"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Desktop Entry
|
||||||
|
|
||||||
|
The module creates a desktop entry "Hyprmonitors Control" that opens the health endpoint in your browser for quick access to verify the service is running.
|
||||||
|
|
||||||
|
## Finding Monitor Names
|
||||||
|
|
||||||
|
To find your monitor names for use with the API:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
hyprctl monitors
|
||||||
|
```
|
||||||
|
|
||||||
|
Common monitor names include:
|
||||||
|
- `DP-1`, `DP-2` (DisplayPort)
|
||||||
|
- `HDMI-A-1`, `HDMI-A-2` (HDMI)
|
||||||
|
- `eDP-1` (Laptop screen)
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Service won't start
|
||||||
|
|
||||||
|
1. Ensure Hyprland is running and properly configured
|
||||||
|
2. Check that the port isn't already in use
|
||||||
|
3. View logs: `journalctl --user -u hyprmonitors.service`
|
||||||
|
|
||||||
|
### API requests fail
|
||||||
|
|
||||||
|
1. Verify the service is running: `hyprmonitors-test`
|
||||||
|
2. Check monitor names: `hyprctl monitors`
|
||||||
|
3. Ensure you're running commands in a Hyprland session
|
||||||
|
|
||||||
|
### Permission issues
|
||||||
|
|
||||||
|
The service runs as your user and should automatically have access to Hyprland's IPC socket. If you encounter permission issues, ensure:
|
||||||
|
|
||||||
|
1. You're running the service as the same user running Hyprland
|
||||||
|
2. The `XDG_RUNTIME_DIR` environment variable is properly set
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
- The service binds to localhost by default for security
|
||||||
|
- If you need remote access, change the host to `0.0.0.0` but ensure proper firewall configuration
|
||||||
|
- The service has restricted permissions and resource limits applied
|
||||||
|
|
||||||
|
## Complete Example
|
||||||
|
|
||||||
|
See `example-home-manager-config.nix` for a complete working example configuration.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- NixOS or Nix with Home Manager
|
||||||
|
- Hyprland window manager
|
||||||
|
- The module automatically handles all dependencies
|
||||||
79
example-home-manager-config.nix
Normal file
79
example-home-manager-config.nix
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
# Example Home Manager configuration for hyprmonitors
|
||||||
|
# Add this to your home.nix or import it as a module
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
# Import the hyprmonitors module
|
||||||
|
./home-manager-module.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
# Enable Hyprland (required for hyprmonitors)
|
||||||
|
wayland.windowManager.hyprland = {
|
||||||
|
enable = true;
|
||||||
|
# Add your Hyprland configuration here
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure hyprmonitors service
|
||||||
|
services.hyprmonitors = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
# Optional: customize host and port (defaults shown)
|
||||||
|
host = "127.0.0.1";
|
||||||
|
port = 3000;
|
||||||
|
|
||||||
|
# Optional: set log level (default: "info")
|
||||||
|
logLevel = "info";
|
||||||
|
|
||||||
|
# Optional: add environment variables
|
||||||
|
environmentVariables = {
|
||||||
|
# Example: if you need to set specific Hyprland instance
|
||||||
|
# HYPRLAND_INSTANCE_SIGNATURE = "your-signature-here";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Optional: override the package (if you want to use a custom build)
|
||||||
|
# package = pkgs.hyprmonitors; # Uses default from module
|
||||||
|
};
|
||||||
|
|
||||||
|
# The module automatically adds these shell aliases:
|
||||||
|
# - hyprmonitors-start: Start the service
|
||||||
|
# - hyprmonitors-stop: Stop the service
|
||||||
|
# - hyprmonitors-restart: Restart the service
|
||||||
|
# - hyprmonitors-status: Check service status
|
||||||
|
# - hyprmonitors-logs: View service logs
|
||||||
|
# - hyprmonitors-test: Test if the API is responding
|
||||||
|
|
||||||
|
# The module also adds a hyprmonitors-curl helper script for API testing:
|
||||||
|
# - hyprmonitors-curl health
|
||||||
|
# - hyprmonitors-curl status
|
||||||
|
# - hyprmonitors-curl on [monitor-name]
|
||||||
|
# - hyprmonitors-curl off [monitor-name]
|
||||||
|
|
||||||
|
# Example of additional Hyprland configuration that works well with hyprmonitors
|
||||||
|
wayland.windowManager.hyprland.settings = {
|
||||||
|
# Your Hyprland config here
|
||||||
|
monitor = [
|
||||||
|
"DP-1,1920x1080@60,0x0,1"
|
||||||
|
"HDMI-A-1,1920x1080@60,1920x0,1"
|
||||||
|
];
|
||||||
|
|
||||||
|
# Example keybinds for monitor control (optional)
|
||||||
|
bind = [
|
||||||
|
# Turn all monitors off/on
|
||||||
|
"SUPER SHIFT, M, exec, hyprmonitors-curl off"
|
||||||
|
"SUPER CTRL, M, exec, hyprmonitors-curl on"
|
||||||
|
|
||||||
|
# Turn specific monitors off/on
|
||||||
|
"SUPER SHIFT, 1, exec, hyprmonitors-curl off DP-1"
|
||||||
|
"SUPER SHIFT, 2, exec, hyprmonitors-curl off HDMI-A-1"
|
||||||
|
"SUPER CTRL, 1, exec, hyprmonitors-curl on DP-1"
|
||||||
|
"SUPER CTRL, 2, exec, hyprmonitors-curl on HDMI-A-1"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Optional: Install additional packages that work well with hyprmonitors
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
curl
|
||||||
|
jq
|
||||||
|
# Add other packages you need
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -69,5 +69,10 @@
|
|||||||
maintainers = [];
|
maintainers = [];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
});
|
})
|
||||||
|
// {
|
||||||
|
# Home Manager module
|
||||||
|
homeManagerModules.default = import ./home-manager-module.nix;
|
||||||
|
homeManagerModules.hyprmonitors = import ./home-manager-module.nix;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
213
home-manager-module.nix
Normal file
213
home-manager-module.nix
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
cfg = config.services.hyprmonitors;
|
||||||
|
|
||||||
|
hyprmonitors = pkgs.rustPlatform.buildRustPackage {
|
||||||
|
pname = "hyprmonitors";
|
||||||
|
version = "0.1.0";
|
||||||
|
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
|
cargoLock = {
|
||||||
|
lockFile = ./Cargo.lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
nativeBuildInputs = with pkgs; [
|
||||||
|
pkg-config
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
openssl
|
||||||
|
];
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Hyprland monitor control server";
|
||||||
|
homepage = "https://github.com/your-username/hyprmonitors";
|
||||||
|
license = licenses.mit;
|
||||||
|
maintainers = [];
|
||||||
|
platforms = platforms.linux;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options.services.hyprmonitors = {
|
||||||
|
enable = mkEnableOption "Hyprland monitor control server";
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = hyprmonitors;
|
||||||
|
defaultText = literalExpression "pkgs.hyprmonitors";
|
||||||
|
description = "The hyprmonitors package to use.";
|
||||||
|
};
|
||||||
|
|
||||||
|
host = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "127.0.0.1";
|
||||||
|
description = "Host address to bind the server to.";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 3000;
|
||||||
|
description = "Port to bind the server to.";
|
||||||
|
};
|
||||||
|
|
||||||
|
logLevel = mkOption {
|
||||||
|
type = types.enum ["error" "warn" "info" "debug" "trace"];
|
||||||
|
default = "info";
|
||||||
|
description = "Log level for the server.";
|
||||||
|
};
|
||||||
|
|
||||||
|
environmentVariables = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default = {};
|
||||||
|
example = {
|
||||||
|
HYPRLAND_INSTANCE_SIGNATURE = "your-signature";
|
||||||
|
};
|
||||||
|
description = "Additional environment variables to set for the service.";
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
type = types.attrs;
|
||||||
|
default = {};
|
||||||
|
example = {
|
||||||
|
cors_origins = ["http://localhost:8080"];
|
||||||
|
timeout_seconds = 30;
|
||||||
|
};
|
||||||
|
description = "Additional configuration settings (if supported by future versions).";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = config.wayland.windowManager.hyprland.enable or false;
|
||||||
|
message = "hyprmonitors requires Hyprland to be enabled. Set wayland.windowManager.hyprland.enable = true;";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
home.packages = [cfg.package];
|
||||||
|
|
||||||
|
systemd.user.services.hyprmonitors = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Hyprland Monitor Control Server";
|
||||||
|
Documentation = "https://github.com/your-username/hyprmonitors";
|
||||||
|
After = ["graphical-session.target" "hyprland-session.target"];
|
||||||
|
Wants = ["graphical-session.target"];
|
||||||
|
PartOf = ["hyprland-session.target"];
|
||||||
|
};
|
||||||
|
|
||||||
|
Service = {
|
||||||
|
Type = "simple";
|
||||||
|
ExecStart = "${cfg.package}/bin/hyprmonitors";
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = 5;
|
||||||
|
|
||||||
|
# Environment variables
|
||||||
|
Environment =
|
||||||
|
[
|
||||||
|
"RUST_LOG=${cfg.logLevel}"
|
||||||
|
"HYPRMONITORS_HOST=${cfg.host}"
|
||||||
|
"HYPRMONITORS_PORT=${toString cfg.port}"
|
||||||
|
"HYPRMONITORS_LOG_LEVEL=${cfg.logLevel}"
|
||||||
|
]
|
||||||
|
++ (mapAttrsToList (name: value: "${name}=${value}") cfg.environmentVariables);
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
ProtectHome = "read-only";
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
ReadWritePaths = ["/tmp"];
|
||||||
|
|
||||||
|
# Resource limits
|
||||||
|
LimitNOFILE = 1024;
|
||||||
|
MemoryMax = "128M";
|
||||||
|
};
|
||||||
|
|
||||||
|
Install = {
|
||||||
|
WantedBy = ["hyprland-session.target"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Create a target for Hyprland session if it doesn't exist
|
||||||
|
systemd.user.targets.hyprland-session = mkIf (!config.systemd.user.targets ? hyprland-session) {
|
||||||
|
Unit = {
|
||||||
|
Description = "Hyprland session";
|
||||||
|
BindsTo = ["graphical-session.target"];
|
||||||
|
Wants = ["graphical-session.target"];
|
||||||
|
After = ["graphical-session.target"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Optional: Add a desktop entry for manual control
|
||||||
|
xdg.desktopEntries.hyprmonitors-control = mkIf (cfg.enable && cfg.host == "127.0.0.1") {
|
||||||
|
name = "Hyprmonitors Control";
|
||||||
|
comment = "Control Hyprland monitors via web interface";
|
||||||
|
exec = "${pkgs.xdg-utils}/bin/xdg-open http://${cfg.host}:${toString cfg.port}/health";
|
||||||
|
icon = "preferences-desktop-display";
|
||||||
|
categories = ["Settings" "System"];
|
||||||
|
terminal = false;
|
||||||
|
type = "Application";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Add some useful aliases for controlling the service
|
||||||
|
home.shellAliases = mkIf cfg.enable {
|
||||||
|
hyprmonitors-start = "systemctl --user start hyprmonitors.service";
|
||||||
|
hyprmonitors-stop = "systemctl --user stop hyprmonitors.service";
|
||||||
|
hyprmonitors-restart = "systemctl --user restart hyprmonitors.service";
|
||||||
|
hyprmonitors-status = "systemctl --user status hyprmonitors.service";
|
||||||
|
hyprmonitors-logs = "journalctl --user -u hyprmonitors.service -f";
|
||||||
|
hyprmonitors-test = "curl http://${cfg.host}:${toString cfg.port}/health";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Add some helper scripts
|
||||||
|
home.packages = mkIf cfg.enable [
|
||||||
|
(pkgs.writeShellScriptBin "hyprmonitors-curl" ''
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Helper script for testing hyprmonitors API
|
||||||
|
|
||||||
|
BASE_URL="http://${cfg.host}:${toString cfg.port}"
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
health)
|
||||||
|
curl -s "$BASE_URL/health" | ${pkgs.jq}/bin/jq
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
curl -s "$BASE_URL/monitors/status" | ${pkgs.jq}/bin/jq
|
||||||
|
;;
|
||||||
|
on)
|
||||||
|
if [ -n "$2" ]; then
|
||||||
|
curl -s -X POST "$BASE_URL/monitors/$2/on" | ${pkgs.jq}/bin/jq
|
||||||
|
else
|
||||||
|
curl -s -X POST "$BASE_URL/monitors/on" | ${pkgs.jq}/bin/jq
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
off)
|
||||||
|
if [ -n "$2" ]; then
|
||||||
|
curl -s -X POST "$BASE_URL/monitors/$2/off" | ${pkgs.jq}/bin/jq
|
||||||
|
else
|
||||||
|
curl -s -X POST "$BASE_URL/monitors/off" | ${pkgs.jq}/bin/jq
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: hyprmonitors-curl {health|status|on [monitor]|off [monitor]}"
|
||||||
|
echo ""
|
||||||
|
echo "Examples:"
|
||||||
|
echo " hyprmonitors-curl health"
|
||||||
|
echo " hyprmonitors-curl status"
|
||||||
|
echo " hyprmonitors-curl on"
|
||||||
|
echo " hyprmonitors-curl off"
|
||||||
|
echo " hyprmonitors-curl on DP-1"
|
||||||
|
echo " hyprmonitors-curl off HDMI-A-1"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user