Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8caf8c0c01 | ||
|
|
589442e59c | ||
|
|
c90cbd7399 | ||
|
|
bb12cae954 | ||
|
|
5249d6bc19 | ||
|
|
3ea21dfb60 |
21
.github/workflows/publish-release.yml
vendored
21
.github/workflows/publish-release.yml
vendored
@@ -166,3 +166,24 @@ jobs:
|
|||||||
body_path: /tmp/release-notes.md
|
body_path: /tmp/release-notes.md
|
||||||
draft: false
|
draft: false
|
||||||
prerelease: false
|
prerelease: false
|
||||||
|
make_latest: 'true'
|
||||||
|
|
||||||
|
# Belt-and-suspenders: action-gh-release@v2 has a long-standing
|
||||||
|
# intermittent bug where it creates the release as a draft and silently
|
||||||
|
# fails to flip the draft→published step, even though it reports success.
|
||||||
|
# When that happens the install script + README snippets resolve "latest"
|
||||||
|
# to whatever was last properly published, so users would get an old
|
||||||
|
# version. We explicitly flip to published + latest here as a safety net;
|
||||||
|
# if the action already did it correctly, this is a no-op.
|
||||||
|
#
|
||||||
|
# Security note: TAG and REPO are sourced from earlier `env:` blocks (not
|
||||||
|
# interpolated inline into the run command), matching the same pattern
|
||||||
|
# used elsewhere in this workflow.
|
||||||
|
- name: Force-publish release
|
||||||
|
if: steps.existing.outputs.skip != 'true'
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
TAG: ${{ steps.version.outputs.tag }}
|
||||||
|
REPO: ${{ github.repository }}
|
||||||
|
run: |
|
||||||
|
gh release edit "$TAG" --repo "$REPO" --draft=false --latest
|
||||||
|
|||||||
16
CHANGELOG.md
16
CHANGELOG.md
@@ -2,6 +2,22 @@
|
|||||||
|
|
||||||
All notable changes to the VirtFusion Direct Provisioning Module for WHMCS.
|
All notable changes to the VirtFusion Direct Provisioning Module for WHMCS.
|
||||||
|
|
||||||
|
## [1.4.3] - 2026-04-25
|
||||||
|
|
||||||
|
### Features
|
||||||
|
- **`install.sh` helper script with `install` / `upgrade` / `check` subcommands.** Single-file POSIX bash script that handles both first-time installation and upgrades, auto-detects the WHMCS web user from the parent directory's ownership and applies it to new files via rsync `--chown`, optionally syncs the PowerDNS reverse-DNS addon (`--with-addon`), accepts a pinned version (`--version v1.4.1`, default: latest published release), preserves any custom `config/ConfigOptionMapping.php` across the rsync `--delete`, and writes a `.installed-version` marker so the `check` subcommand can report installed-vs-latest without making changes. Pipeable via curl or wget. Exit codes for `check` (0=current, 1=outdated, 2=not installed) make it usable as a cron-driven update monitor. Closes the long-standing pitfall where rsyncing as root left files owned by `root:root` and the web server couldn't read them — the classic "module installed but invisible in WHMCS" symptom.
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
- **Release workflow now force-publishes new releases to non-draft and marks them `--latest`.** `softprops/action-gh-release@v2` has a long-standing intermittent bug where it creates a release as a draft and silently fails to flip it to published, despite reporting success. v1.4.0, v1.4.1, and v1.4.2 all shipped as drafts because of this — meaning the GitHub `releases/latest` API returned v1.3.0, the install snippets and the new `install.sh` would all download v1.3.0, and users would never get the storage-type-code fix even after running the documented upgrade. Added a `make_latest: 'true'` input to the action and a follow-up `gh release edit --draft=false --latest` step that runs unconditionally as a safety net. v1.4.0/1/2 were manually re-published as a one-off cleanup.
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
- README install/upgrade sections rewritten to feature the `install.sh` script as the primary path (with both `curl` and `wget` examples), with the manual rsync recipe preserved in collapsible `<details>` blocks for users who prefer not to pipe scripts to bash. The manual recipe also gained a `stat -c '%U:%G'` ownership probe and `--chown="$OWNER"` flag, fixing the same root-owned-file pitfall the script handles automatically.
|
||||||
|
|
||||||
|
## [1.4.2] - 2026-04-25
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
- **Install/upgrade snippets now pull tagged releases instead of cloning `main`.** The previous `git clone` flow always pulled HEAD, which could include in-flight commits between releases — the same trap the v1.4.1 storage-type-code bug fell into for anyone who installed during the v1.4.0 release window. The new snippets default to the latest published release (queried live from the GitHub API at install time) and accept a `VERSION=vX.Y.Z` override for pinned installs and rollbacks. Pure POSIX — only requires `curl`, `sed`, `tar`, and `rsync`, all standard on any WHMCS host. The `archive/refs/tags/<TAG>.tar.gz` endpoint is public and cacheable, so only the version lookup hits the GitHub API (well under the 60/hr unauthenticated rate limit).
|
||||||
|
|
||||||
## [1.4.1] - 2026-04-25
|
## [1.4.1] - 2026-04-25
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
75
README.md
75
README.md
@@ -130,14 +130,42 @@ You also need a VirtFusion API token with the following permissions:
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
The fastest path is the install script. It auto-detects the WHMCS web user from your `modules/servers` directory ownership and applies it to the new files — without that, rsyncing as root would leave files owned by `root:root` and the web server couldn't read them ("module installed but invisible in WHMCS").
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
WHMCS=/path/to/whmcs
|
curl -fsSL https://raw.githubusercontent.com/EZSCALE/virtfusion-whmcs-module/main/install.sh \
|
||||||
git clone https://github.com/EZSCALE/virtfusion-whmcs-module.git /tmp/vf \
|
| sudo bash -s -- install /path/to/whmcs
|
||||||
&& rsync -ahP --delete /tmp/vf/modules/servers/VirtFusionDirect/ "$WHMCS/modules/servers/VirtFusionDirect/" \
|
|
||||||
&& rm -rf /tmp/vf
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Set `WHMCS` once at the top — it's reused in every path below. The database table, schema migrations, and custom fields are all created automatically on first load.
|
Same thing with `wget`:
|
||||||
|
```bash
|
||||||
|
wget -qO- https://raw.githubusercontent.com/EZSCALE/virtfusion-whmcs-module/main/install.sh \
|
||||||
|
| sudo bash -s -- install /path/to/whmcs
|
||||||
|
```
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
- `--with-addon` — also install the PowerDNS reverse-DNS addon (`modules/addons/VirtFusionDns/`).
|
||||||
|
- `--version v1.4.1` — pin a specific release tag (default: latest published release; any tag from [Releases](https://github.com/EZSCALE/virtfusion-whmcs-module/releases)).
|
||||||
|
|
||||||
|
The database table, schema migrations, and custom fields are all created automatically on first load.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>Manual install</b> (if you'd rather not pipe a script to bash)</summary>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
WHMCS=/path/to/whmcs
|
||||||
|
VERSION=${VERSION:-$(curl -fsSL https://api.github.com/repos/EZSCALE/virtfusion-whmcs-module/releases/latest \
|
||||||
|
| sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p')}
|
||||||
|
OWNER=$(stat -c '%U:%G' "$WHMCS/modules/servers")
|
||||||
|
curl -fsSL "https://github.com/EZSCALE/virtfusion-whmcs-module/archive/refs/tags/${VERSION}.tar.gz" -o /tmp/vf.tar.gz \
|
||||||
|
&& mkdir -p /tmp/vf && tar -xzf /tmp/vf.tar.gz -C /tmp/vf --strip-components=1 \
|
||||||
|
&& rsync -ahP --delete --chown="$OWNER" /tmp/vf/modules/servers/VirtFusionDirect/ "$WHMCS/modules/servers/VirtFusionDirect/" \
|
||||||
|
&& rm -rf /tmp/vf /tmp/vf.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
`--chown="$OWNER"` ensures the new files match your WHMCS web user (`www-data`, `apache`, etc.) instead of `root:root`. Requires rsync 3.1+ and root (or already running as the matching user). To pin a version, prepend `VERSION=v1.4.1` before the command.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
Then configure in WHMCS Admin:
|
Then configure in WHMCS Admin:
|
||||||
|
|
||||||
@@ -150,19 +178,42 @@ That's it. Hooks activate automatically and custom fields are created on module
|
|||||||
## Upgrading
|
## Upgrading
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
WHMCS=/path/to/whmcs
|
curl -fsSL https://raw.githubusercontent.com/EZSCALE/virtfusion-whmcs-module/main/install.sh \
|
||||||
git clone https://github.com/EZSCALE/virtfusion-whmcs-module.git /tmp/vf \
|
| sudo bash -s -- upgrade /path/to/whmcs
|
||||||
&& rsync -ahP --delete /tmp/vf/modules/servers/VirtFusionDirect/ "$WHMCS/modules/servers/VirtFusionDirect/" \
|
|
||||||
&& rsync -ahP --delete /tmp/vf/modules/addons/VirtFusionDns/ "$WHMCS/modules/addons/VirtFusionDns/" \
|
|
||||||
&& rm -rf /tmp/vf
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The second `rsync` line is only needed if you use the Reverse DNS addon; skip it otherwise. Addon settings live in `tbladdonmodules` and survive file updates.
|
Add `--with-addon` if you also use the PowerDNS addon. Pin a version with `--version v1.4.1` for controlled rollouts or rollbacks. Addon settings live in `tbladdonmodules` and survive file updates. The script automatically backs up and restores any custom `config/ConfigOptionMapping.php` across the rsync `--delete`.
|
||||||
|
|
||||||
> **Note:** If you have a custom `config/ConfigOptionMapping.php`, back it up first — `--delete` will remove it. Restore it after upgrading.
|
To check whether you're current without making any changes:
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/EZSCALE/virtfusion-whmcs-module/main/install.sh \
|
||||||
|
| bash -s -- check /path/to/whmcs
|
||||||
|
```
|
||||||
|
Exit codes: `0` = up-to-date, `1` = outdated (or version unknown), `2` = not installed. Useful in cron-driven monitoring.
|
||||||
|
|
||||||
If you use theme-overridden templates, review them for any new template variables. Clear the WHMCS template cache after upgrading: **Configuration > System Settings > General Settings > clear template cache**.
|
If you use theme-overridden templates, review them for any new template variables. Clear the WHMCS template cache after upgrading: **Configuration > System Settings > General Settings > clear template cache**.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>Manual upgrade</b> (if you'd rather not pipe a script to bash)</summary>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
WHMCS=/path/to/whmcs
|
||||||
|
VERSION=${VERSION:-$(curl -fsSL https://api.github.com/repos/EZSCALE/virtfusion-whmcs-module/releases/latest \
|
||||||
|
| sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p')}
|
||||||
|
OWNER=$(stat -c '%U:%G' "$WHMCS/modules/servers")
|
||||||
|
curl -fsSL "https://github.com/EZSCALE/virtfusion-whmcs-module/archive/refs/tags/${VERSION}.tar.gz" -o /tmp/vf.tar.gz \
|
||||||
|
&& mkdir -p /tmp/vf && tar -xzf /tmp/vf.tar.gz -C /tmp/vf --strip-components=1 \
|
||||||
|
&& rsync -ahP --delete --chown="$OWNER" /tmp/vf/modules/servers/VirtFusionDirect/ "$WHMCS/modules/servers/VirtFusionDirect/" \
|
||||||
|
&& rsync -ahP --delete --chown="$OWNER" /tmp/vf/modules/addons/VirtFusionDns/ "$WHMCS/modules/addons/VirtFusionDns/" \
|
||||||
|
&& rm -rf /tmp/vf /tmp/vf.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
The second `rsync` line is only needed if you use the Reverse DNS addon; skip it otherwise.
|
||||||
|
|
||||||
|
> **Note:** If you have a custom `config/ConfigOptionMapping.php`, back it up first — `--delete` will remove it. Restore it after. The helper script does this automatically.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
### Server Setup
|
### Server Setup
|
||||||
|
|||||||
190
install.sh
Executable file
190
install.sh
Executable file
@@ -0,0 +1,190 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# install.sh — Manage the VirtFusion Direct WHMCS module.
|
||||||
|
#
|
||||||
|
# Subcommands:
|
||||||
|
# install First-time install. Refuses if already present (use upgrade).
|
||||||
|
# upgrade Refresh an existing install. Refuses if nothing is installed.
|
||||||
|
# check Report installed version vs latest available. No changes.
|
||||||
|
#
|
||||||
|
# Flags (install/upgrade only):
|
||||||
|
# --with-addon, -a Also sync the PowerDNS rDNS addon.
|
||||||
|
# --version, -v vX.Y.Z Pin a specific release tag (default: latest).
|
||||||
|
#
|
||||||
|
# Exit codes for `check`:
|
||||||
|
# 0 installed and up-to-date
|
||||||
|
# 1 installed but outdated (or installed-version unknown)
|
||||||
|
# 2 not installed
|
||||||
|
#
|
||||||
|
# Pipeable:
|
||||||
|
# curl -fsSL https://raw.githubusercontent.com/EZSCALE/virtfusion-whmcs-module/main/install.sh \
|
||||||
|
# | sudo bash -s -- install /path/to/whmcs
|
||||||
|
#
|
||||||
|
# wget -qO- https://raw.githubusercontent.com/EZSCALE/virtfusion-whmcs-module/main/install.sh \
|
||||||
|
# | sudo bash -s -- upgrade --with-addon /path/to/whmcs
|
||||||
|
#
|
||||||
|
# curl -fsSL https://raw.githubusercontent.com/EZSCALE/virtfusion-whmcs-module/main/install.sh \
|
||||||
|
# | bash -s -- check /path/to/whmcs
|
||||||
|
#
|
||||||
|
# Why a script? rsync into a directory owned by the WHMCS web user (e.g.
|
||||||
|
# www-data, apache) lands files as root:root by default, which the web server
|
||||||
|
# can't read — the classic "module installed but invisible in WHMCS" symptom.
|
||||||
|
# This script reads the parent directory's owner and applies it via --chown, so
|
||||||
|
# a `sudo bash` install ends up with correct ownership. It also preserves any
|
||||||
|
# custom config/ConfigOptionMapping.php across --delete.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO="EZSCALE/virtfusion-whmcs-module"
|
||||||
|
MARKER=".installed-version"
|
||||||
|
|
||||||
|
err() { printf '\033[1;31merror:\033[0m %s\n' "$*" >&2; }
|
||||||
|
warn() { printf '\033[1;33mwarn:\033[0m %s\n' "$*" >&2; }
|
||||||
|
info() { printf '\033[1;32m==>\033[0m %s\n' "$*"; }
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<USAGE
|
||||||
|
Usage:
|
||||||
|
install.sh install [--with-addon] [--version vX.Y.Z] /path/to/whmcs
|
||||||
|
install.sh upgrade [--with-addon] [--version vX.Y.Z] /path/to/whmcs
|
||||||
|
install.sh check /path/to/whmcs
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/$REPO/main/install.sh \\
|
||||||
|
| sudo bash -s -- install /path/to/whmcs
|
||||||
|
|
||||||
|
wget -qO- https://raw.githubusercontent.com/$REPO/main/install.sh \\
|
||||||
|
| sudo bash -s -- upgrade --with-addon /path/to/whmcs
|
||||||
|
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/$REPO/main/install.sh \\
|
||||||
|
| bash -s -- check /path/to/whmcs
|
||||||
|
USAGE
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_latest() {
|
||||||
|
curl -fsSL "https://api.github.com/repos/$REPO/releases/latest" \
|
||||||
|
| sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p'
|
||||||
|
}
|
||||||
|
|
||||||
|
read_installed_version() {
|
||||||
|
local marker="$1/modules/servers/VirtFusionDirect/$MARKER"
|
||||||
|
if [ -f "$marker" ]; then
|
||||||
|
tr -d '[:space:]' < "$marker"
|
||||||
|
else
|
||||||
|
echo "unknown"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_check() {
|
||||||
|
local WHMCS="$1"
|
||||||
|
if [ ! -d "$WHMCS/modules/servers/VirtFusionDirect" ]; then
|
||||||
|
warn "Not installed at $WHMCS"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
local current latest
|
||||||
|
current=$(read_installed_version "$WHMCS")
|
||||||
|
latest=$(resolve_latest)
|
||||||
|
[ -n "$latest" ] || { err "Could not resolve latest version from GitHub API"; exit 1; }
|
||||||
|
printf ' installed: %s\n latest: %s\n' "$current" "$latest"
|
||||||
|
if [ "$current" = "$latest" ]; then
|
||||||
|
info "Up to date"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
warn "Update available: $current → $latest"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_sync() {
|
||||||
|
local mode="$1"; shift
|
||||||
|
local WITH_ADDON=0 VERSION="${VERSION:-}" WHMCS=""
|
||||||
|
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--with-addon|-a) WITH_ADDON=1; shift ;;
|
||||||
|
--version|-v) VERSION="${2:-}"; shift 2 ;;
|
||||||
|
-h|--help) usage ;;
|
||||||
|
-*) err "Unknown flag: $1"; usage ;;
|
||||||
|
*) WHMCS="$1"; shift ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
[ -n "$WHMCS" ] || { err "Missing WHMCS path"; usage; }
|
||||||
|
[ -d "$WHMCS/modules/servers" ] || {
|
||||||
|
err "Not a WHMCS install: $WHMCS/modules/servers not found"; exit 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
local target="$WHMCS/modules/servers/VirtFusionDirect"
|
||||||
|
if [ "$mode" = "install" ] && [ -d "$target" ]; then
|
||||||
|
err "Already installed at $target — use 'upgrade' to refresh."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ "$mode" = "upgrade" ] && [ ! -d "$target" ]; then
|
||||||
|
err "Not currently installed at $target — use 'install' instead."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$VERSION" ]; then
|
||||||
|
VERSION=$(resolve_latest)
|
||||||
|
[ -n "$VERSION" ] || { err "Could not resolve latest version from GitHub API"; exit 1; }
|
||||||
|
fi
|
||||||
|
info "Target version: $VERSION"
|
||||||
|
|
||||||
|
local OWNER
|
||||||
|
OWNER=$(stat -c '%U:%G' "$WHMCS/modules/servers" 2>/dev/null || true)
|
||||||
|
[ -n "$OWNER" ] || { err "Could not detect parent directory owner via stat"; exit 1; }
|
||||||
|
info "Owner (from $WHMCS/modules/servers): $OWNER"
|
||||||
|
|
||||||
|
local TMP
|
||||||
|
TMP=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$TMP"' EXIT
|
||||||
|
|
||||||
|
info "Downloading $VERSION..."
|
||||||
|
curl -fsSL "https://github.com/$REPO/archive/refs/tags/$VERSION.tar.gz" -o "$TMP/src.tar.gz"
|
||||||
|
mkdir -p "$TMP/src"
|
||||||
|
tar -xzf "$TMP/src.tar.gz" -C "$TMP/src" --strip-components=1
|
||||||
|
|
||||||
|
local SRC="$TMP/src/modules/servers/VirtFusionDirect"
|
||||||
|
[ -d "$SRC" ] || { err "Tarball did not contain modules/servers/VirtFusionDirect"; exit 1; }
|
||||||
|
|
||||||
|
# Preserve user's custom configurable-option mapping across --delete.
|
||||||
|
local MAP_FILE="$target/config/ConfigOptionMapping.php"
|
||||||
|
local MAP_BACKUP=""
|
||||||
|
if [ -f "$MAP_FILE" ]; then
|
||||||
|
MAP_BACKUP="$TMP/ConfigOptionMapping.php.bak"
|
||||||
|
cp -p "$MAP_FILE" "$MAP_BACKUP"
|
||||||
|
info "Backed up custom ConfigOptionMapping.php"
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "Syncing server module → $target/"
|
||||||
|
rsync -ahP --delete --chown="$OWNER" "$SRC/" "$target/"
|
||||||
|
|
||||||
|
if [ -n "$MAP_BACKUP" ]; then
|
||||||
|
cp -p "$MAP_BACKUP" "$MAP_FILE"
|
||||||
|
chown "$OWNER" "$MAP_FILE"
|
||||||
|
info "Restored custom ConfigOptionMapping.php"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s\n' "$VERSION" > "$target/$MARKER"
|
||||||
|
chown "$OWNER" "$target/$MARKER"
|
||||||
|
|
||||||
|
if [ "$WITH_ADDON" = 1 ]; then
|
||||||
|
local addon_src="$TMP/src/modules/addons/VirtFusionDns"
|
||||||
|
local addon_target="$WHMCS/modules/addons/VirtFusionDns"
|
||||||
|
[ -d "$addon_src" ] || { err "Tarball did not contain modules/addons/VirtFusionDns"; exit 1; }
|
||||||
|
info "Syncing PowerDNS addon → $addon_target/"
|
||||||
|
rsync -ahP --delete --chown="$OWNER" "$addon_src/" "$addon_target/"
|
||||||
|
printf '%s\n' "$VERSION" > "$addon_target/$MARKER"
|
||||||
|
chown "$OWNER" "$addon_target/$MARKER"
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "$mode complete: $VERSION (owner $OWNER)"
|
||||||
|
}
|
||||||
|
|
||||||
|
case "${1:-}" in
|
||||||
|
install) shift; cmd_sync install "$@" ;;
|
||||||
|
upgrade) shift; cmd_sync upgrade "$@" ;;
|
||||||
|
check) shift; [ $# -eq 1 ] || usage; cmd_check "$1" ;;
|
||||||
|
-h|--help|"") usage ;;
|
||||||
|
*) err "Unknown command: $1"; usage ;;
|
||||||
|
esac
|
||||||
Reference in New Issue
Block a user