e62a14dafc
Generate interlinked wiki from master inventory: 397 tool pages, 15 workflow pages, 27 recipe pages, 33 category pages, plus index. All pages use [[wiki-links]] for cross-navigation between tools, workflows, recipes, and categories (1782 links total). Install zk for interactive browsing with fzf search, tag filtering, and backlink discovery. Add 'fhelp wiki' command and Makefile target. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
574 lines
19 KiB
Bash
Executable File
574 lines
19 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Enhanced File Analysis Help System
|
|
# Integrates multiple help sources: custom cheat sheets, tldr, tool database, and workflows
|
|
|
|
# Color definitions
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
BLUE='\033[0;34m'
|
|
YELLOW='\033[1;33m'
|
|
CYAN='\033[0;36m'
|
|
MAGENTA='\033[0;35m'
|
|
NC='\033[0m'
|
|
|
|
# Help system paths
|
|
TOOLS_DB="${TOOLS_DB:-/opt/remnux-docs/tools.db}"
|
|
CHEAT_DIR="${CHEAT_DIR:-/opt/cheatsheets}"
|
|
WORKFLOW_DIR="${WORKFLOW_DIR:-/opt/remnux-docs/workflows}"
|
|
TLDR_CACHE="${TLDR_CACHE:-/home/remnux/.local/share/tldr}"
|
|
WIKI_DIR="${WIKI_DIR:-/opt/wiki}"
|
|
|
|
# Resolve cheat file names from a user-provided tool name
|
|
# Tries several variants: exact, without .py, with .py, hyphen/underscore alternatives
|
|
resolve_cheat_file() {
|
|
local name="$1"
|
|
local base=$(echo "$name" | sed 's/\.[Pp][Yy]$//')
|
|
|
|
# candidates to try in order
|
|
local candidates=(
|
|
"$name"
|
|
"$base"
|
|
"${base}.py"
|
|
"${base//_/}"
|
|
"${base//-/_}"
|
|
"${base//_/-}"
|
|
)
|
|
|
|
for cand in "${candidates[@]}"; do
|
|
if [[ -f "$CHEAT_DIR/personal/$cand" ]]; then
|
|
echo "$CHEAT_DIR/personal/$cand"
|
|
return 0
|
|
fi
|
|
if [[ -f "$CHEAT_DIR/personal/${cand}.cheat" ]]; then
|
|
echo "$CHEAT_DIR/personal/${cand}.cheat"
|
|
return 0
|
|
fi
|
|
if [[ -f "$CHEAT_DIR/${cand}.cheat" ]]; then
|
|
echo "$CHEAT_DIR/${cand}.cheat"
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
show_main_help() {
|
|
echo -e "${CYAN}REMnux Analysis Container Help System${NC}"
|
|
echo "======================================="
|
|
echo ""
|
|
echo -e "${GREEN}Getting Started:${NC}"
|
|
echo " fhelp start - Quick start guide (30 seconds)"
|
|
echo ""
|
|
echo -e "${GREEN}Find Tools:${NC}"
|
|
echo " fhelp tools <keyword> - Search by name or category"
|
|
echo " fhelp tools --interactive - Interactive browser (fzf)"
|
|
echo " Ctrl+G - Interactive cheatsheet browser (navi)"
|
|
echo ""
|
|
echo -e "${GREEN}Get Examples:${NC}"
|
|
echo " fhelp cheat <tool> - Usage examples for a specific tool"
|
|
echo " fhelp quick <command> - Quick tldr examples"
|
|
echo " F1 / Ctrl+/ - Help for command you're typing (zsh)"
|
|
echo ""
|
|
echo -e "${GREEN}Analysis Workflows:${NC}"
|
|
echo " fhelp workflow - List all 8 analysis workflows"
|
|
echo " fhelp workflow <name> - Show step-by-step workflow"
|
|
echo ""
|
|
echo -e "${GREEN}Wiki:${NC}"
|
|
echo " fhelp wiki - Browse the analysis wiki (zk)"
|
|
echo " fhelp wiki <tool> - Open a specific wiki page"
|
|
echo ""
|
|
echo -e "${GREEN}Other:${NC}"
|
|
echo " fhelp coverage - Help coverage statistics"
|
|
echo " fhelp examples - Browse all cheat sheets"
|
|
echo " fhelp --offline - Verify offline capabilities"
|
|
echo ""
|
|
echo -e "${YELLOW}Shortcuts:${NC} analyse, h, ? (all run fhelp)"
|
|
echo ""
|
|
echo -e "${YELLOW}Examples:${NC}"
|
|
echo " fhelp tools pdf # Find PDF analysis tools"
|
|
echo " fhelp cheat pdfid.py # pdfid.py usage examples"
|
|
echo " fhelp workflow static # Static analysis workflow"
|
|
}
|
|
|
|
show_start() {
|
|
echo -e "${CYAN}Quick Start Guide${NC}"
|
|
echo "================="
|
|
echo ""
|
|
|
|
# Count tools
|
|
local tool_count=0
|
|
local rich_count=0
|
|
if [[ -f "$TOOLS_DB" ]]; then
|
|
tool_count=$(wc -l < "$TOOLS_DB" 2>/dev/null || echo 0)
|
|
rich_count=$(grep -c '|rich$' "$TOOLS_DB" 2>/dev/null || echo 0)
|
|
fi
|
|
|
|
echo -e " This container has ${GREEN}${tool_count} analysis tools${NC} installed."
|
|
echo -e " ${GREEN}${rich_count}${NC} have detailed help with FOR610 lab examples."
|
|
echo ""
|
|
echo -e "${YELLOW}1. Find a tool:${NC}"
|
|
echo " fhelp tools pdf # search by keyword"
|
|
echo " fhelp tools --interactive # browse with fuzzy search"
|
|
echo ""
|
|
echo -e "${YELLOW}2. Get usage examples:${NC}"
|
|
echo " fhelp cheat pdfid.py # cheat sheet with examples"
|
|
echo " fhelp cheat oledump.py # Office document analysis"
|
|
echo " fhelp cheat capa # malware capabilities"
|
|
echo ""
|
|
echo -e "${YELLOW}3. Follow a workflow:${NC}"
|
|
echo " fhelp workflow # list all workflows"
|
|
echo " fhelp workflow static # static analysis steps"
|
|
echo " fhelp workflow document # document analysis steps"
|
|
echo ""
|
|
echo -e "${YELLOW}4. Interactive help:${NC}"
|
|
echo -e " ${GREEN}Ctrl+G${NC} # browse cheatsheets (navi)"
|
|
echo -e " ${GREEN}F1${NC} or ${GREEN}Ctrl+/${NC} # help for command you're typing (zsh)"
|
|
echo ""
|
|
echo -e "${YELLOW}5. Tool tiers:${NC}"
|
|
echo -e " ${GREEN}[FOR610]${NC} Rich help with lab examples and workflows"
|
|
echo -e " ${BLUE}[docs]${NC} Standard help from REMnux documentation"
|
|
echo -e " ${YELLOW}[basic]${NC} Minimal help (try: tool --help)"
|
|
echo ""
|
|
echo "Mount your files to /work/ and start analyzing!"
|
|
}
|
|
|
|
show_cheat() {
|
|
local tool="$1"
|
|
|
|
if [[ -z "$tool" ]]; then
|
|
echo -e "${RED}Please specify a tool name${NC}"
|
|
echo "Usage: fhelp cheat <tool>"
|
|
return 1
|
|
fi
|
|
|
|
# Check for specific workflow cheat sheets first
|
|
local cheat_file=""
|
|
case "$tool" in
|
|
"pdf"|"pdf-analysis")
|
|
cheat_file="$CHEAT_DIR/pdf-analysis.cheat"
|
|
;;
|
|
"malware"|"malware-analysis")
|
|
cheat_file="$CHEAT_DIR/malware-analysis.cheat"
|
|
;;
|
|
"system"|"system-utilities")
|
|
cheat_file="$CHEAT_DIR/system-utilities.cheat"
|
|
;;
|
|
*)
|
|
cheat_file=""
|
|
;;
|
|
esac
|
|
|
|
# If not a workflow cheat, try to resolve tool-specific cheat
|
|
if [[ -z "$cheat_file" || ! -f "$cheat_file" ]]; then
|
|
cheat_file=$(resolve_cheat_file "$tool") || cheat_file=""
|
|
fi
|
|
|
|
if [[ -n "$cheat_file" && -f "$cheat_file" ]]; then
|
|
echo -e "${CYAN}Cheat Sheet: ${YELLOW}$tool${NC}"
|
|
echo "$(printf '=%.0s' $(seq 1 $((${#tool} + 14))))"
|
|
echo ""
|
|
# Display cheat file content (skip YAML frontmatter if present)
|
|
awk '/^---$/{if(++c==2) start=1; next} start || !/^---$/ && c!=1' "$cheat_file"
|
|
elif command -v cheat >/dev/null 2>&1 && cheat "$tool" >/dev/null 2>&1; then
|
|
# Fallback: try the cheat command
|
|
echo -e "${CYAN}Cheat Sheet (cheat): ${YELLOW}$tool${NC}"
|
|
echo "$(printf '=%.0s' $(seq 1 $((${#tool} + 22))))"
|
|
echo ""
|
|
cheat "$tool"
|
|
elif command -v tldr >/dev/null 2>&1 && tldr "$tool" >/dev/null 2>&1; then
|
|
# Fallback: try tldr
|
|
echo -e "${CYAN}Quick Reference (tldr): ${YELLOW}$tool${NC}"
|
|
echo "$(printf '=%.0s' $(seq 1 $((${#tool} + 24))))"
|
|
echo ""
|
|
tldr "$tool"
|
|
else
|
|
echo -e "${YELLOW}No help found for '$tool'${NC}"
|
|
echo ""
|
|
# Suggest similar tools
|
|
if [[ -f "$TOOLS_DB" ]]; then
|
|
local matches=$(grep -i "$tool" "$TOOLS_DB" 2>/dev/null | head -5)
|
|
if [[ -n "$matches" ]]; then
|
|
echo "Did you mean one of these?"
|
|
echo "$matches" | while IFS='|' read -r name desc cat usage tier; do
|
|
local badge=""
|
|
case "$tier" in
|
|
rich) badge="${GREEN}[FOR610]${NC}" ;;
|
|
standard) badge="${BLUE}[docs]${NC}" ;;
|
|
*) badge="${YELLOW}[basic]${NC}" ;;
|
|
esac
|
|
echo -e " ${GREEN}$name${NC} $badge - $desc"
|
|
done
|
|
fi
|
|
fi
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
show_quick() {
|
|
local command="$1"
|
|
|
|
if [[ -z "$command" ]]; then
|
|
echo -e "${RED}Please specify a command name${NC}"
|
|
echo "Usage: fhelp quick <command>"
|
|
return 1
|
|
fi
|
|
|
|
echo -e "${CYAN}Quick examples for: ${YELLOW}$command${NC}"
|
|
echo ""
|
|
|
|
if command -v tldr >/dev/null 2>&1; then
|
|
if ! tldr "$command" 2>/dev/null; then
|
|
echo -e "${YELLOW}No tldr page found for '$command'${NC}"
|
|
echo "Try: fhelp cheat $command"
|
|
fi
|
|
else
|
|
echo -e "${RED}tldr command not available${NC}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
show_tools() {
|
|
local search_term="$1"
|
|
local option="$2"
|
|
|
|
case "$search_term" in
|
|
"--interactive")
|
|
if command -v find-tool >/dev/null 2>&1; then
|
|
find-tool --interactive
|
|
else
|
|
echo -e "${RED}find-tool not available${NC}"
|
|
fi
|
|
return
|
|
;;
|
|
"--list")
|
|
if command -v find-tool >/dev/null 2>&1; then
|
|
find-tool --list
|
|
else
|
|
echo -e "${RED}find-tool not available${NC}"
|
|
fi
|
|
return
|
|
;;
|
|
esac
|
|
|
|
if [[ -z "$search_term" ]]; then
|
|
echo -e "${RED}Please provide a search term${NC}"
|
|
echo "Usage: fhelp tools <search_term>"
|
|
echo " fhelp tools --interactive"
|
|
echo " fhelp tools --list"
|
|
return 1
|
|
fi
|
|
|
|
echo -e "${CYAN}Searching analysis tools for '${YELLOW}$search_term${CYAN}'...${NC}"
|
|
echo ""
|
|
|
|
if command -v find-tool >/dev/null 2>&1; then
|
|
find-tool "$search_term"
|
|
elif [[ -f "$TOOLS_DB" ]]; then
|
|
# Fallback: direct grep on tools.db
|
|
local results=$(grep -i "$search_term" "$TOOLS_DB" 2>/dev/null)
|
|
if [[ -n "$results" ]]; then
|
|
echo "$results" | while IFS='|' read -r name desc cat usage tier; do
|
|
local tier_badge=""
|
|
case "$tier" in
|
|
rich) tier_badge="${GREEN}[FOR610]${NC}" ;;
|
|
standard) tier_badge="${BLUE}[docs]${NC}" ;;
|
|
basic) tier_badge="${YELLOW}[basic]${NC}" ;;
|
|
*) tier_badge="" ;;
|
|
esac
|
|
echo -e " ${GREEN}$name${NC} $tier_badge"
|
|
echo " $desc"
|
|
echo " Usage: $usage"
|
|
echo ""
|
|
done
|
|
else
|
|
echo "No tools found matching '$search_term'"
|
|
fi
|
|
else
|
|
echo -e "${RED}No tools database available${NC}"
|
|
fi
|
|
}
|
|
|
|
show_examples() {
|
|
echo -e "${CYAN}Available Command Examples${NC}"
|
|
echo ""
|
|
|
|
if [[ -d "$CHEAT_DIR/personal" ]]; then
|
|
local count=$(ls -1 "$CHEAT_DIR/personal/"*.cheat 2>/dev/null | wc -l)
|
|
echo -e "${GREEN}Per-tool cheat sheets: $count${NC} (use: fhelp cheat <name>)"
|
|
echo ""
|
|
# Show a sample of tools grouped by first letter
|
|
ls -1 "$CHEAT_DIR/personal/"*.cheat 2>/dev/null | sed 's|.*/||; s|\.cheat$||' | head -30 | sed 's/^/ /'
|
|
if [[ $count -gt 30 ]]; then
|
|
echo " ... and $((count - 30)) more"
|
|
fi
|
|
echo ""
|
|
fi
|
|
|
|
if [[ -d "$CHEAT_DIR" ]]; then
|
|
echo -e "${GREEN}Workflow cheat sheets:${NC}"
|
|
ls -1 "$CHEAT_DIR"/*.cheat 2>/dev/null | sed 's|.*/||; s|\.cheat$||' | sed 's/^/ /'
|
|
echo ""
|
|
fi
|
|
|
|
echo -e "${GREEN}Analysis workflows:${NC} (use: fhelp workflow <name>)"
|
|
if [[ -d "$WORKFLOW_DIR" ]]; then
|
|
ls -1 "$WORKFLOW_DIR"/*.txt 2>/dev/null | sed 's|.*/||; s|\.txt$||' | grep -v index | sed 's/^/ /'
|
|
else
|
|
echo " static-analysis, behavioral-analysis, network-interception"
|
|
echo " document-analysis, javascript-deobfuscation, unpacking"
|
|
echo " code-injection, dotnet-analysis"
|
|
fi
|
|
}
|
|
|
|
show_workflow() {
|
|
local name="$1"
|
|
|
|
if [[ -z "$name" ]]; then
|
|
# Show workflow index
|
|
if [[ -f "$WORKFLOW_DIR/index.txt" ]]; then
|
|
cat "$WORKFLOW_DIR/index.txt"
|
|
else
|
|
echo -e "${CYAN}Available Analysis Workflows${NC}"
|
|
echo "=============================="
|
|
echo ""
|
|
echo " static-analysis-workflow Static Properties Analysis"
|
|
echo " behavioral-analysis-workflow Behavioral Analysis"
|
|
echo " network-interception-workflow Network Interception"
|
|
echo " document-analysis-workflow Malicious Document Analysis"
|
|
echo " javascript-deobfuscation-workflow JavaScript Deobfuscation"
|
|
echo " unpacking-workflow Unpacking Packed Executables"
|
|
echo " code-injection-workflow Code Injection Analysis"
|
|
echo " dotnet-analysis-workflow .NET Malware Analysis"
|
|
echo ""
|
|
echo "Usage: fhelp workflow <name>"
|
|
echo "Example: fhelp workflow static-analysis"
|
|
fi
|
|
return
|
|
fi
|
|
|
|
# Normalize name: allow partial matches
|
|
local wf_file=""
|
|
|
|
# Try exact match first
|
|
if [[ -f "$WORKFLOW_DIR/${name}.txt" ]]; then
|
|
wf_file="$WORKFLOW_DIR/${name}.txt"
|
|
elif [[ -f "$WORKFLOW_DIR/${name}-workflow.txt" ]]; then
|
|
wf_file="$WORKFLOW_DIR/${name}-workflow.txt"
|
|
else
|
|
# Fuzzy match: find workflow files containing the search term
|
|
if [[ -d "$WORKFLOW_DIR" ]]; then
|
|
wf_file=$(ls -1 "$WORKFLOW_DIR"/*.txt 2>/dev/null | grep -i "$name" | grep -v index | head -1)
|
|
fi
|
|
fi
|
|
|
|
if [[ -n "$wf_file" && -f "$wf_file" ]]; then
|
|
cat "$wf_file"
|
|
else
|
|
echo -e "${YELLOW}No workflow found matching '$name'${NC}"
|
|
echo ""
|
|
show_workflow # Show list
|
|
fi
|
|
}
|
|
|
|
show_coverage() {
|
|
echo -e "${CYAN}Help Coverage Statistics${NC}"
|
|
echo "========================"
|
|
echo ""
|
|
|
|
if [[ -f "$TOOLS_DB" ]]; then
|
|
local total=$(wc -l < "$TOOLS_DB" 2>/dev/null || echo 0)
|
|
local rich=$(grep -c '|rich$' "$TOOLS_DB" 2>/dev/null || echo 0)
|
|
local standard=$(grep -c '|standard$' "$TOOLS_DB" 2>/dev/null || echo 0)
|
|
local basic=$(grep -c '|basic$' "$TOOLS_DB" 2>/dev/null || echo 0)
|
|
|
|
echo -e " Tools in database: ${GREEN}$total${NC}"
|
|
echo -e " Rich help (FOR610): ${GREEN}$rich${NC}"
|
|
echo -e " Standard (docs): ${BLUE}$standard${NC}"
|
|
echo -e " Basic: ${YELLOW}$basic${NC}"
|
|
else
|
|
echo " Tools database not available"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
if [[ -d "$CHEAT_DIR/personal" ]]; then
|
|
local cheats=$(ls -1 "$CHEAT_DIR/personal/"*.cheat 2>/dev/null | wc -l)
|
|
echo -e " Cheat sheets: ${GREEN}$cheats${NC}"
|
|
fi
|
|
|
|
if [[ -d "$WORKFLOW_DIR" ]]; then
|
|
local wfs=$(ls -1 "$WORKFLOW_DIR"/*.txt 2>/dev/null | grep -cv index 2>/dev/null || echo 0)
|
|
echo -e " Workflows: ${GREEN}$wfs${NC}"
|
|
fi
|
|
}
|
|
|
|
show_offline_status() {
|
|
echo -e "${CYAN}Offline Capability Check${NC}"
|
|
echo "==========================="
|
|
echo ""
|
|
echo "Documentation Tools:"
|
|
|
|
local tools=("find-tool" "cheat" "tldr")
|
|
for tool in "${tools[@]}"; do
|
|
if command -v "$tool" >/dev/null 2>&1; then
|
|
echo -e " ${GREEN}+ $tool - available${NC}"
|
|
else
|
|
echo -e " ${RED}- $tool - missing${NC}"
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
echo "Documentation Files:"
|
|
|
|
if [[ -f "$TOOLS_DB" ]]; then
|
|
local db_count=$(wc -l < "$TOOLS_DB" 2>/dev/null || echo 0)
|
|
echo -e " ${GREEN}+ tools.db - $db_count tools${NC}"
|
|
else
|
|
echo -e " ${RED}- tools.db - missing${NC}"
|
|
fi
|
|
|
|
if [[ -d "$CHEAT_DIR/personal" ]]; then
|
|
local cheat_count=$(ls -1 "$CHEAT_DIR/personal/"*.cheat 2>/dev/null | wc -l)
|
|
echo -e " ${GREEN}+ cheatsheets - $cheat_count files${NC}"
|
|
else
|
|
echo -e " ${RED}- cheatsheets - missing${NC}"
|
|
fi
|
|
|
|
if [[ -d "$WORKFLOW_DIR" ]]; then
|
|
local wf_count=$(ls -1 "$WORKFLOW_DIR"/*.txt 2>/dev/null | grep -cv index 2>/dev/null || echo 0)
|
|
echo -e " ${GREEN}+ workflows - $wf_count workflows${NC}"
|
|
else
|
|
echo -e " ${RED}- workflows - missing${NC}"
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${GREEN}Offline help system ready!${NC}"
|
|
}
|
|
|
|
show_wiki() {
|
|
local query="$1"
|
|
|
|
if [[ ! -d "$WIKI_DIR" ]]; then
|
|
echo -e "${RED}Wiki not installed at $WIKI_DIR${NC}"
|
|
return 1
|
|
fi
|
|
|
|
if [[ -z "$query" ]]; then
|
|
# Interactive browse
|
|
if command -v zk >/dev/null 2>&1; then
|
|
cd "$WIKI_DIR" && zk list --interactive
|
|
elif command -v fzf >/dev/null 2>&1; then
|
|
local selected
|
|
selected=$(find "$WIKI_DIR" -name '*.md' -not -path '*/.zk/*' | sort | fzf --preview "cat {}")
|
|
if [[ -n "$selected" ]]; then
|
|
cat "$selected"
|
|
fi
|
|
else
|
|
echo -e "${CYAN}Wiki pages:${NC}"
|
|
find "$WIKI_DIR" -name '*.md' -not -path '*/.zk/*' | sort | sed "s|$WIKI_DIR/||" | sed 's/^/ /'
|
|
fi
|
|
else
|
|
# Search for specific page
|
|
local found=""
|
|
local search_slug=$(echo "$query" | tr '[:upper:]' '[:lower:]' | sed 's/\.py$//' | sed 's/[^a-z0-9]/-/g' | sed 's/-$//')
|
|
|
|
# Try exact matches
|
|
for dir in tools workflows recipes categories; do
|
|
if [[ -f "$WIKI_DIR/$dir/$search_slug.md" ]]; then
|
|
found="$WIKI_DIR/$dir/$search_slug.md"
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Try fuzzy match
|
|
if [[ -z "$found" ]]; then
|
|
found=$(find "$WIKI_DIR" -name "*${search_slug}*" -name '*.md' -not -path '*/.zk/*' | head -1)
|
|
fi
|
|
|
|
if [[ -n "$found" && -f "$found" ]]; then
|
|
echo -e "${CYAN}Wiki: ${YELLOW}$(basename "$found" .md)${NC}"
|
|
echo "$(printf '=%.0s' $(seq 1 60))"
|
|
echo ""
|
|
cat "$found"
|
|
else
|
|
echo -e "${YELLOW}No wiki page found for '$query'${NC}"
|
|
if command -v zk >/dev/null 2>&1; then
|
|
echo "Try: fhelp wiki (interactive browse)"
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
show_all() {
|
|
echo -e "${CYAN}Complete Help System Overview${NC}"
|
|
echo "================================="
|
|
echo ""
|
|
|
|
show_coverage
|
|
echo ""
|
|
show_workflow
|
|
echo ""
|
|
show_offline_status
|
|
}
|
|
|
|
# Main command parsing
|
|
case "${1:-}" in
|
|
"start"|"quickstart"|"getting-started")
|
|
show_start
|
|
;;
|
|
"tools")
|
|
shift
|
|
show_tools "$@"
|
|
;;
|
|
"cheat")
|
|
shift
|
|
show_cheat "$@"
|
|
;;
|
|
"quick")
|
|
shift
|
|
show_quick "$@"
|
|
;;
|
|
"examples")
|
|
show_examples
|
|
;;
|
|
"workflow")
|
|
shift
|
|
show_workflow "$@"
|
|
;;
|
|
"pdf")
|
|
show_workflow "document-analysis"
|
|
;;
|
|
"malware")
|
|
show_workflow "static-analysis"
|
|
;;
|
|
"forensics")
|
|
show_workflow "behavioral-analysis"
|
|
;;
|
|
"wiki")
|
|
shift
|
|
show_wiki "$@"
|
|
;;
|
|
"coverage")
|
|
show_coverage
|
|
;;
|
|
"--offline")
|
|
show_offline_status
|
|
;;
|
|
"--all")
|
|
show_all
|
|
;;
|
|
"--help"|"-h"|"help"|"")
|
|
show_main_help
|
|
;;
|
|
*)
|
|
# Try as workflow name first, then show error
|
|
if [[ -d "$WORKFLOW_DIR" ]] && ls "$WORKFLOW_DIR"/*.txt 2>/dev/null | grep -qi "$1"; then
|
|
show_workflow "$1"
|
|
else
|
|
echo -e "${RED}Unknown option: $1${NC}"
|
|
echo ""
|
|
show_main_help
|
|
fi
|
|
;;
|
|
esac
|