├── .gitignore
├── macOS
├── welcome.txt
├── entitlements.plist
└── Distribution.xml
├── SECURITY.md
├── tests
└── goss.yaml
├── go.mod
├── Dockerfile
├── .github
└── workflows
│ ├── publish.yml
│ ├── release.yml
│ └── go.yml
├── go.sum
├── README.md
├── NOTICE.txt
├── Makefile
├── LICENSE.txt
├── release-notes.txt
└── fmcsadmin_test.go
/.gitignore:
--------------------------------------------------------------------------------
1 | *.out
2 | .glide/
3 | .DS_Store
4 | bin
5 | dist
6 |
--------------------------------------------------------------------------------
/macOS/welcome.txt:
--------------------------------------------------------------------------------
1 | fmcsadmin is the command line tool to administer the Database Server component of Claris FileMaker Server via Claris FileMaker Admin API.
--------------------------------------------------------------------------------
/macOS/entitlements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.network.client
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | The latest minor version of fmcsadmin 2 is supported.
6 |
7 | | Version | Supported |
8 | | ------- | - |
9 | | 2.3.x | ✅ |
10 | | < 2.3 | ❌ |
11 |
12 | ## Reporting a Vulnerability
13 |
14 | Please open an issue or contact the main author directly (famlog at gmail).
15 |
--------------------------------------------------------------------------------
/tests/goss.yaml:
--------------------------------------------------------------------------------
1 | command:
2 | {{if .Env.OS | regexMatch "(darwin|linux)"}}
3 | print-version:
4 | exec: "./fmcsadmin -v"
5 | exit-status: 0
6 | stdout:
7 | - "2.3.0"
8 | {{end}}
9 |
10 | {{if eq .Env.OS "windows"}}
11 | print-version:
12 | exec: "fmcsadmin.exe -v"
13 | exit-status: 0
14 | stdout: "fmcsadmin 2.3.0\n"
15 | {{end}}
16 |
17 | {{if eq .Env.OS "darwin"}}
18 | check-universal-binary-or-not:
19 | exec: "file ./fmcsadmin"
20 | exit-status: 0
21 | stdout:
22 | - "Mach-O 64-bit executable x86_64"
23 | - "Mach-O 64-bit executable arm64"
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/emic/fmcsadmin
2 |
3 | go 1.23.0
4 |
5 | toolchain go1.23.7
6 |
7 | require (
8 | github.com/golang-jwt/jwt/v5 v5.2.1
9 | github.com/mattn/go-scan v0.0.0-20200228002420-2250e6e52487
10 | github.com/olekukonko/tablewriter v0.0.5
11 | github.com/stretchr/testify v1.10.0
12 | golang.org/x/term v0.30.0
13 | )
14 |
15 | require (
16 | github.com/davecgh/go-spew v1.1.1 // indirect
17 | github.com/mattn/go-runewidth v0.0.16 // indirect
18 | github.com/pmezard/go-difflib v1.0.0 // indirect
19 | github.com/rivo/uniseg v0.4.7 // indirect
20 | golang.org/x/sys v0.31.0 // indirect
21 | gopkg.in/yaml.v3 v3.0.1 // indirect
22 | )
23 |
--------------------------------------------------------------------------------
/macOS/Distribution.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | fmcsadmin 2.3.0
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | fmcsadmin.pkg
18 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM --platform=linux/x86_64 ubuntu:24.04
2 |
3 | RUN apt update && apt install -y curl tar make bash git build-essential
4 |
5 | # Install Go
6 | WORKDIR /root
7 |
8 | RUN curl -LO https://go.dev/dl/go1.22.10.linux-amd64.tar.gz && tar -C /tmp -xzf go1.22.10.linux-amd64.tar.gz && rm -f /root/go1.22.10.linux-amd64.tar.gz && mv /tmp/go go1.22
9 |
10 | WORKDIR /root/go/src/go.googlesource.com/go
11 |
12 | RUN git clone https://go.googlesource.com/go goroot && cd goroot && git checkout release-branch.go1.23 && cd src && export GOROOT_BOOTSTRAP=/root/go1.22 && ./all.bash
13 |
14 | RUN cp -pr /root/go/src/go.googlesource.com/go/goroot /usr/local/go
15 |
16 | RUN /usr/local/go/bin/go version
17 |
18 | # Install Goss
19 | WORKDIR /root/go/src/github.com/goss-org
20 |
21 | ARG GOSS_VERSION="0.4.9"
22 | ARG GOSS_COMMIT_HASH="5704120d25902119cb1139e04bca3db7742a9f73"
23 |
24 | RUN curl -L https://github.com/goss-org/goss/archive/${GOSS_COMMIT_HASH}.tar.gz | tar -xzvf -
25 |
26 | RUN mv goss-${GOSS_COMMIT_HASH} goss && cd goss && PATH=$PATH:/usr/local/go/bin TRAVIS_TAG=${GOSS_VERSION} make build
27 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Image
2 |
3 | on:
4 | push:
5 | paths:
6 | - 'Dockerfile'
7 |
8 | jobs:
9 | publish:
10 | name: Publish Image
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: Checkout
14 | uses: actions/checkout@v4
15 | - name: Set up QEMU
16 | uses: docker/setup-qemu-action@v3
17 | - name: Set up Docker Buildx
18 | uses: docker/setup-buildx-action@v3
19 | - name: Login to GitHub Container Registry
20 | uses: docker/login-action@v3
21 | with:
22 | registry: ghcr.io
23 | username: ${{ github.actor }}
24 | password: ${{ secrets.GHCR_TOKEN_202507 }}
25 | - name: Container meta
26 | id: meta
27 | uses: docker/metadata-action@v5
28 | with:
29 | images: ghcr.io/matsuo/goss
30 | tags: |
31 | type=raw,value=latest
32 | type=sha,prefix=,suffix=,format=short
33 | - name: Push to GitHub Container Registry
34 | uses: docker/build-push-action@v6
35 | with:
36 | context: .
37 | push: true
38 | tags: ${{ steps.meta.outputs.tags }}
39 | labels: ${{ steps.meta.outputs.labels }}
40 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3 | github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
4 | github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
5 | github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
6 | github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
7 | github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
8 | github.com/mattn/go-scan v0.0.0-20200228002420-2250e6e52487 h1:FsO95DVHMp/Eldk9cjfPdO+aCM8csjrsMX6daS0xFuE=
9 | github.com/mattn/go-scan v0.0.0-20200228002420-2250e6e52487/go.mod h1:sNJr+MyYo/WAx30FGeqHkJGtNyqmD6oQyfHrwC/tDVo=
10 | github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
11 | github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
12 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
13 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
14 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
15 | github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
16 | github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
17 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
18 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
19 | golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
20 | golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
21 | golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
22 | golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
23 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
24 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
25 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
26 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | fmcsadmin [](https://github.com/emic/fmcsadmin/actions/workflows/go.yml)
2 | =========
3 | fmcsadmin is a command line tool to administer the Database Server component of Claris FileMaker Server via Claris FileMaker Admin API. fmcsadmin supports public key authentication and remote server administration.
4 |
5 | Features
6 | -----
7 | - Close databases
8 | - Delete a schedule
9 | - Disable schedules
10 | - Disconnect clients
11 | - Enable schedules
12 | - List clients, databases or schedules
13 | - Open databases
14 | - Temporarily stop database access
15 | - Make paused databases available
16 | - Run a schedule
17 | - Send a message to clients
18 | - Start a server process
19 | - Restart a server process
20 | - Stop a server process
21 | - Retrieve server or CWP configuration settings
22 | - Change server or CWP configuration settings
23 | - List plug-ins
24 | - Manage SSL certificates
25 | - Move databases out of hosted folder
26 | - View and change the setting for sharing streaming URLs
27 | - Cancel the currently running backup
28 | - View and change the setting for parallel backup
29 | - FileMaker Admin API PKI Authentication
30 | - View and change the settings for the persistent cache (for FileMaker Server 2024)
31 | - View and change the setting for blocking new users (for FileMaker Server 2024)
32 | - View and change the HTTPS tunneling setting for FileMaker Pro and FileMaker Go (for FileMaker Server 2024 (21.1))
33 | - View and change the "Only open last opened databases" setting (for FileMaker Server 2024 (21.1))
34 |
35 | Supported Servers
36 | -----
37 | Please see details: https://support.claris.com/s/article/Claris-support-policy?language=en_US
38 | - Claris FileMaker Server 2024 (until June 2026)
39 | - Claris FileMaker Server 2023 (until Apr 2025)
40 |
41 | Usage
42 | -----
43 | You can script many tasks with fmcsadmin by using a scripting language that allows execution of shell or terminal commands.
44 |
45 | ```
46 | fmcsadmin HELP COMMANDS
47 | Lists available commands
48 |
49 | fmcsadmin HELP [COMMAND]
50 | Displays help on the specified COMMAND
51 |
52 | fmcsadmin HELP OPTIONS
53 | Lists available options
54 | ```
55 | Note: Handling schedule ID 1 is not supported for FileMaker Server.
56 |
57 | Noteworthy Options
58 | -----
59 | - --fqdn (for remote server administration)
60 | - -i (for PKI authentication)
61 |
62 | ```
63 | fmcsadmin --fqdn fms.example.com -i /path/to/IDENTITYFILE list files
64 | ```
65 |
66 | System Requirements
67 | -----
68 | - Linux version : Ubuntu 20.04 LTS, Ubuntu 22.04 LTS or Ubuntu 22.04 LTS for ARM
69 | - macOS version : macOS Ventura 13, macOS Sonoma 14 or macOS Sequoia 15
70 | - Windows version : Windows Server 2019, Windows Server 2022, Windows 10 Version 22H2, Windows 11 Version 22H2 or later
71 |
72 | Download
73 | -----
74 | Download from the [latest release page](https://github.com/emic/fmcsadmin/releases/latest).
75 |
76 | Author
77 | -----
78 | Emic Corporation
79 |
80 | License
81 | -----
82 | This software is distributed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0), see LICENSE.txt and NOTICE.txt for more information.
83 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | on:
4 | push:
5 | tags:
6 | - '*'
7 |
8 | jobs:
9 | build:
10 | name: Release
11 | runs-on: ${{ matrix.os }}
12 |
13 | strategy:
14 | matrix:
15 | # https://docs.github.com/ja/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners
16 | os: [ 'macos-latest' ]
17 | steps:
18 |
19 | - uses: actions/checkout@v4
20 |
21 | - name: Setup go
22 | uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
23 | with:
24 | cache: false
25 | go-version-file: 'go.mod'
26 | check-latest: true
27 |
28 | - run: make dist
29 |
30 |
31 | - name: Set version
32 | id: version
33 | run: |
34 | VERSION=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g")
35 | echo ::set-output name=version::$VERSION
36 |
37 | - name: Create release
38 | id: create_release
39 | uses: actions/create-release@0cb9c9b65d5d1901c1f53e5e66eaf4afd303e70e # v1.1.4
40 | if: startsWith(github.ref, 'refs/tags/')
41 | env:
42 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43 | with:
44 | tag_name: ${{ steps.version.outputs.version }}
45 | release_name: fmcadmin ${{ steps.version.outputs.version }} Released
46 | draft: true
47 | prerelease: false
48 |
49 | - name: Upload Release Asset for Linux (amd64)
50 | id: upload-release-asset-for-linux
51 | uses: actions/upload-release-asset@e8f9f06c4b078e705bd2ea027f0926603fc9b4d5 # v1.0.2
52 | if: startsWith(github.ref, 'refs/tags/')
53 | env:
54 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
55 | with:
56 | upload_url: ${{ steps.create_release.outputs.upload_url }}
57 | asset_path: ./dist/fmcsadmin-${{ steps.version.outputs.version }}-linux.tar.gz
58 | asset_name: fmcsadmin-${{ steps.version.outputs.version }}-linux.tar.gz
59 | asset_content_type: application/gzip
60 |
61 | - name: Upload Release Asset for Linux (arm64)
62 | id: upload-release-asset-for-linux-arm64
63 | uses: actions/upload-release-asset@e8f9f06c4b078e705bd2ea027f0926603fc9b4d5 # v1.0.2
64 | if: startsWith(github.ref, 'refs/tags/')
65 | env:
66 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
67 | with:
68 | upload_url: ${{ steps.create_release.outputs.upload_url }}
69 | asset_path: ./dist/fmcsadmin-${{ steps.version.outputs.version }}-linux-arm64.tar.gz
70 | asset_name: fmcsadmin-${{ steps.version.outputs.version }}-linux-arm64.tar.gz
71 | asset_content_type: application/gzip
72 |
73 | - name: Upload Release Asset for Windows (x64)
74 | id: upload-release-asset-for-windows-x64
75 | uses: actions/upload-release-asset@e8f9f06c4b078e705bd2ea027f0926603fc9b4d5 # v1.0.2
76 | if: startsWith(github.ref, 'refs/tags/')
77 | env:
78 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
79 | with:
80 | upload_url: ${{ steps.create_release.outputs.upload_url }}
81 | asset_path: ./dist/fmcsadmin-${{ steps.version.outputs.version }}-windows-x64.zip
82 | asset_name: fmcsadmin-${{ steps.version.outputs.version }}-windows-x64.zip
83 | asset_content_type: application/zip
84 |
--------------------------------------------------------------------------------
/NOTICE.txt:
--------------------------------------------------------------------------------
1 | fmcsadmin
2 | Copyright 2017-2025 Emic Corporation, https://www.emic.co.jp/
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 |
16 | ---
17 |
18 | go-scan
19 | Copyright © 2013-2020 Yasuhiro Matsumoto, http://mattn.kaoriya.net
20 |
21 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
22 |
23 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
24 |
25 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 |
27 | ---
28 |
29 | ASCII Table Writer
30 | Copyright (C) 2014 by Oleku Konko
31 |
32 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
33 |
34 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
35 |
36 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 |
38 | ---
39 |
40 | Copyright (c) 2012 Dave Grijalva
41 | Copyright (c) 2021 golang-jwt maintainers
42 |
43 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
44 |
45 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
46 |
47 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
48 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | NAME=fmcsadmin
2 | VERSION=2.3.0
3 |
4 | GOCMD=go
5 | GOBUILD=$(GOCMD) build
6 | GOTEST=$(GOCMD) test
7 | GOGET=$(GOCMD) get
8 | GOINSTALL=$(GOCMD) install
9 | DIST_DIR=dist
10 | LINUX_DIR=linux
11 | LINUX_ARM64_DIR=linux-arm64
12 | MACOS_DIR=macos
13 | MACOS_ALT_DIR=macos-alt
14 | WINDOWS_DIR=windows-x64
15 | DIST_LINUX_DIR=$(NAME)-$(VERSION)-$(LINUX_DIR)
16 | DIST_LINUX_ARM64_DIR=$(NAME)-$(VERSION)-$(LINUX_ARM64_DIR)
17 | DIST_MACOS_DIR=$(NAME)-$(VERSION)-$(MACOS_DIR)
18 | DIST_WINDOWS_DIR=$(NAME)-$(VERSION)-$(WINDOWS_DIR)
19 |
20 | all: test build
21 |
22 | deps:
23 | $(GOGET) github.com/golang-jwt/jwt/v5
24 | $(GOINSTALL) github.com/mattn/go-scan
25 | $(GOINSTALL) github.com/olekukonko/tablewriter
26 | $(GOINSTALL) golang.org/x/term
27 | $(GOINSTALL) github.com/stretchr/testify/assert
28 |
29 | test: deps
30 | $(GOTEST) --cover
31 |
32 | .PHONY: clean
33 | clean:
34 | @rm -rf $(DIST_DIR)
35 |
36 | build: build-linux build-linux-arm64 build-macos build-windows
37 |
38 | build-linux:
39 | mkdir -p $(DIST_DIR)/$(LINUX_DIR)
40 | GOOS=linux GOARCH=amd64 CGO_ENABLED=0 $(GOBUILD) -ldflags "-X main.version=$(VERSION)" -o $(DIST_DIR)/$(LINUX_DIR)/$(NAME)
41 |
42 | build-linux-arm64:
43 | mkdir -p $(DIST_DIR)/$(LINUX_ARM64_DIR)
44 | GOOS=linux GOARCH=arm64 CGO_ENABLED=0 $(GOBUILD) -ldflags "-X main.version=$(VERSION)" -o $(DIST_DIR)/$(LINUX_ARM64_DIR)/$(NAME)
45 |
46 | ifeq ($(shell uname -m),x86_64)
47 | build-macos:
48 | mkdir -p $(DIST_DIR)/$(MACOS_DIR)
49 | GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 $(GOBUILD) -ldflags "-X main.version=$(VERSION)" -o $(DIST_DIR)/$(MACOS_DIR)/$(NAME)
50 | else
51 | build-macos:
52 | mkdir -p $(DIST_DIR)/$(MACOS_DIR)
53 | GOOS=darwin GOARCH=arm64 CGO_ENABLED=0 $(GOBUILD) -ldflags "-X main.version=$(VERSION)" -o $(DIST_DIR)/$(MACOS_DIR)/$(NAME)
54 | endif
55 |
56 | ifeq ($(shell uname -m),x86_64)
57 | build-macos-alt:
58 | mkdir -p $(DIST_DIR)/$(MACOS_ALT_DIR)
59 | GOOS=darwin GOARCH=arm64 CGO_ENABLED=0 $(GOBUILD) -ldflags "-X main.version=$(VERSION)" -o $(DIST_DIR)/$(MACOS_ALT_DIR)/$(NAME)
60 | else
61 | build-macos-alt:
62 | mkdir -p $(DIST_DIR)/$(MACOS_ALT_DIR)
63 | GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 $(GOBUILD) -ldflags "-X main.version=$(VERSION)" -o $(DIST_DIR)/$(MACOS_ALT_DIR)/$(NAME)
64 | endif
65 |
66 | build-windows:
67 | mkdir -p $(DIST_DIR)/$(WINDOWS_DIR)
68 | GOOS=windows GOARCH=amd64 CGO_ENABLED=0 $(GOBUILD) -ldflags "-X main.version=$(VERSION)" -o $(DIST_DIR)/$(WINDOWS_DIR)/$(NAME).exe
69 |
70 | .PHONY: dist
71 | dist-multiplatform: deps build
72 | cd $(DIST_DIR) && \
73 | mv $(LINUX_DIR) $(DIST_LINUX_DIR) && \
74 | cp -p ../LICENSE.txt $(DIST_LINUX_DIR)/ && \
75 | cp -p ../NOTICE.txt $(DIST_LINUX_DIR)/ && \
76 | cp -p ../README.md $(DIST_LINUX_DIR)/ && \
77 | cp -p ../release-notes.txt $(DIST_LINUX_DIR)/ && \
78 | tar -zcf $(DIST_LINUX_DIR).tar.gz $(DIST_LINUX_DIR) && \
79 | cd ..
80 |
81 | cd $(DIST_DIR) && \
82 | mv $(LINUX_ARM64_DIR) $(DIST_LINUX_ARM64_DIR) && \
83 | cp -p ../LICENSE.txt $(DIST_LINUX_ARM64_DIR)/ && \
84 | cp -p ../NOTICE.txt $(DIST_LINUX_ARM64_DIR)/ && \
85 | cp -p ../README.md $(DIST_LINUX_ARM64_DIR)/ && \
86 | cp -p ../release-notes.txt $(DIST_LINUX_ARM64_DIR)/ && \
87 | tar -zcf $(DIST_LINUX_ARM64_DIR).tar.gz $(DIST_LINUX_ARM64_DIR) && \
88 | cd ..
89 |
90 | cd $(DIST_DIR) && \
91 | mv $(MACOS_DIR) $(DIST_MACOS_DIR) && \
92 | cp -p ../LICENSE.txt $(DIST_MACOS_DIR)/ && \
93 | cp -p ../NOTICE.txt $(DIST_MACOS_DIR)/ && \
94 | cp -p ../README.md $(DIST_MACOS_DIR)/ && \
95 | cp -p ../release-notes.txt $(DIST_MACOS_DIR)/ && \
96 | cd ..
97 |
98 | cd $(DIST_DIR) && \
99 | mv $(WINDOWS_DIR) $(DIST_WINDOWS_DIR) && \
100 | cp -p ../LICENSE.txt $(DIST_WINDOWS_DIR)/ && \
101 | cp -p ../NOTICE.txt $(DIST_WINDOWS_DIR)/ && \
102 | cp -p ../README.md $(DIST_WINDOWS_DIR)/ && \
103 | cp -p ../release-notes.txt $(DIST_WINDOWS_DIR)/ && \
104 | zip -r $(DIST_WINDOWS_DIR).zip $(DIST_WINDOWS_DIR) && \
105 | cd ..
106 |
107 | ifeq ($(shell uname),Darwin)
108 | dist: dist-multiplatform build-macos-alt
109 | cd $(DIST_DIR) && \
110 | mv $(DIST_MACOS_DIR)/$(NAME) $(DIST_MACOS_DIR)/$(NAME).tmp && \
111 | lipo -create $(DIST_MACOS_DIR)/$(NAME).tmp $(MACOS_ALT_DIR)/$(NAME) -output $(DIST_MACOS_DIR)/$(NAME) && \
112 | rm -f $(MACOS_ALT_DIR)/$(NAME) && \
113 | rmdir $(MACOS_ALT_DIR) && \
114 | rm -f $(DIST_MACOS_DIR)/$(NAME).tmp && \
115 | cd ..
116 | else
117 | dist: dist-multiplatform
118 | endif
--------------------------------------------------------------------------------
/.github/workflows/go.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on: [ push, pull_request ]
4 |
5 | jobs:
6 |
7 | build:
8 | name: Build
9 | runs-on: ${{ matrix.os }}
10 |
11 | strategy:
12 | matrix:
13 | # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners
14 | os: [ 'ubuntu-20.04', 'ubuntu-22.04', 'ubuntu-22.04-arm', 'ubuntu-24.04', 'ubuntu-24.04-arm', 'ubuntu-latest', 'macos-13', 'macos-14', 'macos-15', 'macos-latest', 'windows-2019', 'windows-2022', 'windows-2025', 'windows-latest' ]
15 | steps:
16 |
17 | - uses: actions/checkout@v4
18 |
19 | - name: Setup go
20 | uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
21 | with:
22 | cache: false
23 | go-version-file: 'go.mod'
24 | check-latest: true
25 |
26 | - run: go test
27 |
28 | - shell: bash
29 | run: cat Makefile | grep "^VERSION=" | sed -e "s/VERSION/fmcsadmin_version/g" >> "$GITHUB_ENV"
30 |
31 | - run: go build -ldflags "-X main.version=${{ env.fmcsadmin_version }}" fmcsadmin.go
32 |
33 | - if: runner.os == 'macOS'
34 | run: make dist && cp -p "dist/fmcsadmin-${{ env.fmcsadmin_version }}-macos/fmcsadmin" .
35 |
36 | - shell: bash
37 | run: echo "goss_commit_hash=5704120d25902119cb1139e04bca3db7742a9f73" >> "$GITHUB_ENV" # v0.4.9
38 |
39 | - if: runner.os == 'macOS' || runner.os == 'Windows'
40 | shell: bash
41 | run: echo "GOSS_USE_ALPHA=1" >> "$GITHUB_ENV"
42 |
43 | - if: runner.os == 'Linux' && (github.repository_owner == 'emic' || github.repository_owner == 'matsuo')
44 | name: Login to GitHub Container Registry
45 | uses: docker/login-action@v3
46 | with:
47 | registry: ghcr.io
48 | username: ${{ github.actor }}
49 | password: ${{ secrets.GHCR_TOKEN_202507 }}
50 |
51 | - if: (matrix.os == 'ubuntu-22.04' || matrix.os == 'ubuntu-24.04' || matrix.os == 'ubuntu-latest') && (github.repository_owner == 'emic' || github.repository_owner == 'matsuo')
52 | name: Pull from GitHub Container Registry
53 | run: |
54 | docker pull ghcr.io/matsuo/goss:latest
55 | docker run --rm -i -v /$(pwd):/tmp ghcr.io/matsuo/goss:latest bash <<'EOF'
56 | cd /root/go/src/github.com/goss-org/goss
57 | cp ./release/goss-darwin-amd64 /tmp/goss-darwin-amd64
58 | cp ./release/goss-darwin-arm64 /tmp/goss-darwin-arm64
59 | cp ./release/goss-linux-amd64 /tmp/goss-linux-amd64
60 | cp ./release/goss-linux-arm64 /tmp/goss-linux-arm64
61 | EOF
62 |
63 | - if: runner.os == 'macOS' || matrix.os == 'ubuntu-22.04-arm' || matrix.os == 'ubuntu-24.04-arm' || (runner.os == 'Linux' && !(github.repository_owner == 'emic' || github.repository_owner == 'matsuo'))
64 | run: |
65 | curl -L "https://github.com/goss-org/goss/archive/${{ env.goss_commit_hash }}.tar.gz" -o goss.tar.gz
66 | tar xzvf goss.tar.gz
67 | cd "goss-${{ env.goss_commit_hash }}"
68 | make build
69 | cd ..
70 |
71 | - if: runner.os == 'Windows'
72 | shell: bash
73 | run: |
74 | curl -L "https://github.com/goss-org/goss/archive/${{ env.goss_commit_hash }}.tar.gz" -o goss.tar.gz
75 | tar xzvf goss.tar.gz
76 | cd "goss-${{ env.goss_commit_hash }}"
77 | go build -o goss-windows-amd64.exe github.com/goss-org/goss/cmd/goss
78 | mkdir release
79 | mv goss-windows-amd64.exe release/
80 | cd ..
81 |
82 | - if: (matrix.os == 'ubuntu-22.04' || matrix.os == 'ubuntu-24.04' || matrix.os == 'ubuntu-latest') && (github.repository_owner == 'emic' || github.repository_owner == 'matsuo')
83 | run: |
84 | ./goss-linux-amd64 --version
85 | OS=linux ./goss-linux-amd64 --gossfile tests/goss.yaml validate --format documentation
86 |
87 | - if: (matrix.os == 'ubuntu-22.04' || matrix.os == 'ubuntu-24.04' || matrix.os == 'ubuntu-latest') && !(github.repository_owner == 'emic' || github.repository_owner == 'matsuo')
88 | run: |
89 | OS=linux "./goss-${{ env.goss_commit_hash }}/release/goss-linux-amd64" --gossfile tests/goss.yaml validate --format documentation
90 |
91 | - if: matrix.os == 'ubuntu-22.04-arm' || matrix.os == 'ubuntu-24.04-arm'
92 | run: |
93 | OS=linux "./goss-${{ env.goss_commit_hash }}/release/goss-linux-arm64" --gossfile tests/goss.yaml validate --format documentation
94 |
95 | - if: runner.os == 'macOS'
96 | run: |
97 | OS=darwin "./goss-${{ env.goss_commit_hash }}/release/goss-darwin-amd64" --gossfile tests/goss.yaml validate --format documentation
98 |
99 | - if: runner.os == 'Windows'
100 | shell: bash
101 | run: |
102 | OS=windows "./goss-${{ env.goss_commit_hash }}/release/goss-windows-amd64.exe" --gossfile tests/goss.yaml validate --format documentation
103 |
104 | - run: ./fmcsadmin -v
105 |
106 | - name: Create dmg format file for macOS
107 | if: runner.os == 'macOS'
108 | run: |
109 | lipo -info "dist/fmcsadmin-${{ env.fmcsadmin_version }}-macos/fmcsadmin"
110 | cd "dist/fmcsadmin-${{ env.fmcsadmin_version }}-macos"
111 | pkgbuild --root . --identifier jp.co.emic.fmcsadmin --version "${{ env.fmcsadmin_version }}" --install-location /usr/local/bin ../fmcsadmin.pkg
112 | cd ..
113 | cp -p ../{LICENSE.txt,README.md,NOTICE.txt,release-notes.txt} .
114 | cp -p ../macOS/{Distribution.xml,welcome.txt} .
115 | productbuild --distribution Distribution.xml --resources . --package-path fmcsadmin.pkg "fmcsadmin-${{ env.fmcsadmin_version }}-unsigned.pkg"
116 | cp -p "fmcsadmin-${{ env.fmcsadmin_version }}-unsigned.pkg" "fmcsadmin-${{ env.fmcsadmin_version }}.pkg"
117 | mkdir macos-dist
118 | mv "fmcsadmin-${{ env.fmcsadmin_version }}.pkg" macos-dist/
119 | mv {LICENSE.txt,README.md,NOTICE.txt,release-notes.txt} macos-dist/
120 | cd macos-dist
121 | cd ..
122 | hdiutil create -srcfolder ./macos-dist/ -fs HFS+ -format UDZO -volname "fmcsadmin-${{ env.fmcsadmin_version }}" "fmcsadmin-${{ env.fmcsadmin_version }}-macos.dmg"
123 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/release-notes.txt:
--------------------------------------------------------------------------------
1 | fmcsadmin
2 | (c) 2017-2025 Emic Corporation
3 | This software is distributed under the Apache License, Version 2.0, see LICENSE.txt and NOTICE.txt for more information.
4 |
5 | Version: 2.3.0
6 | Date: March 6, 2025
7 | - Add support for Claris FileMaker Server 2024 (21.1).
8 | - Add support for macOS Sequoia 15.
9 | - Update "GET SERVERPREFS" command to view the "Only open last opened databases" setting. (Usage: "fmcsadmin get serverprefs OnlyOpenLastOpenedDatabases")
10 | - Update "SET SERVERPREFS" command to open only the databases that were opened when the database server was last shut down. (Usage: "fmcsadmin set serverprefs OnlyOpenLastOpenedDatabases=true")
11 | - Update "GET SERVERPREFS" command to get the https tunneling setting for FileMaker Pro and FileMaker Go. (Usage: "fmcsadmin get serverprefs EnableHttpProtocolNetwork")
12 | - Update "SET SERVERPREFS" command to enable or disable the https tunneling for FileMaker Pro and FileMaker Go. (Usage: "fmcsadmin set serverprefs EnableHttpProtocolNetwork=true")
13 | - Change the error message displayed when executing "get serverprefs" command with invalid arguments on older versions of FileMaker Server.
14 | - Change the error message displayed when executing "set serverprefs" command with invalid arguments on older versions of FileMaker Server.
15 | - Built with Go 1.23.
16 | - [INFO] Drop support for Claris FileMaker Server 19.6.
17 | - [INFO] Drop support for macOS Monterey 12.
18 | - [INFO] Drop support for Windows 11 Version 21H2.
19 |
20 | Version: 2.2.0
21 | Date: August 28, 2024
22 | - Add support for Claris FileMaker Server 2024 (21.0).
23 | - Add support for Claris FileMaker Server 2023 (20.1, 20.2 and 20.3).
24 | - Add support for Ubuntu 22.04 LTS (on amd64 architecture).
25 | - Add support for Ubuntu 22.04 LTS on arm64 architecture.
26 | - Update "GET SERVERPREFS" command to get blocking new users setting for Claris FileMaker Server 2024 (21.0). (Usage: "fmcsadmin get serverprefs BlockNewUsersEnabled")
27 | - Update "SET SERVERPREFS" command to set blocking new users setting for Claris FileMaker Server 2024 (21.0). (Usage: "fmcsadmin set serverprefs BlockNewUsersEnabled=true")
28 | - Update "SET SERVERPREFS" command to set persistent cache setting for Claris FileMaker Server 2024 (21.0). (Usage: "fmcsadmin set serverprefs PersistCacheEnabled=true")
29 | - Update "SET SERVERPREFS" command to set persistent cache sync setting for Claris FileMaker Server 2024 (21.0). To change the value of SyncPersistCache to true, the value of PersistCacheEnabled must be true. (Usage: "fmcsadmin set serverprefs SyncPersistCache=true")
30 | - Update "GET SERVERPREFS" command to get database server auto restart setting for Claris FileMaker Server 2024 (21.0). (Usage: "fmcsadmin get serverprefs DatabaseServerAutoRestart")
31 | - Update "SET SERVERPREFS" command to set database server auto restart setting for Claris FileMaker Server 2024 (21.0). To change the value of DatabaseServerAutoRestart to true, the value of PersistCacheEnabled must be true. (Usage: "fmcsadmin set serverprefs DatabaseServerAutoRestart=true")
32 | - Update "GET SERVERPREFS" command to get persistent cache setting for Claris FileMaker Server 2023 (20.1) or later. (Usage: "fmcsadmin get serverprefs PersistCacheEnabled" or "fmcsadmin get serverprefs SyncPersistCache")
33 | - Update "GET SERVERPREFS" command to get persistent cache sync setting for Claris FileMaker Server 2023 (20.1) or later. (Usage: "fmcsadmin get serverprefs SyncPersistCache")
34 | - Update "GET SERVERCONFIG" command and "GET SERVERPREFS" command due to increasing the maximum number of hosted database files per FileMaker Server instance for Claris FileMaker Server 2023 or later.
35 | - Update "SET SERVERCONFIG" command and "SET SERVERPREFS" command due to increasing the maximum number of hosted database files per FileMaker Server instance for Claris FileMaker Server 2023 or later.
36 | - Modify behavior of outputting error messages for invalid parameters when using "GET SERVERPREFS" and "SET SERVERPREFS" command.
37 | - Add support for Windows Server 2019 and Windows Server 2022.
38 | - Tested with Claris FileMaker Server 2024 (21.0).
39 | - Tested on macOS Sonoma 14.
40 | - Built with Go 1.22.
41 | - [INFO] Drop support for Claris FileMaker Server 19.3, 19.4 and 19.5.
42 | - [INFO] Drop support for Ubuntu 18.04 LTS.
43 | - [INFO] Drop support for CentOS Linux 7.
44 | - [INFO] Drop support for Windows 10 Version 21H2.
45 | - [INFO] Drop support for macOS Big Sur 11.
46 | - [BUG FIX] Fix "SET SERVERPREFS" command was not executed correctly in some cases.
47 |
48 | Version: 2.1.0
49 | Date: May 17, 2023
50 | - Add "-i" option to specify a private key file for FileMaker Admin API PKI Authentication (requires Claris FileMaker Server 19.6.1 or later).
51 | - Update behavior of "GET CWPCONFIG" command and "SET CWPCONFIG" command on Linux for FileMaker Server 19.6.1 or later.
52 | - Detect an invalid configuration value when using "SET CWPCONFIG" command.
53 | - Tested with Claris FileMaker Server 19.6.
54 | - Tested on macOS Ventura 13.
55 | - Fix spelling in help messages.
56 | - Built with Go 1.19.
57 | - [INFO] Drop support for Claris FileMaker Server 19.0, 19.1 and 19.2.
58 | - [INFO] Drop support for macOS Catalina 10.15.
59 | - [INFO] Drop support for Windows 10 Version 21H1.
60 | - [BUG FIX] Fix causing unintended changes of the configuration settings for unspecified options in some cases when using "SET CWPCONFIG" command.
61 |
62 | Version: 2.0.0
63 | Date: June 27, 2022
64 | - Change to the Apache License, Version 2.0.
65 | - Support Ubuntu 20.04 LTS.
66 | - Add "CANCEL" command to cancel the currently running backup for Claris FileMaker Server 19.5.1. (Usage: "fmcsadmin cancel backup")
67 | - Update "GET SERVERPREFS" command to check the status of parallel backup for Claris FileMaker Server 19.5.1. (Usage: "fmcsadmin get serverprefs ParallelBackupEnabled")
68 | - Update "SET SERVERPREFS" command to enable or disable parallel backup for Claris FileMaker Server 19.5.1. (Usage: "fmcsadmin set serverprefs ParallelBackupEnabled=false")
69 | - Add support for credentials via environment variables (FMS_USERNAME and FMS_PASSWORD).
70 | - Add error messages for the FileMaker error code 956, 1702.
71 | - Change an error message when specifying the host name of Claris FileMaker Cloud with "--fqdn" option.
72 | - Tested with Claris FileMaker Server 19.5.
73 | - Tested on Windows 11 and macOS Monterey 12.
74 | - Built with Go 1.18.
75 | - [INFO] Drop support for Claris FileMaker Server 18 and FileMaker Cloud for AWS 1.18.
76 | - [INFO] Drop support for 32-bit Windows version.
77 | - [INFO] Drop support for Windows 10 Version 1903, 1909, 2004 and 20H2.
78 | - [INFO] Drop support for macOS Mojave 10.14.
79 | - [INFO] Drop support for CentOS Linux 8.
80 | - [BUG FIX] Improve DNS error handling when using "--fqdn" option.
81 | - [BUG FIX] Output an error message when using "SET SERVERPREFS" command to set streaming URL cookie check setting with unsupported versions of FileMaker Server. The affected version is 1.3.0 only.
82 |
83 | Version: 1.3.0
84 | Date: August 17, 2021
85 | - Support Ubuntu 18.04 LTS.
86 | - Support Apple Silicon on macOS.
87 | - Add "REMOVE" command to move databases out of hosted folder for Claris FileMaker Server 19.3.1.
88 | - Update "GET SERVERPREFS" command to get streaming URL cookie check setting for Claris FileMaker Server 19.3.2. (Usage: "fmcsadmin get serverprefs AuthenticatedStream")
89 | - Update "SET SERVERPREFS" command to set streaming URL cookie check setting for Claris FileMaker Server 19.3.2. (Usage: "fmcsadmin set serverprefs AuthenticatedStream=1")
90 | - Return the FileMaker error code 10502 when using "LIST" command and fmserverd is stopping.
91 | - Improve error handling in case of detecting server-side error.
92 | - Suppress outputting error messages for debugging.
93 | - Add error messages for the FileMaker error code 1713, 20501.
94 | - Built with Go 1.16.
95 | - [BUG FIX] Detect upper case when using "SET SERVERCONFIG SecureFilesOnly", "SET SERVERPREFS RequireSecureDB" and "SET CWPCONFIG" command.
96 |
97 | Version: 1.2.0
98 | Date: February 17, 2021
99 | - Support Claris FileMaker Server for Linux.
100 | - Add "DELETE" command to delete a schedule.
101 | - Support "PLUGINS" type of "LIST" command to list Database Server calculation plug-ins for Claris FileMaker Server 19.2.1.
102 | - Add "CERTIFICATE" command to manage SSL certificates for Claris FileMaker Server 19.2.1.
103 | - Modify behavior of "GET CWPCONFIG" command and "SET CWPCONFIG" command on Linux.
104 | - Modify behavior of outputting error messages for invalid parameters when using "GET CWPCONFIG", "GET SERVERCONFIG", "SET CWPCONFIG" and "SET SERVERCONFIG" command.
105 | - Modify behavior of outputting error messages for unavailable commands when using "GET SERVERPREFS" command and "SET SERVERPREFS" command.
106 | - Change error code for unavailable commands when using "GET SERVERPREFS" command and "SET SERVERPREFS" command.
107 | - Modify behavior of "DISABLE" command without "-y" or "--yes" option.
108 | - Add error messages for the FileMaker error code 21, 20402, 20405, 20406, 20408, 20630 and 20632.
109 | - Update error messages for the FileMaker error code -1 and 1708.
110 | - Built with Go 1.15.
111 | - [INFO] Drop support for macOS High Sierra 10.13.
112 | - [BUG FIX] Fix compatibility with Claris FileMaker Server 19.1.2 or later when using "SET SERVERCONFIG" command and "SET SERVERPREFS" command.
113 |
114 | Version: 1.1.0
115 | Date: June 17, 2020
116 | - Support "--savekey" option of "OPEN" command for FileMaker Server 19.
117 | - Add the notarized installer for macOS to support macOS Catalina 10.15.
118 | - Built with Go 1.14.
119 |
120 | Version: 1.0.0
121 | Date: September 26, 2019
122 | - Support and require FileMaker Admin API v2 of FileMaker Server 18 and FileMaker Cloud for AWS 1.18. Released as a stable version.
123 | - Change to the MIT License.
124 | - Enable "--fqdn" option for FileMaker Server.
125 | - Add "-f" and "--force" option for forcing database to close or database server to stop, immediately disconnecting clients.
126 | - Add "GET BACKUPTIME" command to retrieve the start time of a specified backup schedule or the start times of all backup schedules for FileMaker Server (Handling schedule ID 1 is not supported).
127 | - Add "GET SERVERPREFS" command for FileMaker Server.
128 | - Add "SET SERVERPREFS" command for FileMaker Server.
129 | - Add 32-bit version for Windows.
130 | - [BUG FIX] Modify outputting enabled extended privileges of closed files when using "-s" option of "LIST FILES" command.
131 |
132 | Version: 0.9.3 (beta)
133 | Date: January 28, 2019
134 | - Add an error message for the FileMaker error code 214.
135 | - Built with Go 1.11.
136 | - [BUG FIX] Fix "-m" and "--message" option of "CLOSE" command. The affected version is 0.9.2 only.
137 | - [BUG FIX] Output "File Closed:" when using "-m" or "--message" option of "CLOSE" command and there is no client connected to the specified databases.
138 |
139 | Version: 0.9.2 (beta)
140 | Date: July 6, 2018
141 | - Support FileMaker Admin API (Trial) of FileMaker Server 17 experimentally ("--fqdn" option and handling schedule ID 1 is not supported for FileMaker Server).
142 | - Add "START" command to start a server process for FileMaker Server 17.
143 | - Add "STOP" command to stop a server process for FileMaker Server 17.
144 | - Add "RESTART" command to restart a server process for FileMaker Server 17.
145 | - Add "GET" command to retrieve server or CWP (Custom Web Publishing) configuration settings for FileMaker Server 17.
146 | - Add "SET" command to change server or CWP (Custom Web Publishing) configuration settings for FileMaker Server 17.
147 | - Consider local time zone when listing schedules and outputting timestamp.
148 | - Improve connection error handling.
149 | - Output an error message when detecting an invalid option.
150 | - Add error messages for the FileMaker error code -1, 3 and 4.
151 | - Add error messages for the error code 10001, 10007, 10502, 11000 and 11002.
152 | - Change an error message for the FileMaker error code 9.
153 | - Show an error message of the error code 11005 when specified client ID doesn't exist and using "DISCONNECT" command.
154 | - Adjust showing value of "CONNECT TIME" and "FILE NAME" when listing clients with "STATUS" command.
155 | - Built with Go 1.10.
156 | - [BUG FIX] Fix "DISCONNECT" command.
157 | - [BUG FIX] Show an error message when specified schedule ID doesn't exist and using "ENABLE", "DISABLE" and "RUN" commands.
158 | - [BUG FIX] Fix "SEND" command to send a text message to the clients connected to the specified databases.
159 | - [BUG FIX] Fix showing values of "LAST COMPLETED" and "STATUS" correctly in some cases when listing schedules with "LIST" command.
160 | - [BUG FIX] Fix "STATUS" command to show the status of a specified client number correctly.
161 | - [BUG FIX] Fix "STATUS" command not to show the list of databases when a specified database is not exist.
162 |
163 | Version: 0.9.1 (beta)
164 | Date: February 15, 2018
165 | - Add error messages for the FileMaker error code 10006 and 10908.
166 | - Add NOTICE.txt to the distribution file.
167 | - [BUG FIX] Fix logging out process.
168 |
169 | Version: 0.9.0 (beta)
170 | Date: December 22, 2017
171 | - Initial release supporting FileMaker Admin API (Trial). Released as a beta version under the Apache License, Version 2.0.
172 |
--------------------------------------------------------------------------------
/fmcsadmin_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "bytes"
5 | "fmt"
6 | "io"
7 | "log"
8 | "net"
9 | "net/http"
10 | "net/http/httptest"
11 | "runtime"
12 | "strings"
13 | "testing"
14 | "time"
15 |
16 | "github.com/stretchr/testify/assert"
17 | )
18 |
19 | func TestRun(t *testing.T) {
20 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
21 | cli := &cli{outStream: outStream, errStream: errStream}
22 | var args []string
23 | var status int
24 |
25 | args = strings.Split("fmcsadmin", " ")
26 | status = cli.Run(args)
27 | assert.Equal(t, 0, status)
28 |
29 | args = strings.Split("fmcsadmin -V", " ")
30 | status = cli.Run(args)
31 | assert.Equal(t, 248, status)
32 |
33 | args = strings.Split("fmcsadmin certificate", " ")
34 | status = cli.Run(args)
35 | assert.Equal(t, 248, status)
36 |
37 | args = strings.Split("fmcsadmin close -b", " ")
38 | status = cli.Run(args)
39 | assert.Equal(t, 249, status)
40 |
41 | args = strings.Split("fmcsadmin close --unknown", " ")
42 | status = cli.Run(args)
43 | assert.Equal(t, 249, status)
44 |
45 | args = strings.Split("fmcsadmin disconnect unknown", " ")
46 | status = cli.Run(args)
47 | assert.Equal(t, 248, status)
48 |
49 | args = strings.Split("fmcsadmin disconnect 0", " ")
50 | status = cli.Run(args)
51 | assert.Equal(t, 248, status)
52 |
53 | args = strings.Split("fmcsadmin list", " ")
54 | status = cli.Run(args)
55 | assert.Equal(t, 248, status)
56 |
57 | args = strings.Split("fmcsadmin list unknown", " ")
58 | status = cli.Run(args)
59 | assert.Equal(t, 248, status)
60 |
61 | args = strings.Split("fmcsadmin get", " ")
62 | status = cli.Run(args)
63 | assert.Equal(t, 248, status)
64 |
65 | args = strings.Split("fmcsadmin get cwpconfig invalidparameter", " ")
66 | status = cli.Run(args)
67 | assert.Equal(t, 10001, status)
68 |
69 | args = strings.Split("fmcsadmin get cwpconfig invalidparameter", " ")
70 | _ = cli.Run(args)
71 | expected := "Invalid configuration name: invalidparameter"
72 | assert.Contains(t, outStream.String(), expected)
73 |
74 | args = strings.Split("fmcsadmin get serverconfig invalidparameter", " ")
75 | status = cli.Run(args)
76 | assert.Equal(t, 10001, status)
77 |
78 | args = strings.Split("fmcsadmin get serverprefs invalidparameter", " ")
79 | status = cli.Run(args)
80 | assert.Equal(t, 10001, status)
81 |
82 | args = strings.Split("fmcsadmin get unknown", " ")
83 | status = cli.Run(args)
84 | assert.Equal(t, 248, status)
85 |
86 | args = strings.Split("fmcsadmin restart", " ")
87 | status = cli.Run(args)
88 | if runtime.GOOS == "darwin" || runtime.GOOS == "windows" {
89 | assert.Equal(t, 248, status)
90 | } else {
91 | assert.Equal(t, 248, status)
92 | }
93 |
94 | args = strings.Split("fmcsadmin restart unknown -y", " ")
95 | status = cli.Run(args)
96 | if runtime.GOOS == "darwin" || runtime.GOOS == "windows" {
97 | assert.Equal(t, 23, status)
98 | } else {
99 | assert.Equal(t, 23, status)
100 | }
101 |
102 | args = strings.Split("fmcsadmin run unknown", " ")
103 | status = cli.Run(args)
104 | assert.Equal(t, 248, status)
105 |
106 | args = strings.Split("fmcsadmin set", " ")
107 | status = cli.Run(args)
108 | assert.Equal(t, 248, status)
109 |
110 | args = strings.Split("fmcsadmin set cwpconfig", " ")
111 | status = cli.Run(args)
112 | assert.Equal(t, 10001, status)
113 |
114 | args = strings.Split("fmcsadmin set cwpconfig enablephp", " ")
115 | status = cli.Run(args)
116 | assert.Equal(t, 10001, status)
117 |
118 | args = strings.Split("fmcsadmin set cwpconfig invalidparameter=true", " ")
119 | status = cli.Run(args)
120 | assert.Equal(t, 10001, status)
121 |
122 | args = strings.Split("fmcsadmin set cwpconfig invalidparameter=true", " ")
123 | _ = cli.Run(args)
124 | expected = "Invalid configuration name: invalidparameter"
125 | assert.Contains(t, outStream.String(), expected)
126 |
127 | args = strings.Split("fmcsadmin set serverconfig", " ")
128 | status = cli.Run(args)
129 | assert.Equal(t, 10001, status)
130 |
131 | args = strings.Split("fmcsadmin set serverconfig invalidparameter", " ")
132 | status = cli.Run(args)
133 | assert.Equal(t, 10001, status)
134 |
135 | args = strings.Split("fmcsadmin set serverconfig invalidparameter=true", " ")
136 | status = cli.Run(args)
137 | assert.Equal(t, 10001, status)
138 |
139 | args = strings.Split("fmcsadmin set serverprefs", " ")
140 | status = cli.Run(args)
141 | assert.Equal(t, 10001, status)
142 |
143 | args = strings.Split("fmcsadmin set serverprefs invalidparameter", " ")
144 | status = cli.Run(args)
145 | assert.Equal(t, 10001, status)
146 |
147 | args = strings.Split("fmcsadmin set serverprefs invalidparameter=true", " ")
148 | status = cli.Run(args)
149 | assert.Equal(t, 10001, status)
150 |
151 | args = strings.Split("fmcsadmin set unknown", " ")
152 | status = cli.Run(args)
153 | assert.Equal(t, 248, status)
154 |
155 | args = strings.Split("fmcsadmin start", " ")
156 | status = cli.Run(args)
157 | if runtime.GOOS == "darwin" || runtime.GOOS == "windows" {
158 | assert.Equal(t, 248, status)
159 | } else {
160 | assert.Equal(t, 248, status)
161 | }
162 |
163 | args = strings.Split("fmcsadmin start unknown", " ")
164 | status = cli.Run(args)
165 | if runtime.GOOS == "darwin" || runtime.GOOS == "windows" {
166 | assert.Equal(t, 23, status)
167 | } else {
168 | assert.Equal(t, 23, status)
169 | }
170 |
171 | args = strings.Split("fmcsadmin status unknown", " ")
172 | status = cli.Run(args)
173 | assert.Equal(t, 248, status)
174 |
175 | args = strings.Split("fmcsadmin stop", " ")
176 | status = cli.Run(args)
177 | if runtime.GOOS == "darwin" || runtime.GOOS == "windows" {
178 | assert.Equal(t, 248, status)
179 | } else {
180 | assert.Equal(t, 248, status)
181 | }
182 |
183 | args = strings.Split("fmcsadmin stop unknown -y", " ")
184 | status = cli.Run(args)
185 | if runtime.GOOS == "darwin" || runtime.GOOS == "windows" {
186 | assert.Equal(t, 23, status)
187 | } else {
188 | assert.Equal(t, 23, status)
189 | }
190 | }
191 |
192 | func TestRunInvalidCommand(t *testing.T) {
193 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
194 | cli := &cli{outStream: outStream, errStream: errStream}
195 |
196 | args := strings.Split("fmcsadmin invalidcommand", " ")
197 | status := cli.Run(args)
198 | assert.Equal(t, 248, status)
199 | expected := "Usage: fmcsadmin [options] [COMMAND]"
200 | assert.Contains(t, outStream.String(), expected)
201 | }
202 |
203 | func TestRunWithHelpOption1(t *testing.T) {
204 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
205 | cli := &cli{outStream: outStream, errStream: errStream}
206 |
207 | args := strings.Split("fmcsadmin -h", " ")
208 | status := cli.Run(args)
209 | assert.Equal(t, 0, status)
210 | expected := "Usage: fmcsadmin [options] [COMMAND]"
211 | assert.Contains(t, outStream.String(), expected)
212 | }
213 |
214 | func TestRunWithHelpOption2(t *testing.T) {
215 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
216 | cli := &cli{outStream: outStream, errStream: errStream}
217 |
218 | args := strings.Split("fmcsadmin --help", " ")
219 | status := cli.Run(args)
220 | assert.Equal(t, 0, status)
221 | expected := "Usage: fmcsadmin [options] [COMMAND]"
222 | assert.Contains(t, outStream.String(), expected)
223 | }
224 |
225 | func TestRunWithIdentityFileOption(t *testing.T) {
226 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
227 | cli := &cli{outStream: outStream, errStream: errStream}
228 |
229 | args := strings.Split("fmcsadmin -i notexist.pub list files", " ")
230 | status := cli.Run(args)
231 | assert.Equal(t, 20405, status)
232 | }
233 |
234 | func TestRunWithVersionOption1(t *testing.T) {
235 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
236 | cli := &cli{outStream: outStream, errStream: errStream}
237 |
238 | args := strings.Split("fmcsadmin -v", " ")
239 | status := cli.Run(args)
240 | assert.Equal(t, 0, status)
241 | expected := "fmcsadmin"
242 | assert.Contains(t, outStream.String(), expected)
243 | }
244 |
245 | func TestRunWithVersionOption2(t *testing.T) {
246 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
247 | cli := &cli{outStream: outStream, errStream: errStream}
248 |
249 | args := strings.Split("fmcsadmin --version", " ")
250 | status := cli.Run(args)
251 | assert.Equal(t, 0, status)
252 | expected := "fmcsadmin"
253 | assert.Contains(t, outStream.String(), expected)
254 | }
255 |
256 | func TestRunCancelCommand(t *testing.T) {
257 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
258 | cli := &cli{outStream: outStream, errStream: errStream}
259 |
260 | args := strings.Split("fmcsadmin cancel", " ")
261 | status := cli.Run(args)
262 | assert.Equal(t, 248, status)
263 | expected := "Error: 11000 (Invalid command)"
264 | assert.Contains(t, outStream.String(), expected)
265 | }
266 |
267 | func TestRunDeleteCommand1(t *testing.T) {
268 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
269 | cli := &cli{outStream: outStream, errStream: errStream}
270 |
271 | args := strings.Split("fmcsadmin delete", " ")
272 | status := cli.Run(args)
273 | assert.Equal(t, 248, status)
274 | expected := "Error: 11000 (Invalid command)"
275 | assert.Contains(t, outStream.String(), expected)
276 | }
277 |
278 | func TestRunDeleteCommand2(t *testing.T) {
279 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
280 | cli := &cli{outStream: outStream, errStream: errStream}
281 |
282 | args := strings.Split("fmcsadmin delete schedule", " ")
283 | status := cli.Run(args)
284 | assert.Equal(t, 0, status)
285 | expected := "fmcsadmin: really delete a schedule? (y, n)"
286 | assert.Contains(t, outStream.String(), expected)
287 | }
288 |
289 | func TestRunDisableCommand1(t *testing.T) {
290 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
291 | cli := &cli{outStream: outStream, errStream: errStream}
292 |
293 | args := strings.Split("fmcsadmin disable", " ")
294 | status := cli.Run(args)
295 | assert.Equal(t, 248, status)
296 | expected := "Error: 11000 (Invalid command)"
297 | assert.Contains(t, outStream.String(), expected)
298 | }
299 |
300 | func TestRunDisableCommand2(t *testing.T) {
301 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
302 | cli := &cli{outStream: outStream, errStream: errStream}
303 |
304 | args := strings.Split("fmcsadmin disable schedule", " ")
305 | status := cli.Run(args)
306 | assert.Equal(t, 0, status)
307 | expected := "fmcsadmin: really disable schedule(s)? (y, n) "
308 | assert.Contains(t, outStream.String(), expected)
309 | }
310 |
311 | func TestRunDisableCommand3(t *testing.T) {
312 | running := true
313 | url := "http://127.0.0.1:16001/fmi/admin/api/v2/user/auth"
314 | _, err := http.Get(url)
315 | if err != nil {
316 | running = false
317 | }
318 |
319 | if running == true {
320 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
321 | cli := &cli{outStream: outStream, errStream: errStream}
322 | args := strings.Split("fmcsadmin -u USERNAME -p PASSWORD -y disable schedule", " ")
323 | status := cli.Run(args)
324 | assert.Equal(t, 10600, status)
325 | expected := "Error: 10600 (Schedule at specified index does not exist)"
326 | assert.Contains(t, outStream.String(), expected)
327 | }
328 | }
329 |
330 | func TestRunDisconnectCommand1(t *testing.T) {
331 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
332 | cli := &cli{outStream: outStream, errStream: errStream}
333 |
334 | args := strings.Split("fmcsadmin disconnect", " ")
335 | status := cli.Run(args)
336 | assert.Equal(t, 248, status)
337 | expected := "Error: 11000 (Invalid command)"
338 | assert.Contains(t, outStream.String(), expected)
339 | }
340 |
341 | func TestRunableEnbleCommand1(t *testing.T) {
342 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
343 | cli := &cli{outStream: outStream, errStream: errStream}
344 |
345 | args := strings.Split("fmcsadmin enable", " ")
346 | status := cli.Run(args)
347 | assert.Equal(t, 248, status)
348 | expected := "Error: 11000 (Invalid command)"
349 | assert.Contains(t, outStream.String(), expected)
350 | }
351 |
352 | /*
353 | func TestRunEnableCommand2(t *testing.T) {
354 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
355 | cli := &cli{outStream: outStream, errStream: errStream}
356 |
357 | args := strings.Split("fmcsadmin -y enable schedule", " ")
358 | status := cli.Run(args)
359 | assert.Equal(t, 104, status)
360 | expected := "Error: 10600 (Schedule at specified index does not exist)"
361 | assert.Contains(t, outStream.String(), expected)
362 | }
363 | */
364 |
365 | func TestRunHelpCommand1(t *testing.T) {
366 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
367 | cli := &cli{outStream: outStream, errStream: errStream}
368 |
369 | args := strings.Split("fmcsadmin help", " ")
370 | status := cli.Run(args)
371 | assert.Equal(t, 0, status)
372 | expected := "Usage: fmcsadmin [options] [COMMAND]"
373 | assert.Contains(t, outStream.String(), expected)
374 | }
375 |
376 | func TestRunHelpCommand2(t *testing.T) {
377 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
378 | cli := &cli{outStream: outStream, errStream: errStream}
379 |
380 | args := strings.Split("fmcsadmin help commands", " ")
381 | status := cli.Run(args)
382 | assert.Equal(t, 0, status)
383 | expected := "fmcsadmin commands are:"
384 | assert.Contains(t, outStream.String(), expected)
385 | }
386 |
387 | func TestRunHelpCommand3(t *testing.T) {
388 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
389 | cli := &cli{outStream: outStream, errStream: errStream}
390 |
391 | args := strings.Split("fmcsadmin help options", " ")
392 | status := cli.Run(args)
393 | assert.Equal(t, 0, status)
394 | expected := "Many fmcsadmin commands take options and parameters."
395 | assert.Contains(t, outStream.String(), expected)
396 | }
397 |
398 | func TestRunHelpCommand4(t *testing.T) {
399 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
400 | cli := &cli{outStream: outStream, errStream: errStream}
401 |
402 | args := strings.Split("fmcsadmin help invalidoption", " ")
403 | status := cli.Run(args)
404 | assert.Equal(t, 0, status)
405 | expected := "Usage: fmcsadmin [options] [COMMAND]"
406 | assert.Contains(t, outStream.String(), expected)
407 | }
408 |
409 | func TestRunRunCommand1(t *testing.T) {
410 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
411 | cli := &cli{outStream: outStream, errStream: errStream}
412 |
413 | args := strings.Split("fmcsadmin run", " ")
414 | status := cli.Run(args)
415 | assert.Equal(t, 248, status)
416 | expected := "Error: 11000 (Invalid command)"
417 | assert.Contains(t, outStream.String(), expected)
418 | }
419 |
420 | /*
421 | func TestRunRunCommand2(t *testing.T) {
422 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
423 | cli := &cli{outStream: outStream, errStream: errStream}
424 |
425 | args := strings.Split("fmcsadmin -y run schedule", " ")
426 | status := cli.Run(args)
427 | assert.Equal(t, 104, status)
428 | expected := "Error: 10600 (Schedule at specified index does not exist)"
429 | assert.Contains(t, outStream.String(), expected)
430 | }
431 | */
432 |
433 | func TestRunShowCertificateCommandHelp(t *testing.T) {
434 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
435 | cli := &cli{outStream: outStream, errStream: errStream}
436 |
437 | args := strings.Split("fmcsadmin help certificate", " ")
438 | status := cli.Run(args)
439 | assert.Equal(t, 0, status)
440 | expected := "Usage: fmcsadmin CERTIFICATE [CERT_OP] [options] [NAME] [FILE]"
441 | assert.Contains(t, outStream.String(), expected)
442 | }
443 |
444 | func TestRunShowCloseCommandHelp(t *testing.T) {
445 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
446 | cli := &cli{outStream: outStream, errStream: errStream}
447 |
448 | args := strings.Split("fmcsadmin help close", " ")
449 | status := cli.Run(args)
450 | assert.Equal(t, 0, status)
451 | expected := "Usage: fmcsadmin CLOSE [FILE...] [PATH...] [options]"
452 | assert.Contains(t, outStream.String(), expected)
453 | }
454 |
455 | func TestRunShowDeleteCommandHelp(t *testing.T) {
456 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
457 | cli := &cli{outStream: outStream, errStream: errStream}
458 |
459 | args := strings.Split("fmcsadmin help delete", " ")
460 | status := cli.Run(args)
461 | assert.Equal(t, 0, status)
462 | expected := "Usage: fmcsadmin DELETE [TYPE] [SCHEDULE_NUMBER]"
463 | assert.Contains(t, outStream.String(), expected)
464 | }
465 |
466 | func TestRunShowDisableCommandHelp(t *testing.T) {
467 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
468 | cli := &cli{outStream: outStream, errStream: errStream}
469 |
470 | args := strings.Split("fmcsadmin help disable", " ")
471 | status := cli.Run(args)
472 | assert.Equal(t, 0, status)
473 | expected := "Usage: fmcsadmin DISABLE [TYPE] [SCHEDULE_NUMBER]"
474 | assert.Contains(t, outStream.String(), expected)
475 | }
476 |
477 | func TestRunShowDisconnectCommandHelp(t *testing.T) {
478 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
479 | cli := &cli{outStream: outStream, errStream: errStream}
480 |
481 | args := strings.Split("fmcsadmin help disconnect", " ")
482 | status := cli.Run(args)
483 | assert.Equal(t, 0, status)
484 | expected := "Usage: fmcsadmin DISCONNECT CLIENT [CLIENT_NUMBER] [options]"
485 | assert.Contains(t, outStream.String(), expected)
486 | }
487 |
488 | func TestRunShowEnableCommandHelp(t *testing.T) {
489 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
490 | cli := &cli{outStream: outStream, errStream: errStream}
491 |
492 | args := strings.Split("fmcsadmin help enable", " ")
493 | status := cli.Run(args)
494 | assert.Equal(t, 0, status)
495 | expected := "Usage: fmcsadmin ENABLE [TYPE] [SCHEDULE_NUMBER]"
496 | assert.Contains(t, outStream.String(), expected)
497 | }
498 |
499 | func TestRunShowListCommandHelp(t *testing.T) {
500 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
501 | cli := &cli{outStream: outStream, errStream: errStream}
502 |
503 | args := strings.Split("fmcsadmin help list", " ")
504 | status := cli.Run(args)
505 | assert.Equal(t, 0, status)
506 | expected := "Usage: fmcsadmin LIST [TYPE] [options]"
507 | assert.Contains(t, outStream.String(), expected)
508 | }
509 |
510 | func TestRunShowOpenCommandHelp(t *testing.T) {
511 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
512 | cli := &cli{outStream: outStream, errStream: errStream}
513 |
514 | args := strings.Split("fmcsadmin help open", " ")
515 | status := cli.Run(args)
516 | assert.Equal(t, 0, status)
517 | expected := "Usage: fmcsadmin OPEN [options] [FILE...] [PATH...]"
518 | assert.Contains(t, outStream.String(), expected)
519 | }
520 |
521 | func TestRunShowPauseCommandHelp(t *testing.T) {
522 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
523 | cli := &cli{outStream: outStream, errStream: errStream}
524 |
525 | args := strings.Split("fmcsadmin help pause", " ")
526 | status := cli.Run(args)
527 | assert.Equal(t, 0, status)
528 | expected := "Usage: fmcsadmin PAUSE [FILE...] [PATH...]"
529 | assert.Contains(t, outStream.String(), expected)
530 | }
531 |
532 | func TestRunShowRestartCommandHelp(t *testing.T) {
533 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
534 | cli := &cli{outStream: outStream, errStream: errStream}
535 |
536 | args := strings.Split("fmcsadmin help restart", " ")
537 | status := cli.Run(args)
538 | assert.Equal(t, 0, status)
539 | expected := "Usage: fmcsadmin RESTART [TYPE]"
540 | assert.Contains(t, outStream.String(), expected)
541 | }
542 |
543 | func TestRunShowResumeCommandHelp(t *testing.T) {
544 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
545 | cli := &cli{outStream: outStream, errStream: errStream}
546 |
547 | args := strings.Split("fmcsadmin help resume", " ")
548 | status := cli.Run(args)
549 | assert.Equal(t, 0, status)
550 | expected := "Usage: fmcsadmin RESUME [FILE...] [PATH...]"
551 | assert.Contains(t, outStream.String(), expected)
552 | }
553 |
554 | func TestRunShowRunCommandHelp(t *testing.T) {
555 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
556 | cli := &cli{outStream: outStream, errStream: errStream}
557 |
558 | args := strings.Split("fmcsadmin help run", " ")
559 | status := cli.Run(args)
560 | assert.Equal(t, 0, status)
561 | expected := "Usage: fmcsadmin RUN SCHEDULE [SCHEDULE_NUMBER]"
562 | assert.Contains(t, outStream.String(), expected)
563 | }
564 |
565 | func TestRunShowSendCommandHelp(t *testing.T) {
566 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
567 | cli := &cli{outStream: outStream, errStream: errStream}
568 |
569 | args := strings.Split("fmcsadmin help send", " ")
570 | status := cli.Run(args)
571 | assert.Equal(t, 0, status)
572 | expected := "Usage: fmcsadmin SEND [options] [CLIENT_NUMBER] [FILE...] [PATH...]"
573 | assert.Contains(t, outStream.String(), expected)
574 | }
575 |
576 | func TestRunShowStartCommandHelp(t *testing.T) {
577 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
578 | cli := &cli{outStream: outStream, errStream: errStream}
579 |
580 | args := strings.Split("fmcsadmin help start", " ")
581 | status := cli.Run(args)
582 | assert.Equal(t, 0, status)
583 | expected := "Usage: fmcsadmin START [TYPE]"
584 | assert.Contains(t, outStream.String(), expected)
585 | }
586 |
587 | func TestRunShowStatusCommandHelp(t *testing.T) {
588 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
589 | cli := &cli{outStream: outStream, errStream: errStream}
590 |
591 | args := strings.Split("fmcsadmin help status", " ")
592 | status := cli.Run(args)
593 | assert.Equal(t, 0, status)
594 | expected := "Usage: fmcsadmin STATUS [TYPE] [CLIENT_NUMBER] [FILE...]"
595 | assert.Contains(t, outStream.String(), expected)
596 | }
597 |
598 | func TestRunShowStopCommandHelp(t *testing.T) {
599 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
600 | cli := &cli{outStream: outStream, errStream: errStream}
601 |
602 | args := strings.Split("fmcsadmin help stop", " ")
603 | status := cli.Run(args)
604 | assert.Equal(t, 0, status)
605 | expected := "Usage: fmcsadmin STOP [TYPE] [options]"
606 | assert.Contains(t, outStream.String(), expected)
607 | }
608 |
609 | func TestRunCloseCommand1(t *testing.T) {
610 | running := true
611 | url := "http://127.0.0.1:16001/fmi/admin/api/v2/user/auth"
612 | _, err := http.Get(url)
613 | if err != nil {
614 | running = false
615 | }
616 |
617 | if running == false {
618 | handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
619 | fmt.Fprintln(w, "{\"response\": {\"token\": \"ACCESSTOKEN\", \"totalDBCount\": 1, \"clients\": [], \"databases\": [{\"id\": \"1\", \"filename\": \"TestDB.fmp12\", \"status\": \"NORMAL\", \"folder\": \"filemac:/Macintosh HD/Library/FileMaker Server/Data/Databases/Sample/\", \"decryptHint\": \"\"}]}, \"messages\": [{\"code\": \"0\"}]}")
620 | if strings.Contains(r.URL.Path, "/fmi/admin/api/v2/databases/") {
621 | request, _ := io.ReadAll(r.Body)
622 | if strings.Contains(string([]byte(request)), "\"status\":\"CLOSED\"") {
623 | assert.Equal(t, "{\"status\":\"CLOSED\",\"messageText\":\"TESTMESSAGE\",\"force\":false}", string([]byte(request)))
624 | }
625 | }
626 | })
627 |
628 | address := "127.0.0.1:16001"
629 | l, err := net.Listen("tcp", address)
630 | if err != nil {
631 | log.Fatal(err)
632 | }
633 | ts := httptest.Server{
634 | Listener: l,
635 | Config: &http.Server{Handler: handler},
636 | }
637 | ts.Start()
638 | defer ts.Close()
639 | }
640 |
641 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
642 | cli := &cli{outStream: outStream, errStream: errStream}
643 | args := strings.Split("fmcsadmin close TestDB -y -u USERNAME -p PASSWORD -m TESTMESSAGE", " ")
644 | status := cli.Run(args)
645 | assert.Equal(t, 0, status)
646 | expected := "Closing: TestDB.fmp12"
647 | assert.Contains(t, outStream.String(), expected)
648 | }
649 |
650 | func TestRunOpenCommand1(t *testing.T) {
651 | running := true
652 | url := "http://127.0.0.1:16001/fmi/admin/api/v2/user/auth"
653 | _, err := http.Get(url)
654 | if err != nil {
655 | running = false
656 | }
657 |
658 | if running == false {
659 | handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
660 | fmt.Fprintln(w, "{\"response\": {\"token\": \"ACCESSTOKEN\", \"totalDBCount\": 1, \"clients\": [], \"databases\": [{\"id\": \"1\", \"filename\": \"TestDB.fmp12\", \"status\": \"CLOSED\", \"folder\": \"filemac:/Macintosh HD/Library/FileMaker Server/Data/Databases/Sample/\", \"decryptHint\": \"\"}]}, \"messages\": [{\"code\": \"0\"}]}")
661 | if strings.Contains(r.URL.Path, "/fmi/admin/api/v2/databases/") {
662 | request, _ := io.ReadAll(r.Body)
663 | if strings.Contains(string([]byte(request)), "\"status\":\"OPENED\"") {
664 | assert.Equal(t, "{\"status\":\"OPENED\",\"key\":\"\",\"saveKey\":false}", string([]byte(request)))
665 | }
666 | }
667 | })
668 |
669 | address := "127.0.0.1:16001"
670 | l, err := net.Listen("tcp", address)
671 | if err != nil {
672 | log.Fatal(err)
673 | }
674 | ts := httptest.Server{
675 | Listener: l,
676 | Config: &http.Server{Handler: handler},
677 | }
678 | ts.Start()
679 | defer ts.Close()
680 | }
681 |
682 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
683 | cli := &cli{outStream: outStream, errStream: errStream}
684 | args := strings.Split("fmcsadmin open TestDB -u USERNAME -p PASSWORD", " ")
685 | status := cli.Run(args)
686 | assert.Equal(t, 0, status)
687 | expected := "File Opening: TestDB.fmp12"
688 | assert.Contains(t, outStream.String(), expected)
689 | }
690 | func TestRunStatusCommand1(t *testing.T) {
691 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
692 | cli := &cli{outStream: outStream, errStream: errStream}
693 |
694 | args := strings.Split("fmcsadmin status", " ")
695 | status := cli.Run(args)
696 | assert.Equal(t, 248, status)
697 | expected := "Error: 11000 (Invalid command)"
698 | assert.Contains(t, outStream.String(), expected)
699 | }
700 |
701 | func TestGetFlags(t *testing.T) {
702 | var expected []string
703 | var args []string
704 | var resultFlags commandOptions
705 | var cmdArgs []string
706 |
707 | flags := commandOptions{}
708 | flags.helpFlag = false
709 | flags.versionFlag = false
710 | flags.yesFlag = false
711 | flags.statsFlag = false
712 | flags.fqdn = ""
713 | flags.username = ""
714 | flags.password = ""
715 | flags.key = ""
716 | flags.message = ""
717 | flags.clientID = -1
718 | flags.graceTime = 90
719 |
720 | /*
721 | * cancel
722 | * Usage: fmcsadmin CANCEL [TYPE]
723 | *
724 | * fmcsadmin cancel backup
725 | * fmcsadmin cancel -y backup
726 | * fmcsadmin --fqdn example.jp cancel backup
727 | * fmcsadmin --fqdn example.jp cancel -y backup
728 | * fmcsadmin --fqdn example.jp -u USERNAME cancel backup
729 | * fmcsadmin --fqdn example.jp -u USERNAME cancel -y backup
730 | * fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD cancel backup
731 | * fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD cancel -y backup
732 | */
733 | expected = []string{"cancel", "backup"}
734 | args = strings.Split("fmcsadmin cancel backup", " ")
735 | cmdArgs, resultFlags, _ = getFlags(args, flags)
736 | assert.Equal(t, expected, cmdArgs)
737 |
738 | /*
739 | * certificate
740 | * Usage: fmcsadmin CERTIFICATE [CERT_OP] [options] [NAME] [FILE]
741 | *
742 | * fmcsadmin certificate create "/CN=fms.example.com/C=US" --keyfilepass secret
743 | * fmcsadmin -u USERNAME certificate create "/CN=fms.example.com/C=US" --keyfilepass secret
744 | * fmcsadmin -p PASSWORD certificate create "/CN=fms.example.com/C=US" --keyfilepass secret
745 | * fmcsadmin -u USERNAME -p PASSWORD certificate create "/CN=fms.example.com/C=US" --keyfilepass secret
746 | * fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD certificate create "/CN=fms.example.com/C=US" --keyfilepass secret
747 | * fmcsadmin certificate import --keyfile KEYFILE --keyfilepass secret --intermediateCA intermediateCAfile CRTFILE
748 | * fmcsadmin certificate import --keyfile KEYFILE --keyfilepass secret --intermediateCA intermediateCAfile -y CRTFILE
749 | * fmcsadmin certificate import -u USERNAME --keyfile KEYFILE --keyfilepass secret --intermediateCA intermediateCAfile CRTFILE
750 | * fmcsadmin certificate import -p PASSWORD --keyfile KEYFILE --keyfilepass secret --intermediateCA intermediateCAfile CRTFILE
751 | * fmcsadmin certificate import -u USERNAME -p PASSWORD --keyfile KEYFILE --keyfilepass secret --intermediateCA intermediateCAfile CRTFILE
752 | * fmcsadmin certificate import --fqdn example.jp -u USERNAME -p PASSWORD --keyfile KEYFILE --keyfilepass secret --intermediateCA intermediateCAfile CRTFILE
753 | * fmcsadmin certificate import --fqdn example.jp -u USERNAME -p PASSWORD --keyfile KEYFILE --keyfilepass secret --intermediateCA intermediateCAfile -y CRTFILE
754 | * fmcsadmin certificate delete
755 | * fmcsadmin certificate delete -y
756 | * fmcsadmin -u USERNAME certificate delete
757 | * fmcsadmin -p PASSWORD certificate delete
758 | * fmcsadmin -u USERNAME -p PASSWORD certificate delete
759 | * fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD certificate delete
760 | * fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD certificate delete -y
761 | * etc.
762 | */
763 |
764 | /*
765 | * close
766 | * Usage: fmcsadmin CLOSE [FILE...] [PATH...] [options]
767 | *
768 | * fmcsadmin close
769 | * fmcsadmin close 1
770 | * fmcsadmin close 1 2
771 | * fmcsadmin close TestDB
772 | * fmcsadmin close TestDB.fmp12
773 | * fmcsadmin close "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"
774 | * fmcsadmin close "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"
775 | * fmcsadmin close "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"
776 | * fmcsadmin close "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"
777 | * fmcsadmin close "/opt/FileMaker/FileMaker Server/Data/Databases/"
778 | * fmcsadmin close "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/"
779 | * fmcsadmin close TestDB FMServer_Sample
780 | * fmcsadmin --fqdn example.jp close TestDB
781 | * fmcsadmin close -y TestDB
782 | * fmcsadmin close -u USERNAME TestDB
783 | * fmcsadmin close -p PASSWORD TestDB
784 | * fmcsadmin close -u USERNAME -p PASSWORD TestDB
785 | * fmcsadmin close -u USERNAME -p PASSWORD -y TestDB
786 | * fmcsadmin close -m "Test Message" TestDB
787 | * fmcsadmin close -m "Test Message" -y TestDB
788 | * etc.
789 | */
790 | expected = []string{"close", "1"}
791 | args = strings.Split("fmcsadmin close 1", " ")
792 | cmdArgs, resultFlags, _ = getFlags(args, flags)
793 | assert.Equal(t, expected, cmdArgs)
794 |
795 | expected = []string{"close", "1", "2"}
796 | args = strings.Split("fmcsadmin close 1 2", " ")
797 | cmdArgs, resultFlags, _ = getFlags(args, flags)
798 | assert.Equal(t, expected, cmdArgs)
799 |
800 | expected = []string{"close", "TestDB"}
801 | args = strings.Split("fmcsadmin close TestDB", " ")
802 | cmdArgs, resultFlags, _ = getFlags(args, flags)
803 | assert.Equal(t, false, resultFlags.yesFlag)
804 | assert.Equal(t, expected, cmdArgs)
805 |
806 | expected = []string{"close", "TestDB", "FMServer_Sample"}
807 | args = strings.Split("fmcsadmin close TestDB FMServer_Sample", " ")
808 | cmdArgs, resultFlags, _ = getFlags(args, flags)
809 | assert.Equal(t, false, resultFlags.yesFlag)
810 | assert.Equal(t, expected, cmdArgs)
811 |
812 | expected = []string{"close", "TestDB"}
813 | args = strings.Split("fmcsadmin --fqdn example.jp close TestDB", " ")
814 | cmdArgs, resultFlags, _ = getFlags(args, flags)
815 | assert.Equal(t, "example.jp", resultFlags.fqdn)
816 | assert.Equal(t, expected, cmdArgs)
817 |
818 | expected = []string{"close", "TestDB"}
819 | args = strings.Split("fmcsadmin -y close TestDB", " ")
820 | cmdArgs, resultFlags, _ = getFlags(args, flags)
821 | assert.Equal(t, true, resultFlags.yesFlag)
822 | assert.Equal(t, expected, cmdArgs)
823 |
824 | expected = []string{"close", "TestDB", "FMServer_Sample"}
825 | args = strings.Split("fmcsadmin -y close TestDB FMServer_Sample", " ")
826 | cmdArgs, resultFlags, _ = getFlags(args, flags)
827 | assert.Equal(t, true, resultFlags.yesFlag)
828 | assert.Equal(t, expected, cmdArgs)
829 |
830 | expected = []string{"close", "TestDB"}
831 | args = strings.Split("fmcsadmin close TestDB -y", " ")
832 | cmdArgs, resultFlags, _ = getFlags(args, flags)
833 | assert.Equal(t, true, resultFlags.yesFlag)
834 | assert.Equal(t, expected, cmdArgs)
835 |
836 | expected = []string{"close", "TestDB", "FMServer_Sample"}
837 | args = strings.Split("fmcsadmin close TestDB FMServer_Sample -y", " ")
838 | cmdArgs, resultFlags, _ = getFlags(args, flags)
839 | assert.Equal(t, true, resultFlags.yesFlag)
840 | assert.Equal(t, expected, cmdArgs)
841 |
842 | expected = []string{"close", "TestDB"}
843 | args = strings.Split("fmcsadmin close -y TestDB", " ")
844 | cmdArgs, resultFlags, _ = getFlags(args, flags)
845 | assert.Equal(t, true, resultFlags.yesFlag)
846 | assert.Equal(t, expected, cmdArgs)
847 |
848 | expected = []string{"close", "TestDB", "FMServer_Sample"}
849 | args = strings.Split("fmcsadmin close -y TestDB FMServer_Sample", " ")
850 | cmdArgs, resultFlags, _ = getFlags(args, flags)
851 | assert.Equal(t, true, resultFlags.yesFlag)
852 | assert.Equal(t, expected, cmdArgs)
853 |
854 | expected = []string{"close", "TestDB"}
855 | args = strings.Split("fmcsadmin close -u USERNAME TestDB", " ")
856 | cmdArgs, resultFlags, _ = getFlags(args, flags)
857 | assert.Equal(t, "USERNAME", resultFlags.username)
858 | assert.Equal(t, expected, cmdArgs)
859 |
860 | expected = []string{"close", "TestDB"}
861 | args = strings.Split("fmcsadmin close -p PASSWORD TestDB", " ")
862 | cmdArgs, resultFlags, _ = getFlags(args, flags)
863 | assert.Equal(t, "PASSWORD", resultFlags.password)
864 | assert.Equal(t, expected, cmdArgs)
865 |
866 | expected = []string{"close", "TestDB"}
867 | args = strings.Split("fmcsadmin close -u USERNAME -p PASSWORD TestDB", " ")
868 | cmdArgs, resultFlags, _ = getFlags(args, flags)
869 | assert.Equal(t, "USERNAME", resultFlags.username)
870 | assert.Equal(t, "PASSWORD", resultFlags.password)
871 | assert.Equal(t, expected, cmdArgs)
872 |
873 | expected = []string{"close", "TestDB"}
874 | args = strings.Split("fmcsadmin close -u USERNAME -p PASSWORD -y TestDB", " ")
875 | cmdArgs, resultFlags, _ = getFlags(args, flags)
876 | assert.Equal(t, "USERNAME", resultFlags.username)
877 | assert.Equal(t, "PASSWORD", resultFlags.password)
878 | assert.Equal(t, true, resultFlags.yesFlag)
879 | assert.Equal(t, expected, cmdArgs)
880 |
881 | expected = []string{"close", "TestDB"}
882 | args = strings.Split("fmcsadmin close -m Message TestDB", " ")
883 | cmdArgs, resultFlags, _ = getFlags(args, flags)
884 | assert.Equal(t, "Message", resultFlags.message)
885 | assert.Equal(t, expected, cmdArgs)
886 |
887 | expected = []string{"close", "TestDB"}
888 | args = strings.Split("fmcsadmin close -m Message -y TestDB", " ")
889 | cmdArgs, resultFlags, _ = getFlags(args, flags)
890 | assert.Equal(t, "Message", resultFlags.message)
891 | assert.Equal(t, true, resultFlags.yesFlag)
892 | assert.Equal(t, expected, cmdArgs)
893 |
894 | /*
895 | * delete
896 | * Usage: fmcsadmin DELETE [TYPE] [SCHEDULE_NUMBER]
897 | *
898 | * fmcsadmin delete schedule 2
899 | * fmcsadmin delete -y schedule 2
900 | * fmcsadmin --fqdn example.jp delete schedule 2
901 | * fmcsadmin --fqdn example.jp delete -y schedule 2
902 | * fmcsadmin --fqdn example.jp -u USERNAME delete schedule 2
903 | * fmcsadmin --fqdn example.jp -u USERNAME delete -y schedule 2
904 | * fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD delete schedule 2
905 | * fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD delete -y schedule 2
906 | */
907 | expected = []string{"delete", "schedule", "2"}
908 | args = strings.Split("fmcsadmin delete schedule 2", " ")
909 | cmdArgs, resultFlags, _ = getFlags(args, flags)
910 | assert.Equal(t, expected, cmdArgs)
911 |
912 | expected = []string{"delete", "schedule", "2"}
913 | args = strings.Split("fmcsadmin delete -y schedule 2", " ")
914 | cmdArgs, resultFlags, _ = getFlags(args, flags)
915 | assert.Equal(t, true, resultFlags.yesFlag)
916 | assert.Equal(t, expected, cmdArgs)
917 |
918 | expected = []string{"delete", "schedule", "2"}
919 | args = strings.Split("fmcsadmin --fqdn example.jp delete schedule 2", " ")
920 | cmdArgs, resultFlags, _ = getFlags(args, flags)
921 | assert.Equal(t, "example.jp", resultFlags.fqdn)
922 | assert.Equal(t, expected, cmdArgs)
923 |
924 | expected = []string{"delete", "schedule", "2"}
925 | args = strings.Split("fmcsadmin --fqdn example.jp delete -y schedule 2", " ")
926 | cmdArgs, resultFlags, _ = getFlags(args, flags)
927 | assert.Equal(t, "example.jp", resultFlags.fqdn)
928 | assert.Equal(t, true, resultFlags.yesFlag)
929 | assert.Equal(t, expected, cmdArgs)
930 |
931 | expected = []string{"delete", "schedule", "2"}
932 | args = strings.Split("fmcsadmin --fqdn example.jp -u USERNAME delete schedule 2", " ")
933 | cmdArgs, resultFlags, _ = getFlags(args, flags)
934 | assert.Equal(t, "example.jp", resultFlags.fqdn)
935 | assert.Equal(t, "USERNAME", resultFlags.username)
936 | assert.Equal(t, expected, cmdArgs)
937 |
938 | expected = []string{"delete", "schedule", "2"}
939 | args = strings.Split("fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD delete schedule 2", " ")
940 | cmdArgs, resultFlags, _ = getFlags(args, flags)
941 | assert.Equal(t, "example.jp", resultFlags.fqdn)
942 | assert.Equal(t, "USERNAME", resultFlags.username)
943 | assert.Equal(t, "PASSWORD", resultFlags.password)
944 | assert.Equal(t, expected, cmdArgs)
945 |
946 | expected = []string{"delete", "schedule", "2"}
947 | args = strings.Split("fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD -y delete schedule 2", " ")
948 | cmdArgs, resultFlags, _ = getFlags(args, flags)
949 | assert.Equal(t, "example.jp", resultFlags.fqdn)
950 | assert.Equal(t, "USERNAME", resultFlags.username)
951 | assert.Equal(t, "PASSWORD", resultFlags.password)
952 | assert.Equal(t, true, resultFlags.yesFlag)
953 | assert.Equal(t, expected, cmdArgs)
954 |
955 | /*
956 | * disable
957 | * Usage: fmcsadmin DISABLE [TYPE] [SCHEDULE_NUMBER]
958 | *
959 | * fmcsadmin disable schedule 1
960 | * fmcsadmin disable -y schedule 1
961 | * fmcsadmin --fqdn example.jp disable schedule 1
962 | * fmcsadmin --fqdn example.jp disable -y schedule 1
963 | * fmcsadmin --fqdn example.jp -u USERNAME disable schedule 1
964 | * fmcsadmin --fqdn example.jp -u USERNAME disable -y schedule 1
965 | * fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD disable schedule 1
966 | * fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD disable -y schedule 1
967 | */
968 | expected = []string{"disable", "schedule", "1"}
969 | args = strings.Split("fmcsadmin disable schedule 1", " ")
970 | cmdArgs, resultFlags, _ = getFlags(args, flags)
971 | assert.Equal(t, expected, cmdArgs)
972 |
973 | expected = []string{"disable", "schedule", "1"}
974 | args = strings.Split("fmcsadmin disable -y schedule 1", " ")
975 | cmdArgs, resultFlags, _ = getFlags(args, flags)
976 | assert.Equal(t, true, resultFlags.yesFlag)
977 | assert.Equal(t, expected, cmdArgs)
978 |
979 | expected = []string{"disable", "schedule", "1"}
980 | args = strings.Split("fmcsadmin --fqdn example.jp disable schedule 1", " ")
981 | cmdArgs, resultFlags, _ = getFlags(args, flags)
982 | assert.Equal(t, "example.jp", resultFlags.fqdn)
983 | assert.Equal(t, expected, cmdArgs)
984 |
985 | expected = []string{"disable", "schedule", "1"}
986 | args = strings.Split("fmcsadmin --fqdn example.jp disable -y schedule 1", " ")
987 | cmdArgs, resultFlags, _ = getFlags(args, flags)
988 | assert.Equal(t, "example.jp", resultFlags.fqdn)
989 | assert.Equal(t, true, resultFlags.yesFlag)
990 | assert.Equal(t, expected, cmdArgs)
991 |
992 | expected = []string{"disable", "schedule", "1"}
993 | args = strings.Split("fmcsadmin --fqdn example.jp -u USERNAME disable schedule 1", " ")
994 | cmdArgs, resultFlags, _ = getFlags(args, flags)
995 | assert.Equal(t, "example.jp", resultFlags.fqdn)
996 | assert.Equal(t, "USERNAME", resultFlags.username)
997 | assert.Equal(t, expected, cmdArgs)
998 |
999 | expected = []string{"disable", "schedule", "1"}
1000 | args = strings.Split("fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD disable schedule 1", " ")
1001 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1002 | assert.Equal(t, "example.jp", resultFlags.fqdn)
1003 | assert.Equal(t, "USERNAME", resultFlags.username)
1004 | assert.Equal(t, "PASSWORD", resultFlags.password)
1005 | assert.Equal(t, expected, cmdArgs)
1006 |
1007 | expected = []string{"disable", "schedule", "1"}
1008 | args = strings.Split("fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD -y disable schedule 1", " ")
1009 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1010 | assert.Equal(t, "example.jp", resultFlags.fqdn)
1011 | assert.Equal(t, "USERNAME", resultFlags.username)
1012 | assert.Equal(t, "PASSWORD", resultFlags.password)
1013 | assert.Equal(t, true, resultFlags.yesFlag)
1014 | assert.Equal(t, expected, cmdArgs)
1015 |
1016 | /*
1017 | * disconnect
1018 | * Usage: fmcsadmin DISCONNECT CLIENT [CLIENT_NUMBER] [options]
1019 | *
1020 | * fmcsadmin disconnect client
1021 | * fmcsadmin disconnect client -y
1022 | * fmcsadmin disconnect client -m "Message"
1023 | * fmcsadmin disconnect client -m "Message" -y
1024 | * fmcsadmin disconnect client -t 90
1025 | * fmcsadmin disconnect client -t 90 -y
1026 | * fmcsadmin disconnect client -m "Message" -t 90
1027 | * fmcsadmin disconnect client -m "Message" -t 90 -y
1028 | * fmcsadmin disconnect client 1
1029 | * fmcsadmin disconnect client 1 -y
1030 | * fmcsadmin disconnect client 1 -m "Message"
1031 | * fmcsadmin disconnect client 1 -m "Message" -y
1032 | * fmcsadmin disconnect client 1 -t 90
1033 | * fmcsadmin disconnect client 1 -t 90 -y
1034 | * fmcsadmin disconnect client 1 -m "Message" -t 90
1035 | * fmcsadmin disconnect client 1 -m "Message" -t 90 -y
1036 | * fmcsadmin --fqdn example.jp disconnect client
1037 | * fmcsadmin --fqdn example.jp disconnect -y client
1038 | * fmcsadmin --fqdn example.jp -u USERNAME disconnect client
1039 | * fmcsadmin --fqdn example.jp -u USERNAME disconnect -y client
1040 | * fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD disconnect client
1041 | * fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD disconnect -y client
1042 | * etc.
1043 | */
1044 | expected = []string{"disconnect", "client"}
1045 | args = strings.Split("fmcsadmin disconnect client", " ")
1046 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1047 | assert.Equal(t, expected, cmdArgs)
1048 |
1049 | expected = []string{"disconnect", "client"}
1050 | args = strings.Split("fmcsadmin disconnect client -y", " ")
1051 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1052 | assert.Equal(t, true, resultFlags.yesFlag)
1053 | assert.Equal(t, expected, cmdArgs)
1054 |
1055 | expected = []string{"disconnect", "client"}
1056 | args = strings.Split("fmcsadmin disconnect client -m Message", " ")
1057 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1058 | assert.Equal(t, "Message", resultFlags.message)
1059 | assert.Equal(t, expected, cmdArgs)
1060 |
1061 | expected = []string{"disconnect", "client"}
1062 | args = strings.Split("fmcsadmin disconnect client -m Message -y", " ")
1063 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1064 | assert.Equal(t, "Message", resultFlags.message)
1065 | assert.Equal(t, true, resultFlags.yesFlag)
1066 | assert.Equal(t, expected, cmdArgs)
1067 |
1068 | expected = []string{"disconnect", "client"}
1069 | args = strings.Split("fmcsadmin disconnect client -m Message -t 90", " ")
1070 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1071 | assert.Equal(t, "Message", resultFlags.message)
1072 | assert.Equal(t, 90, resultFlags.graceTime)
1073 | assert.Equal(t, expected, cmdArgs)
1074 |
1075 | expected = []string{"disconnect", "client"}
1076 | args = strings.Split("fmcsadmin disconnect client -m Message -t 90 -y", " ")
1077 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1078 | assert.Equal(t, "Message", resultFlags.message)
1079 | assert.Equal(t, 90, resultFlags.graceTime)
1080 | assert.Equal(t, true, resultFlags.yesFlag)
1081 | assert.Equal(t, expected, cmdArgs)
1082 |
1083 | expected = []string{"disconnect", "client", "1"}
1084 | args = strings.Split("fmcsadmin disconnect client 1", " ")
1085 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1086 | assert.Equal(t, expected, cmdArgs)
1087 |
1088 | expected = []string{"disconnect", "client", "1"}
1089 | args = strings.Split("fmcsadmin disconnect client 1 -y", " ")
1090 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1091 | assert.Equal(t, true, resultFlags.yesFlag)
1092 | assert.Equal(t, expected, cmdArgs)
1093 |
1094 | expected = []string{"disconnect", "client", "1"}
1095 | args = strings.Split("fmcsadmin disconnect client 1 -m Message", " ")
1096 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1097 | assert.Equal(t, "Message", resultFlags.message)
1098 | assert.Equal(t, expected, cmdArgs)
1099 |
1100 | expected = []string{"disconnect", "client", "1"}
1101 | args = strings.Split("fmcsadmin disconnect client 1 -m Message -y", " ")
1102 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1103 | assert.Equal(t, "Message", resultFlags.message)
1104 | assert.Equal(t, true, resultFlags.yesFlag)
1105 | assert.Equal(t, expected, cmdArgs)
1106 |
1107 | expected = []string{"disconnect", "client", "1"}
1108 | args = strings.Split("fmcsadmin disconnect client 1 -m Message -t 90", " ")
1109 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1110 | assert.Equal(t, "Message", resultFlags.message)
1111 | assert.Equal(t, 90, resultFlags.graceTime)
1112 | assert.Equal(t, expected, cmdArgs)
1113 |
1114 | expected = []string{"disconnect", "client", "1"}
1115 | args = strings.Split("fmcsadmin disconnect client 1 -m Message -t 90 -y", " ")
1116 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1117 | assert.Equal(t, "Message", resultFlags.message)
1118 | assert.Equal(t, 90, resultFlags.graceTime)
1119 | assert.Equal(t, true, resultFlags.yesFlag)
1120 | assert.Equal(t, expected, cmdArgs)
1121 |
1122 | /*
1123 | * enable
1124 | * Usage: fmcsadmin ENABLE [TYPE] [SCHEDULE_NUMBER]
1125 | *
1126 | * fmcsadmin enable schedule 2
1127 | * fmcsadmin -u USERNAME enable schedule 2
1128 | * fmcsadmin -u USERNAME -p PASSWORD enable schedule 2
1129 | * fmcsadmin --fqdn example.jp enable schedule 2
1130 | * fmcsadmin --fqdn example.jp -u USERNAME enable schedule 2
1131 | * fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD enable schedule 2
1132 | */
1133 | expected = []string{"enable", "schedule", "2"}
1134 | args = strings.Split("fmcsadmin enable schedule 2", " ")
1135 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1136 | assert.Equal(t, expected, cmdArgs)
1137 |
1138 | expected = []string{"enable", "schedule", "2"}
1139 | args = strings.Split("fmcsadmin --fqdn example.jp enable schedule 2", " ")
1140 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1141 | assert.Equal(t, "example.jp", resultFlags.fqdn)
1142 | assert.Equal(t, expected, cmdArgs)
1143 |
1144 | /*
1145 | * get
1146 | * Usage: fmcsadmin GET BACKUPTIME [ID]
1147 | * fmcsadmin GET CONFIG_TYPE [NAME1 NAME2 ...]
1148 | *
1149 | * fmcsadmin get backuptime
1150 | * fmcsadmin get backuptime 2
1151 | * fmcsadmin get serverconfig
1152 | * fmcsadmin get serverconfig hostedfiles scriptsessions
1153 | * fmcsadmin get serverconfig scriptsessions hostedfiles
1154 | * fmcsadmin get cwpconfig
1155 | * fmcsadmin get cwpconfig enablexml
1156 | * fmcsadmin get cwpconfig enablephp usefmphp
1157 | * fmcsadmin get cwpconfig usefmphp enablephp
1158 | * fmcsadmin get serverprefs
1159 | * fmcsadmin get serverprefs maxguests maxfiles
1160 | * fmcsadmin get serverprefs maxfiles maxguests
1161 | * fmcsadmin get serverprefs AuthenticatedStream
1162 | * fmcsadmin get serverprefs ParallelBackupEnabled
1163 | * fmcsadmin get serverprefs PersistCacheEnabled
1164 | * fmcsadmin get serverprefs SyncPersistCache
1165 | * fmcsadmin get serverprefs DatabaseServerAutoRestart
1166 | * fmcsadmin get serverprefs BlockNewUsersEnabled
1167 | * fmcsadmin get serverprefs EnableHttpProtocolNetwork
1168 | * fmcsadmin get serverprefs OnlyOpenLastOpenedDatabases
1169 | * fmcsadmin --fqdn example.jp get backuptime
1170 | * fmcsadmin --fqdn example.jp -u USERNAME get backuptime
1171 | * fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD get backuptime
1172 | * etc.
1173 | */
1174 |
1175 | /*
1176 | * help
1177 | * Usage: fmcsadmin HELP COMMANDS
1178 | * fmcsadmin HELP [COMMAND]
1179 | * fmcsadmin HELP OPTIONS
1180 | *
1181 | * fmcsadmin help
1182 | * fmcsadmin help commands
1183 | * fmcsadmin help options
1184 | * fmcsadmin help certificate
1185 | * fmcsadmin help close
1186 | * fmcsadmin help delete
1187 | * fmcsadmin help disable
1188 | * fmcsadmin help disconnect
1189 | * fmcsadmin help enable
1190 | * fmcsadmin help get
1191 | * fmcsadmin help help
1192 | * fmcsadmin help list
1193 | * fmcsadmin help open
1194 | * fmcsadmin help pause
1195 | * fmcsadmin help run
1196 | * fmcsadmin help send
1197 | * fmcsadmin help set
1198 | * fmcsadmin help status
1199 | */
1200 | expected = []string{"help"}
1201 | args = strings.Split("fmcsadmin help", " ")
1202 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1203 | assert.Equal(t, expected, cmdArgs)
1204 |
1205 | /*
1206 | * list
1207 | * Usage: fmcsadmin LIST [TYPE] [options]
1208 | *
1209 | * fmcsadmin list clients
1210 | * fmcsadmin list clients -s
1211 | * fmcsadmin list files
1212 | * fmcsadmin list files -s
1213 | * fmcsadmin list plugins
1214 | * fmcsadmin list plugins -s
1215 | * fmcsadmin list schedules
1216 | * fmcsadmin list schedules -s
1217 | * fmcsadmin --fqdn example.jp list clients
1218 | * fmcsadmin --fqdn example.jp list clients -s
1219 | * fmcsadmin --fqdn example.jp list files
1220 | * fmcsadmin --fqdn example.jp list files -s
1221 | * fmcsadmin --fqdn example.jp list plugins
1222 | * fmcsadmin --fqdn example.jp list plugins -s
1223 | * fmcsadmin --fqdn example.jp list schedules
1224 | * fmcsadmin --fqdn example.jp list schedules -s
1225 | * fmcsadmin -u USERNAME list clients
1226 | * fmcsadmin -u USERNAME list clients -s
1227 | * fmcsadmin -u USERNAME list files
1228 | * fmcsadmin -u USERNAME list files -s
1229 | * fmcsadmin -u USERNAME list plugins
1230 | * fmcsadmin -u USERNAME list plugins -s
1231 | * fmcsadmin -u USERNAME list schedules
1232 | * fmcsadmin -u USERNAME list schedules -s
1233 | * fmcsadmin -p PASSWORD list clients
1234 | * fmcsadmin -p PASSWORD list clients -s
1235 | * fmcsadmin -p PASSWORD list files
1236 | * fmcsadmin -p PASSWORD list files -s
1237 | * fmcsadmin -p PASSWORD list plugins
1238 | * fmcsadmin -p PASSWORD list plugins -s
1239 | * fmcsadmin -p PASSWORD list schedules
1240 | * fmcsadmin -p PASSWORD list schedules -s
1241 | * fmcsadmin -u USERNAME -p PASSWORD list clients
1242 | * fmcsadmin -u USERNAME -p PASSWORD list clients -s
1243 | * fmcsadmin -u USERNAME -p PASSWORD list files
1244 | * fmcsadmin -u USERNAME -p PASSWORD list files -s
1245 | * fmcsadmin -u USERNAME -p PASSWORD list plugins
1246 | * fmcsadmin -u USERNAME -p PASSWORD list plugins -s
1247 | * fmcsadmin -u USERNAME -p PASSWORD list schedules
1248 | * fmcsadmin -u USERNAME -p PASSWORD list schedules -s
1249 | */
1250 | // list clients
1251 | expected = []string{"list", "clients"}
1252 | args = strings.Split("fmcsadmin list clients", " ")
1253 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1254 | assert.Equal(t, false, resultFlags.statsFlag)
1255 | assert.Equal(t, expected, cmdArgs)
1256 |
1257 | expected = []string{"list", "clients"}
1258 | args = strings.Split("fmcsadmin -s list clients", " ")
1259 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1260 | assert.Equal(t, true, resultFlags.statsFlag)
1261 | assert.Equal(t, expected, cmdArgs)
1262 |
1263 | expected = []string{"list", "clients"}
1264 | args = strings.Split("fmcsadmin --stats list clients", " ")
1265 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1266 | assert.Equal(t, true, resultFlags.statsFlag)
1267 | assert.Equal(t, expected, cmdArgs)
1268 |
1269 | expected = []string{"list", "clients"}
1270 | args = strings.Split("fmcsadmin list clients -s", " ")
1271 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1272 | assert.Equal(t, true, resultFlags.statsFlag)
1273 | assert.Equal(t, expected, cmdArgs)
1274 |
1275 | expected = []string{"list", "clients"}
1276 | args = strings.Split("fmcsadmin list clients --stats", " ")
1277 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1278 | assert.Equal(t, true, resultFlags.statsFlag)
1279 | assert.Equal(t, expected, cmdArgs)
1280 |
1281 | expected = []string{"list", "clients"}
1282 | args = strings.Split("fmcsadmin list -s clients", " ")
1283 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1284 | assert.Equal(t, true, resultFlags.statsFlag)
1285 | assert.Equal(t, expected, cmdArgs)
1286 |
1287 | expected = []string{"list", "clients"}
1288 | args = strings.Split("fmcsadmin list --stats clients", " ")
1289 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1290 | assert.Equal(t, true, resultFlags.statsFlag)
1291 | assert.Equal(t, expected, cmdArgs)
1292 |
1293 | // list files
1294 | expected = []string{"list", "files"}
1295 | args = strings.Split("fmcsadmin list files", " ")
1296 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1297 | assert.Equal(t, false, resultFlags.statsFlag)
1298 | assert.Equal(t, expected, cmdArgs)
1299 |
1300 | expected = []string{"list", "files"}
1301 | args = strings.Split("fmcsadmin -s list files", " ")
1302 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1303 | assert.Equal(t, true, resultFlags.statsFlag)
1304 | assert.Equal(t, expected, cmdArgs)
1305 |
1306 | expected = []string{"list", "files"}
1307 | args = strings.Split("fmcsadmin --stats list files", " ")
1308 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1309 | assert.Equal(t, true, resultFlags.statsFlag)
1310 | assert.Equal(t, expected, cmdArgs)
1311 |
1312 | expected = []string{"list", "files"}
1313 | args = strings.Split("fmcsadmin list files -s", " ")
1314 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1315 | assert.Equal(t, true, resultFlags.statsFlag)
1316 | assert.Equal(t, expected, cmdArgs)
1317 |
1318 | expected = []string{"list", "files"}
1319 | args = strings.Split("fmcsadmin list files --stats", " ")
1320 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1321 | assert.Equal(t, true, resultFlags.statsFlag)
1322 | assert.Equal(t, expected, cmdArgs)
1323 |
1324 | expected = []string{"list", "files"}
1325 | args = strings.Split("fmcsadmin list -s files", " ")
1326 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1327 | assert.Equal(t, true, resultFlags.statsFlag)
1328 | assert.Equal(t, expected, cmdArgs)
1329 |
1330 | expected = []string{"list", "files"}
1331 | args = strings.Split("fmcsadmin list --stats files", " ")
1332 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1333 | assert.Equal(t, true, resultFlags.statsFlag)
1334 | assert.Equal(t, expected, cmdArgs)
1335 |
1336 | // list plugins
1337 | expected = []string{"list", "plugins"}
1338 | args = strings.Split("fmcsadmin list plugins", " ")
1339 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1340 | assert.Equal(t, false, resultFlags.statsFlag)
1341 | assert.Equal(t, expected, cmdArgs)
1342 |
1343 | expected = []string{"list", "plugins"}
1344 | args = strings.Split("fmcsadmin -s list plugins", " ")
1345 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1346 | assert.Equal(t, true, resultFlags.statsFlag)
1347 | assert.Equal(t, expected, cmdArgs)
1348 |
1349 | expected = []string{"list", "plugins"}
1350 | args = strings.Split("fmcsadmin --stats list plugins", " ")
1351 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1352 | assert.Equal(t, true, resultFlags.statsFlag)
1353 | assert.Equal(t, expected, cmdArgs)
1354 |
1355 | expected = []string{"list", "plugins"}
1356 | args = strings.Split("fmcsadmin list plugins -s", " ")
1357 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1358 | assert.Equal(t, true, resultFlags.statsFlag)
1359 | assert.Equal(t, expected, cmdArgs)
1360 |
1361 | expected = []string{"list", "plugins"}
1362 | args = strings.Split("fmcsadmin list plugins --stats", " ")
1363 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1364 | assert.Equal(t, true, resultFlags.statsFlag)
1365 | assert.Equal(t, expected, cmdArgs)
1366 |
1367 | expected = []string{"list", "plugins"}
1368 | args = strings.Split("fmcsadmin list -s plugins", " ")
1369 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1370 | assert.Equal(t, true, resultFlags.statsFlag)
1371 | assert.Equal(t, expected, cmdArgs)
1372 |
1373 | expected = []string{"list", "plugins"}
1374 | args = strings.Split("fmcsadmin list --stats plugins", " ")
1375 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1376 | assert.Equal(t, true, resultFlags.statsFlag)
1377 | assert.Equal(t, expected, cmdArgs)
1378 |
1379 | // list schedules
1380 | expected = []string{"list", "schedules"}
1381 | args = strings.Split("fmcsadmin list schedules", " ")
1382 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1383 | assert.Equal(t, false, resultFlags.statsFlag)
1384 | assert.Equal(t, expected, cmdArgs)
1385 |
1386 | expected = []string{"list", "schedules"}
1387 | args = strings.Split("fmcsadmin -s list schedules", " ")
1388 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1389 | assert.Equal(t, true, resultFlags.statsFlag)
1390 | assert.Equal(t, expected, cmdArgs)
1391 |
1392 | expected = []string{"list", "schedules"}
1393 | args = strings.Split("fmcsadmin --stats list schedules", " ")
1394 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1395 | assert.Equal(t, true, resultFlags.statsFlag)
1396 | assert.Equal(t, expected, cmdArgs)
1397 |
1398 | expected = []string{"list", "schedules"}
1399 | args = strings.Split("fmcsadmin list schedules -s", " ")
1400 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1401 | assert.Equal(t, true, resultFlags.statsFlag)
1402 | assert.Equal(t, expected, cmdArgs)
1403 |
1404 | expected = []string{"list", "schedules"}
1405 | args = strings.Split("fmcsadmin list schedules --stats", " ")
1406 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1407 | assert.Equal(t, true, resultFlags.statsFlag)
1408 | assert.Equal(t, expected, cmdArgs)
1409 |
1410 | expected = []string{"list", "schedules"}
1411 | args = strings.Split("fmcsadmin list -s schedules", " ")
1412 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1413 | assert.Equal(t, true, resultFlags.statsFlag)
1414 | assert.Equal(t, expected, cmdArgs)
1415 |
1416 | expected = []string{"list", "schedules"}
1417 | args = strings.Split("fmcsadmin list --stats schedules", " ")
1418 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1419 | assert.Equal(t, true, resultFlags.statsFlag)
1420 | assert.Equal(t, expected, cmdArgs)
1421 |
1422 | /*
1423 | * open
1424 | * Usage: fmcsadmin OPEN [options] [FILE...] [PATH...]
1425 | *
1426 | * fmcsadmin open
1427 | * fmcsadmin open 1
1428 | * fmcsadmin open 1 2
1429 | * fmcsadmin open TestDB
1430 | * fmcsadmin open TestDB.fmp12
1431 | * fmcsadmin open "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"
1432 | * fmcsadmin open "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"
1433 | * fmcsadmin open "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"
1434 | * fmcsadmin open "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"
1435 | * fmcsadmin open "/opt/FileMaker/FileMaker Server/Data/Databases/"
1436 | * fmcsadmin open "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/"
1437 | * fmcsadmin open TestDB FMServer_Sample
1438 | * fmcsadmin --fqdn example.jp open TestDB
1439 | * fmcsadmin open -y TestDB
1440 | * fmcsadmin open -u USERNAME TestDB
1441 | * fmcsadmin open -p PASSWORD TestDB
1442 | * fmcsadmin open -u USERNAME -p PASSWORD TestDB
1443 | * fmcsadmin open --key ENCRYPTPASS TestDB
1444 | * fmcsadmin open --key ENCRYPTPASS --savekey TestDB
1445 | */
1446 | expected = []string{"open", "TestDB"}
1447 | args = strings.Split("fmcsadmin open TestDB", " ")
1448 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1449 | assert.Equal(t, "", resultFlags.key)
1450 | assert.Equal(t, expected, cmdArgs)
1451 |
1452 | expected = []string{"open", "TestDB"}
1453 | args = strings.Split("fmcsadmin --key KEY open TestDB", " ")
1454 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1455 | assert.Equal(t, "KEY", resultFlags.key)
1456 | assert.Equal(t, expected, cmdArgs)
1457 |
1458 | expected = []string{"open", "TestDB"}
1459 | args = strings.Split("fmcsadmin open TestDB --key KEY", " ")
1460 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1461 | assert.Equal(t, "KEY", resultFlags.key)
1462 | assert.Equal(t, expected, cmdArgs)
1463 |
1464 | expected = []string{"open", "TestDB"}
1465 | args = strings.Split("fmcsadmin open --key KEY TestDB", " ")
1466 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1467 | assert.Equal(t, "KEY", resultFlags.key)
1468 | assert.Equal(t, expected, cmdArgs)
1469 |
1470 | expected = []string{"open", "TestDB"}
1471 | args = strings.Split("fmcsadmin open --key KEY TestDB", " ")
1472 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1473 | assert.Equal(t, "KEY", resultFlags.key)
1474 | assert.Equal(t, expected, cmdArgs)
1475 |
1476 | expected = []string{"open"}
1477 | args = strings.Split("fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD open --key KEY", " ")
1478 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1479 | assert.Equal(t, "example.jp", resultFlags.fqdn)
1480 | assert.Equal(t, "USERNAME", resultFlags.username)
1481 | assert.Equal(t, "PASSWORD", resultFlags.password)
1482 | assert.Equal(t, "KEY", resultFlags.key)
1483 | assert.Equal(t, expected, cmdArgs)
1484 |
1485 | expected = []string{"open"}
1486 | args = strings.Split("fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD open --key KEY --savekey", " ")
1487 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1488 | assert.Equal(t, "example.jp", resultFlags.fqdn)
1489 | assert.Equal(t, "USERNAME", resultFlags.username)
1490 | assert.Equal(t, "PASSWORD", resultFlags.password)
1491 | assert.Equal(t, "KEY", resultFlags.key)
1492 | assert.Equal(t, expected, cmdArgs)
1493 |
1494 | /*
1495 | * pause
1496 | * Usage: fmcsadmin PAUSE [FILE...] [PATH...]
1497 | *
1498 | * fmcsadmin pause
1499 | * fmcsadmin pause 1
1500 | * fmcsadmin pause 1 2
1501 | * fmcsadmin pause TestDB
1502 | * fmcsadmin pause TestDB.fmp12
1503 | * fmcsadmin pause "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"
1504 | * fmcsadmin pause "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"
1505 | * fmcsadmin pause "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"
1506 | * fmcsadmin pause "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"
1507 | * fmcsadmin pause "/opt/FileMaker/FileMaker Server/Data/Databases/"
1508 | * fmcsadmin pause "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/"
1509 | * fmcsadmin pause TestDB FMServer_Sample
1510 | * fmcsadmin --fqdn example.jp pause TestDB
1511 | * fmcsadmin pause -u USERNAME TestDB
1512 | * fmcsadmin pause -p PASSWORD TestDB
1513 | * fmcsadmin pause -u USERNAME -p PASSWORD TestDB
1514 | */
1515 | expected = []string{"pause", "TestDB"}
1516 | args = strings.Split("fmcsadmin pause TestDB", " ")
1517 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1518 | assert.Equal(t, expected, cmdArgs)
1519 |
1520 | expected = []string{"pause", "TestDB", "FMServer_Sample"}
1521 | args = strings.Split("fmcsadmin pause TestDB FMServer_Sample", " ")
1522 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1523 | assert.Equal(t, expected, cmdArgs)
1524 |
1525 | /*
1526 | * remove
1527 | * Usage: fmcsadmin REMOVE [FILE...] [PATH...]
1528 | *
1529 | * fmcsadmin remove
1530 | * fmcsadmin remove 1
1531 | * fmcsadmin remove 1 2
1532 | * fmcsadmin remove TestDB
1533 | * fmcsadmin remove TestDB.fmp12
1534 | * fmcsadmin remove 11.fmp12
1535 | * fmcsadmin remove "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"
1536 | * fmcsadmin remove "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"
1537 | * fmcsadmin remove "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"
1538 | * fmcsadmin remove "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"
1539 | * fmcsadmin remove "/opt/FileMaker/FileMaker Server/Data/Databases/"
1540 | * fmcsadmin remove "filemac:/Macintosh HD/Library/FileMaker Server/Data/Databases/"
1541 | * fmcsadmin remove "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/"
1542 | * fmcsadmin remove TestDB FMServer_Sample
1543 | * fmcsadmin --fqdn example.jp remove TestDB
1544 | * fmcsadmin remove -u USERNAME TestDB
1545 | * fmcsadmin remove -p PASSWORD TestDB
1546 | * fmcsadmin remove -u USERNAME -p PASSWORD TestDB
1547 | * fmcsadmin remove -u USERNAME -p PASSWORD TestDB -y
1548 | */
1549 | expected = []string{"remove", "TestDB"}
1550 | args = strings.Split("fmcsadmin remove TestDB", " ")
1551 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1552 | assert.Equal(t, expected, cmdArgs)
1553 |
1554 | expected = []string{"remove", "TestDB", "FMServer_Sample"}
1555 | args = strings.Split("fmcsadmin remove TestDB FMServer_Sample", " ")
1556 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1557 | assert.Equal(t, expected, cmdArgs)
1558 |
1559 | /*
1560 | * resume
1561 | * Usage: fmcsadmin RESUME [FILE...] [PATH...]
1562 | *
1563 | * fmcsadmin resume
1564 | * fmcsadmin resume 1
1565 | * fmcsadmin resume 1 2
1566 | * fmcsadmin resume TestDB
1567 | * fmcsadmin resume TestDB.fmp12
1568 | * fmcsadmin resume "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"
1569 | * fmcsadmin resume "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"
1570 | * fmcsadmin resume "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"
1571 | * fmcsadmin resume "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"
1572 | * fmcsadmin resume "/opt/FileMaker/FileMaker Server/Data/Databases/"
1573 | * fmcsadmin resume "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/"
1574 | * fmcsadmin resume TestDB FMServer_Sample
1575 | * fmcsadmin --fqdn example.jp resume TestDB
1576 | * fmcsadmin resume -u USERNAME TestDB
1577 | * fmcsadmin resume -p PASSWORD TestDB
1578 | * fmcsadmin resume -u USERNAME -p PASSWORD TestDB
1579 | */
1580 | expected = []string{"resume", "TestDB"}
1581 | args = strings.Split("fmcsadmin resume TestDB", " ")
1582 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1583 | assert.Equal(t, expected, cmdArgs)
1584 |
1585 | expected = []string{"resume", "TestDB", "FMServer_Sample"}
1586 | args = strings.Split("fmcsadmin resume TestDB FMServer_Sample", " ")
1587 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1588 | assert.Equal(t, expected, cmdArgs)
1589 |
1590 | /*
1591 | * run
1592 | * Usage: fmcsadmin RUN SCHEDULE [SCHEDULE_NUMBER]
1593 | *
1594 | * fmcsadmin run schedule 2
1595 | * fmcsadmin --fqdn example.jp run schedule 2
1596 | * fmcsadmin --fqdn example.jp -u USERNAME run schedule 2
1597 | * fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD run schedule 2
1598 | */
1599 | expected = []string{"run", "schedule", "2"}
1600 | args = strings.Split("fmcsadmin run schedule 2", " ")
1601 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1602 | assert.Equal(t, expected, cmdArgs)
1603 |
1604 | /*
1605 | * send
1606 | * Usage: fmcsadmin SEND [options] [CLIENT_NUMBER] [FILE...] [PATH...]
1607 | *
1608 | * fmcsadmin send -m "This is a test message"
1609 | * fmcsadmin send -c 2 -m "This is a test message"
1610 | * etc.
1611 | */
1612 |
1613 | /*
1614 | * set
1615 | * Usage: fmcsadmin SET CONFIG_TYPE [NAME1=VALUE1 NAME2=VALUE2 ...]
1616 | *
1617 | * fmcsadmin set serverconfig hostedfiles=125 scriptsessions=100
1618 | * fmcsadmin set cwpconfig enablephp=true
1619 | * fmcsadmin set cwpconfig enablexml=true
1620 | * fmcsadmin set cwpconfig encoding=UTF-8
1621 | * fmcsadmin set cwpconfig encoding=ISO-8859-1
1622 | * fmcsadmin set cwpconfig locale=en
1623 | * fmcsadmin set cwpconfig locale=ja
1624 | * fmcsadmin set cwpconfig prevalidation=false
1625 | * fmcsadmin set cwpconfig enablephp=true usefmphp=false
1626 | * fmcsadmin set cwpconfig enablephp=true usefmphp=true
1627 | * fmcsadmin --fqdn example.jp set cwpconfig enablephp=true usefmphp=true
1628 | * fmcsadmin --fqdn example.jp -u USERNAME set cwpconfig enablephp=true usefmphp=true
1629 | * fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD set cwpconfig enablephp=true usefmphp=true
1630 | * fmcsadmin set serverprefs maxguests=125 maxfiles=256
1631 | * fmcsadmin set serverprefs AuthenticatedStream=1
1632 | * fmcsadmin set serverprefs AuthenticatedStream=2
1633 | * fmcsadmin set serverprefs ParallelBackupEnabled=false
1634 | * fmcsadmin set serverprefs ParallelBackupEnabled=true
1635 | * fmcsadmin set serverprefs PersistCacheEnabled=false
1636 | * fmcsadmin set serverprefs PersistCacheEnabled=true
1637 | * fmcsadmin set serverprefs SyncPersistCache=false
1638 | * fmcsadmin set serverprefs SyncPersistCache=true
1639 | * fmcsadmin set serverprefs DatabaseServerAutoRestart=false
1640 | * fmcsadmin set serverprefs DatabaseServerAutoRestart=true
1641 | * fmcsadmin set serverprefs BlockNewUsersEnabled=false
1642 | * fmcsadmin set serverprefs BlockNewUsersEnabled=true
1643 | * fmcsadmin set serverprefs EnableHttpProtocolNetwork=false
1644 | * fmcsadmin set serverprefs EnableHttpProtocolNetwork=true
1645 | * fmcsadmin set serverprefs OnlyOpenLastOpenedDatabases=false
1646 | * fmcsadmin set serverprefs OnlyOpenLastOpenedDatabases=true
1647 | * fmcsadmin --fqdn example.jp set serverconfig hostedfiles=125 scriptsessions=100
1648 | * fmcsadmin --fqdn example.jp -u USERNAME set serverconfig hostedfiles=125 scriptsessions=100
1649 | * fmcsadmin --fqdn example.jp -u USERNAME -p PASSWORD set serverconfig hostedfiles=125 scriptsessions=100
1650 | * etc.
1651 | */
1652 |
1653 | /*
1654 | * status
1655 | * Usage: fmcsadmin STATUS [TYPE] [CLIENT_NUMBER] [FILE...]
1656 | *
1657 | * fmcsadmin status client 1
1658 | * fmcsadmin status file TestDB
1659 | * fmcsadmin status file "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"
1660 | * fmcsadmin status file "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"
1661 | * fmcsadmin status file "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"
1662 | * fmcsadmin status file "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"
1663 | * fmcsadmin status file TestDB FMServer_Sample
1664 | */
1665 | expected = []string{"status", "client", "1"}
1666 | args = strings.Split("fmcsadmin status client 1", " ")
1667 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1668 | assert.Equal(t, expected, cmdArgs)
1669 |
1670 | expected = []string{"status", "file", "TestDB"}
1671 | args = strings.Split("fmcsadmin status file TestDB", " ")
1672 | cmdArgs, resultFlags, _ = getFlags(args, flags)
1673 | assert.Equal(t, expected, cmdArgs)
1674 | }
1675 |
1676 | func TestOutputInvalidCommandErrorMessage(t *testing.T) {
1677 | outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
1678 | cli := &cli{outStream: outStream, errStream: errStream}
1679 | status := outputInvalidCommandErrorMessage(cli)
1680 | assert.Equal(t, 248, status)
1681 | }
1682 |
1683 | func TestGetBaseURI(t *testing.T) {
1684 | if runtime.GOOS == "linux" {
1685 | assert.Equal(t, "http://127.0.0.1:16001", getBaseURI(""))
1686 | } else if runtime.GOOS == "darwin" || runtime.GOOS == "windows" {
1687 | assert.Equal(t, "http://127.0.0.1:16001", getBaseURI(""))
1688 | }
1689 | assert.Equal(t, "https://example.jp", getBaseURI("example.jp"))
1690 | assert.Equal(t, "https://example.jp", getBaseURI("example.jp "))
1691 | assert.Equal(t, "https://example.jp", getBaseURI(" example.jp"))
1692 | }
1693 |
1694 | func TestGetAPIBasePath(t *testing.T) {
1695 | assert.Equal(t, "/fmi/admin/api/v2", getAPIBasePath())
1696 | }
1697 |
1698 | func TestGetServerVersionAsFloat(t *testing.T) {
1699 | version, _ := getServerVersionAsFloat("19.3.1")
1700 | assert.Equal(t, 19.3, version)
1701 | version, _ = getServerVersionAsFloat("19.3.2")
1702 | assert.Equal(t, 19.3, version)
1703 | }
1704 |
1705 | func TestComparePath(t *testing.T) {
1706 | assert.Equal(t, false, comparePath("TestDB", "TestDB2"))
1707 |
1708 | assert.Equal(t, true, comparePath("TestDB", "TestDB"))
1709 | assert.Equal(t, true, comparePath("TestDB.fmp12", "TestDB.fmp12"))
1710 | assert.Equal(t, true, comparePath("TestDB", "TestDB.fmp12"))
1711 | assert.Equal(t, true, comparePath("TestDB.fmp12", "TestDB"))
1712 |
1713 | assert.Equal(t, true, comparePath("filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/", "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/"))
1714 |
1715 | assert.Equal(t, true, comparePath("filemac:/opt/FileMaker/FileMaker Server/Data/Databases/", "filemac:/opt/FileMaker/FileMaker Server/Data/Databases/"))
1716 |
1717 | assert.Equal(t, true, comparePath("filewin:/opt/FileMaker/FileMaker Server/Data/Databases/", "filewin:/opt/FileMaker/FileMaker Server/Data/Databases/"))
1718 |
1719 | assert.Equal(t, true, comparePath("filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB", "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"))
1720 | assert.Equal(t, true, comparePath("filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12", "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"))
1721 | assert.Equal(t, true, comparePath("filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB", "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"))
1722 | assert.Equal(t, true, comparePath("filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12", "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"))
1723 |
1724 | assert.Equal(t, true, comparePath("filemac:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB", "filemac:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"))
1725 | assert.Equal(t, true, comparePath("filemac:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12", "filemac:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"))
1726 | assert.Equal(t, true, comparePath("filemac:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB", "filemac:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"))
1727 | assert.Equal(t, true, comparePath("filemac:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12", "filemac:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"))
1728 |
1729 | assert.Equal(t, true, comparePath("filemac:/Macintosh HD/Library/FileMaker Server/Data/Databases/test/TestDB", "/Volumes/Macintosh HD/Library/FileMaker Server/Data/Databases/test/TestDB"))
1730 | assert.Equal(t, true, comparePath("filemac:/Macintosh HD/Library/FileMaker Server/Data/Databases/test/TestDB", "/Volumes/Macintosh HD/Library/FileMaker Server/Data/Databases/test/TestDB.fmp12"))
1731 | assert.Equal(t, true, comparePath("filemac:/Macintosh HD/Library/FileMaker Server/Data/Databases/test/TestDB.fmp12", "/Volumes/Macintosh HD/Library/FileMaker Server/Data/Databases/test/TestDB"))
1732 | assert.Equal(t, true, comparePath("filemac:/Macintosh HD/Library/FileMaker Server/Data/Databases/test/TestDB.fmp12", "/Volumes/Macintosh HD/Library/FileMaker Server/Data/Databases/test/TestDB.fmp12"))
1733 |
1734 | assert.Equal(t, true, comparePath("filewin:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB", "filewin:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"))
1735 | assert.Equal(t, true, comparePath("filewin:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12", "filewin:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"))
1736 | assert.Equal(t, true, comparePath("filewin:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB", "filewin:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"))
1737 | assert.Equal(t, true, comparePath("filewin:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12", "filewin:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"))
1738 |
1739 | assert.Equal(t, true, comparePath("/opt/FileMaker/FileMaker Server/Data/Databases/TestDB", "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"))
1740 | assert.Equal(t, true, comparePath("/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12", "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"))
1741 | assert.Equal(t, true, comparePath("/opt/FileMaker/FileMaker Server/Data/Databases/TestDB", "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"))
1742 | assert.Equal(t, true, comparePath("/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12", "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"))
1743 |
1744 | assert.Equal(t, true, comparePath("/opt/FileMaker/FileMaker Server/Data/Databases/TestDB", "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"))
1745 | assert.Equal(t, true, comparePath("/opt/FileMaker/FileMaker Server/Data/Databases/TestDB", "filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"))
1746 | assert.Equal(t, true, comparePath("filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12", "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"))
1747 | assert.Equal(t, true, comparePath("filelinux:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12", "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"))
1748 |
1749 | if runtime.GOOS == "darwin" {
1750 | assert.Equal(t, true, comparePath("/opt/FileMaker/FileMaker Server/Data/Databases/TestDB", "filemac:/"+getVolumeName()+"/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"))
1751 | assert.Equal(t, true, comparePath("/opt/FileMaker/FileMaker Server/Data/Databases/TestDB", "filemac:/"+getVolumeName()+"/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"))
1752 | assert.Equal(t, true, comparePath("filemac:/"+getVolumeName()+"/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12", "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"))
1753 | assert.Equal(t, true, comparePath("filemac:/"+getVolumeName()+"/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12", "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"))
1754 | }
1755 |
1756 | assert.Equal(t, true, comparePath("/opt/FileMaker/FileMaker Server/Data/Databases/TestDB", "filewin:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"))
1757 | assert.Equal(t, true, comparePath("/opt/FileMaker/FileMaker Server/Data/Databases/TestDB", "filewin:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"))
1758 | assert.Equal(t, true, comparePath("filewin:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12", "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB"))
1759 | assert.Equal(t, true, comparePath("filewin:/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12", "/opt/FileMaker/FileMaker Server/Data/Databases/TestDB.fmp12"))
1760 | }
1761 |
1762 | func TestGetErrorDescription(t *testing.T) {
1763 | assert.Equal(t, "", getErrorDescription(0))
1764 | assert.Equal(t, "Unknown error", getErrorDescription(-1))
1765 | assert.Equal(t, "Unavailable command", getErrorDescription(3))
1766 | assert.Equal(t, "Command is unknown", getErrorDescription(4))
1767 | assert.Equal(t, "Empty result", getErrorDescription(8))
1768 | assert.Equal(t, "Access denied", getErrorDescription(9))
1769 | assert.Equal(t, "Not Supported", getErrorDescription(21))
1770 | assert.Equal(t, "Invalid user account and/or password; please try again", getErrorDescription(212))
1771 | assert.Equal(t, "Unable to open the file", getErrorDescription(802))
1772 | assert.Equal(t, "Parameter missing", getErrorDescription(958))
1773 | assert.Equal(t, "Parameter is invalid", getErrorDescription(960))
1774 | assert.Equal(t, "Parameter value is invalid", getErrorDescription(1708))
1775 | assert.Equal(t, "Service already running", getErrorDescription(10006))
1776 | assert.Equal(t, "Schedule at specified index does not exist", getErrorDescription(10600))
1777 | assert.Equal(t, "Schedule is misconfigured; invalid taskType or run status", getErrorDescription(10601))
1778 | assert.Equal(t, "Schedule can't be created or duplicated", getErrorDescription(10603))
1779 | assert.Equal(t, "Cannot enable schedule", getErrorDescription(10604))
1780 | assert.Equal(t, "No schedules created in configuration file", getErrorDescription(10610))
1781 | assert.Equal(t, "Schedule name is already used", getErrorDescription(10611))
1782 | assert.Equal(t, "No applicable files for this operation", getErrorDescription(10904))
1783 | assert.Equal(t, "Script is missing", getErrorDescription(10906))
1784 | assert.Equal(t, "System script aborted", getErrorDescription(10908))
1785 | assert.Equal(t, "Invalid command", getErrorDescription(11000))
1786 | assert.Equal(t, "Unable to create command", getErrorDescription(11002))
1787 | assert.Equal(t, "Disconnect Client invalid ID", getErrorDescription(11005))
1788 | assert.Equal(t, "File permission error", getErrorDescription(20402))
1789 | assert.Equal(t, "File not found or not accessible.", getErrorDescription(20405))
1790 | assert.Equal(t, "File already exists", getErrorDescription(20406))
1791 | assert.Equal(t, "File read error", getErrorDescription(20408))
1792 | assert.Equal(t, "SSL certificate expired", getErrorDescription(20630))
1793 | assert.Equal(t, "SSL certificate verification error", getErrorDescription(20632))
1794 | assert.Equal(t, "Parameters are invalid", getErrorDescription(25004))
1795 | assert.Equal(t, "Invalid session error", getErrorDescription(25006))
1796 | }
1797 |
1798 | func TestGetDateTimeStringOfCurrentTimeZone(t *testing.T) {
1799 | const location = "Asia/Tokyo"
1800 | loc, err := time.LoadLocation(location)
1801 | if err != nil {
1802 | loc = time.FixedZone(location, 9*60*60)
1803 | }
1804 | time.Local = loc
1805 | assert.Equal(t, "", getDateTimeStringOfCurrentTimeZone("", "2006/01/02 15:04:05", false))
1806 | assert.Equal(t, "", getDateTimeStringOfCurrentTimeZone("0000-00-00 00:00:00", "2006/01/02 15:04:05", false))
1807 | assert.Equal(t, "", getDateTimeStringOfCurrentTimeZone("0000-00-00 00:00:00 GMT", "2006/01/02 15:04:05", false))
1808 |
1809 | //assert.Equal(t, "2006/01/03 00:04", getDateTimeStringOfCurrentTimeZone("2006-01-02T15:04:05"))
1810 | assert.Equal(t, "2006/01/02 15:04", getDateTimeStringOfCurrentTimeZone("2006-01-02T15:04:05", "2006/01/02 15:04", false))
1811 | assert.Equal(t, "2006/01/03 00:04", getDateTimeStringOfCurrentTimeZone("2006-01-02T15:04:05", "2006/01/02 15:04", true))
1812 | assert.Equal(t, "2006/01/02 15:04:05", getDateTimeStringOfCurrentTimeZone("2006-01-02T15:04:05", "2006/01/02 15:04:05", false))
1813 |
1814 | //assert.Equal(t, "2006/01/03 00:04", getDateTimeStringOfCurrentTimeZone("2006-01-02 15:04:05 GMT"))
1815 | assert.Equal(t, "2006/01/02 15:04", getDateTimeStringOfCurrentTimeZone("2006-01-02 15:04:05 GMT", "2006/01/02 15:04", false))
1816 | assert.Equal(t, "2006/01/03 00:04", getDateTimeStringOfCurrentTimeZone("2006-01-02 15:04:05 GMT", "2006/01/02 15:04", true))
1817 | assert.Equal(t, "2006/01/02 15:04:05", getDateTimeStringOfCurrentTimeZone("2006-01-02 15:04:05 GMT", "2006/01/02 15:04:05", false))
1818 | }
1819 |
--------------------------------------------------------------------------------