Add --account N flag and full credential resolution to AWK, COBOL, Forth, Prolog
All four implementations now support: - --account N flag: bypasses env vars, loads credentials from accounts.csv row N - UNSANDBOX_ACCOUNT env var: selects default CSV row (fallback to row 0) - accounts.csv fallback: tries ~/.unsandbox/accounts.csv then ./accounts.csv - Correct priority: explicit flags > --account N > env vars > CSV row 0 AWK: Added load_accounts_csv() with native getline, GLOBAL_ACCOUNT_INDEX variable, pre-scan loop in END block for --account/-p/-k global flags. COBOL: Added GET-CREDENTIALS paragraph with shell-based CSV resolution, WS-ACCOUNT-INDEX variable, --account N parsing at start of MAIN-PROCEDURE, all HANDLE-* paragraphs now PERFORM GET-CREDENTIALS instead of inline credential fetching. Forth: Added account-index variable, load-accounts-csv-index word, sarg shifted-arg accessor, arg-shift variable, --account N detection in main. All handler N arg calls replaced with N sarg to support the shift. Prolog: Added load_accounts_csv/3 predicate with file I/O, nb_setval/nb_getval for account_index global, --account N pattern matching in main/1, get_public_key/1 and get_secret_key/1 now check account_index before env vars.
This commit is contained in:
parent
422985c6db
commit
7dd16bf796
4 changed files with 455 additions and 194 deletions
|
|
@ -64,6 +64,9 @@ BEGIN {
|
|||
GREEN = "\033[32m"
|
||||
YELLOW = "\033[33m"
|
||||
RESET = "\033[0m"
|
||||
|
||||
# Global credential state
|
||||
GLOBAL_ACCOUNT_INDEX = -1
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
|
|
@ -106,32 +109,84 @@ function health_check( cmd, result) {
|
|||
return (result == "200")
|
||||
}
|
||||
|
||||
function get_api_keys( public_key, secret_key, cmd) {
|
||||
# Get public key
|
||||
cmd = "echo -n $UNSANDBOX_PUBLIC_KEY"
|
||||
cmd | getline public_key
|
||||
close(cmd)
|
||||
|
||||
# Get secret key
|
||||
cmd = "echo -n $UNSANDBOX_SECRET_KEY"
|
||||
cmd | getline secret_key
|
||||
close(cmd)
|
||||
|
||||
# Fallback to old UNSANDBOX_API_KEY for backwards compat
|
||||
if (public_key == "") {
|
||||
cmd = "echo -n $UNSANDBOX_API_KEY"
|
||||
cmd | getline public_key
|
||||
close(cmd)
|
||||
secret_key = ""
|
||||
function load_accounts_csv(index , home, path, line, fields, count, pk, sk) {
|
||||
home = ENVIRON["HOME"]
|
||||
count = -1
|
||||
pk = ""
|
||||
sk = ""
|
||||
# Try ~/.unsandbox/accounts.csv first
|
||||
path = home "/.unsandbox/accounts.csv"
|
||||
while ((getline line < path) > 0) {
|
||||
if (line ~ /^[[:space:]]*$/ || line ~ /^[[:space:]]*#/) continue
|
||||
count++
|
||||
if (count == index) {
|
||||
split(line, fields, ",")
|
||||
pk = fields[1]; sk = fields[2]
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", pk)
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", sk)
|
||||
close(path)
|
||||
GLOBAL_PUBLIC_KEY = pk; GLOBAL_SECRET_KEY = sk
|
||||
return 1
|
||||
}
|
||||
}
|
||||
close(path)
|
||||
# Try ./accounts.csv as fallback
|
||||
count = -1; path = "accounts.csv"
|
||||
while ((getline line < path) > 0) {
|
||||
if (line ~ /^[[:space:]]*$/ || line ~ /^[[:space:]]*#/) continue
|
||||
count++
|
||||
if (count == index) {
|
||||
split(line, fields, ",")
|
||||
pk = fields[1]; sk = fields[2]
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", pk)
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", sk)
|
||||
close(path)
|
||||
GLOBAL_PUBLIC_KEY = pk; GLOBAL_SECRET_KEY = sk
|
||||
return 1
|
||||
}
|
||||
}
|
||||
close(path)
|
||||
return 0
|
||||
}
|
||||
|
||||
if (public_key == "") {
|
||||
print RED "Error: UNSANDBOX_PUBLIC_KEY or UNSANDBOX_API_KEY not set" RESET > "/dev/stderr"
|
||||
function get_api_keys( public_key, secret_key, cmd, default_index) {
|
||||
# Priority 1: already set via -p/-k flags
|
||||
if (GLOBAL_PUBLIC_KEY != "" && GLOBAL_SECRET_KEY != "") { return }
|
||||
|
||||
# Priority 2: --account N bypasses env vars
|
||||
if (GLOBAL_ACCOUNT_INDEX >= 0) {
|
||||
if (load_accounts_csv(GLOBAL_ACCOUNT_INDEX)) {
|
||||
if (GLOBAL_PUBLIC_KEY != "") return
|
||||
}
|
||||
print RED "Error: Account index " GLOBAL_ACCOUNT_INDEX " not found in accounts.csv" RESET > "/dev/stderr"
|
||||
exit 1
|
||||
}
|
||||
|
||||
GLOBAL_PUBLIC_KEY = public_key
|
||||
GLOBAL_SECRET_KEY = secret_key
|
||||
# Priority 3: env vars UNSANDBOX_PUBLIC_KEY / UNSANDBOX_SECRET_KEY
|
||||
cmd = "echo -n $UNSANDBOX_PUBLIC_KEY"; cmd | getline public_key; close(cmd)
|
||||
cmd = "echo -n $UNSANDBOX_SECRET_KEY"; cmd | getline secret_key; close(cmd)
|
||||
if (public_key != "" && secret_key != "") {
|
||||
GLOBAL_PUBLIC_KEY = public_key; GLOBAL_SECRET_KEY = secret_key; return
|
||||
}
|
||||
|
||||
# Fallback to legacy UNSANDBOX_API_KEY for backwards compat
|
||||
if (public_key == "") {
|
||||
cmd = "echo -n $UNSANDBOX_API_KEY"; cmd | getline public_key; close(cmd)
|
||||
secret_key = ""
|
||||
}
|
||||
if (public_key != "") {
|
||||
GLOBAL_PUBLIC_KEY = public_key; GLOBAL_SECRET_KEY = secret_key; return
|
||||
}
|
||||
|
||||
# Priority 4/5: accounts.csv with UNSANDBOX_ACCOUNT env var or row 0
|
||||
cmd = "echo -n $UNSANDBOX_ACCOUNT"; cmd | getline default_index; close(cmd)
|
||||
if (default_index == "") default_index = 0
|
||||
if (load_accounts_csv(default_index + 0)) {
|
||||
if (GLOBAL_PUBLIC_KEY != "") return
|
||||
}
|
||||
|
||||
print RED "Error: UNSANDBOX_PUBLIC_KEY or UNSANDBOX_API_KEY not set" RESET > "/dev/stderr"
|
||||
exit 1
|
||||
}
|
||||
|
||||
function get_extension(filename) {
|
||||
|
|
@ -2359,6 +2414,20 @@ END {
|
|||
exit 0
|
||||
}
|
||||
|
||||
# Pre-scan ARGV for global flags: --account N, -p KEY, -k KEY
|
||||
for (_gi = 1; _gi < ARGC; _gi++) {
|
||||
if (ARGV[_gi] == "--account" && _gi + 1 < ARGC) {
|
||||
GLOBAL_ACCOUNT_INDEX = ARGV[_gi + 1] + 0
|
||||
_gi++
|
||||
} else if (ARGV[_gi] == "-p" && _gi + 1 < ARGC) {
|
||||
GLOBAL_PUBLIC_KEY = ARGV[_gi + 1]
|
||||
_gi++
|
||||
} else if (ARGV[_gi] == "-k" && _gi + 1 < ARGC) {
|
||||
GLOBAL_SECRET_KEY = ARGV[_gi + 1]
|
||||
_gi++
|
||||
}
|
||||
}
|
||||
|
||||
if (ARGV[1] == "session") {
|
||||
if (ARGC >= 3 && ARGV[2] == "--list") {
|
||||
session_list()
|
||||
|
|
|
|||
|
|
@ -45,15 +45,21 @@
|
|||
SELECT SOURCE-FILE ASSIGN TO WS-FILENAME
|
||||
ORGANIZATION IS LINE SEQUENTIAL
|
||||
FILE STATUS IS WS-FILE-STATUS.
|
||||
SELECT CRED-FILE ASSIGN TO "/tmp/unsb_creds.txt"
|
||||
ORGANIZATION IS LINE SEQUENTIAL
|
||||
FILE STATUS IS WS-CRED-STATUS.
|
||||
|
||||
DATA DIVISION.
|
||||
FILE SECTION.
|
||||
FD SOURCE-FILE.
|
||||
01 SOURCE-LINE PIC X(1024).
|
||||
FD CRED-FILE.
|
||||
01 CRED-LINE PIC X(512).
|
||||
|
||||
WORKING-STORAGE SECTION.
|
||||
01 WS-FILENAME PIC X(256).
|
||||
01 WS-FILE-STATUS PIC XX.
|
||||
01 WS-CRED-STATUS PIC XX.
|
||||
01 WS-API-KEY PIC X(256).
|
||||
01 WS-PUBLIC-KEY PIC X(256).
|
||||
01 WS-SECRET-KEY PIC X(256).
|
||||
|
|
@ -97,12 +103,23 @@
|
|||
01 WS-UOD-ENABLED PIC X(8).
|
||||
01 WS-TYPE PIC X(32).
|
||||
01 WS-SHELL PIC X(32).
|
||||
01 WS-ACCOUNT-INDEX PIC S9(4) VALUE -1.
|
||||
01 WS-ACCOUNT-STR PIC X(16).
|
||||
01 WS-ACCT-POS PIC 9(4) VALUE 0.
|
||||
01 WS-ERROR-MSG PIC X(256).
|
||||
|
||||
PROCEDURE DIVISION.
|
||||
MAIN-PROCEDURE.
|
||||
* Get command line argument (first argument)
|
||||
* Get first command line argument
|
||||
ACCEPT WS-ARG1 FROM COMMAND-LINE.
|
||||
|
||||
* Pre-scan: handle --account N global flag before subcommand
|
||||
IF WS-ARG1 = "--account"
|
||||
ACCEPT WS-ACCOUNT-STR FROM ARGUMENT-VALUE
|
||||
MOVE FUNCTION NUMVAL(WS-ACCOUNT-STR) TO WS-ACCOUNT-INDEX
|
||||
ACCEPT WS-ARG1 FROM ARGUMENT-VALUE
|
||||
END-IF.
|
||||
|
||||
IF WS-ARG1 = SPACES
|
||||
DISPLAY "Usage: un.cob <source_file>" UPON SYSERR
|
||||
DISPLAY " un.cob session [options]" UPON SYSERR
|
||||
|
|
@ -147,7 +164,94 @@
|
|||
PERFORM HANDLE-EXECUTE.
|
||||
STOP RUN.
|
||||
|
||||
GET-CREDENTIALS.
|
||||
* If already set, return immediately
|
||||
IF WS-PUBLIC-KEY NOT = SPACES AND WS-SECRET-KEY NOT = SPACES
|
||||
EXIT PARAGRAPH
|
||||
END-IF.
|
||||
|
||||
* Build shell script to resolve credentials with full priority
|
||||
IF WS-ACCOUNT-INDEX >= 0
|
||||
MOVE WS-ACCOUNT-INDEX TO WS-ACCOUNT-STR
|
||||
STRING "IDX=" FUNCTION TRIM(WS-ACCOUNT-STR) "; "
|
||||
"PK=''; SK=''; CNT=-1; "
|
||||
"for CSV in \"$HOME/.unsandbox/accounts.csv\" "
|
||||
"\"./accounts.csv\"; do "
|
||||
"[ -f \"$CSV\" ] || continue; "
|
||||
"while IFS= read -r line || [ -n \"$line\" ]; do "
|
||||
"case \"$line\" in \"#\"*|\"\"|\" \"*) continue ;; esac; "
|
||||
"CNT=$((CNT+1)); "
|
||||
"if [ \"$CNT\" -eq \"$IDX\" ]; then "
|
||||
"PK=$(echo \"$line\" | cut -d',' -f1 | tr -d ' '); "
|
||||
"SK=$(echo \"$line\" | cut -d',' -f2 | tr -d ' '); "
|
||||
"break 2; fi; "
|
||||
"done < \"$CSV\"; done; "
|
||||
"if [ -z \"$PK\" ]; then "
|
||||
"echo -e '\\x1b[31mError: Account index "
|
||||
FUNCTION TRIM(WS-ACCOUNT-STR)
|
||||
" not found in accounts.csv\\x1b[0m' >&2; exit 1; fi; "
|
||||
"printf '%s\\n%s\\n' \"$PK\" \"$SK\" "
|
||||
"> /tmp/unsb_creds.txt"
|
||||
DELIMITED BY SIZE INTO WS-CURL-CMD
|
||||
END-STRING
|
||||
ELSE
|
||||
STRING "PK=\"$UNSANDBOX_PUBLIC_KEY\"; "
|
||||
"SK=\"$UNSANDBOX_SECRET_KEY\"; "
|
||||
"if [ -z \"$PK\" ]; then PK=\"$UNSANDBOX_API_KEY\"; SK=''; fi; "
|
||||
"if [ -z \"$PK\" ]; then "
|
||||
"IDX=\"${UNSANDBOX_ACCOUNT:-0}\"; "
|
||||
"CNT=-1; "
|
||||
"for CSV in \"$HOME/.unsandbox/accounts.csv\" "
|
||||
"\"./accounts.csv\"; do "
|
||||
"[ -f \"$CSV\" ] || continue; "
|
||||
"while IFS= read -r line || [ -n \"$line\" ]; do "
|
||||
"case \"$line\" in \"#\"*|\"\"|\" \"*) continue ;; esac; "
|
||||
"CNT=$((CNT+1)); "
|
||||
"if [ \"$CNT\" -eq \"$IDX\" ]; then "
|
||||
"PK=$(echo \"$line\" | cut -d',' -f1 | tr -d ' '); "
|
||||
"SK=$(echo \"$line\" | cut -d',' -f2 | tr -d ' '); "
|
||||
"break 2; fi; "
|
||||
"done < \"$CSV\"; done; fi; "
|
||||
"if [ -z \"$PK\" ]; then "
|
||||
"echo -e '\\x1b[31mError: No credentials found\\x1b[0m' "
|
||||
">&2; exit 1; fi; "
|
||||
"printf '%s\\n%s\\n' \"$PK\" \"$SK\" "
|
||||
"> /tmp/unsb_creds.txt"
|
||||
DELIMITED BY SIZE INTO WS-CURL-CMD
|
||||
END-STRING
|
||||
END-IF.
|
||||
|
||||
CALL "SYSTEM" USING WS-CURL-CMD
|
||||
RETURNING WS-EXIT-CODE.
|
||||
IF WS-EXIT-CODE NOT = 0
|
||||
MOVE WS-EXIT-CODE TO RETURN-CODE
|
||||
STOP RUN
|
||||
END-IF.
|
||||
|
||||
* Read resolved credentials from temp file
|
||||
MOVE SPACES TO WS-PUBLIC-KEY.
|
||||
MOVE SPACES TO WS-SECRET-KEY.
|
||||
OPEN INPUT CRED-FILE.
|
||||
IF WS-CRED-STATUS = "00"
|
||||
READ CRED-FILE INTO WS-PUBLIC-KEY
|
||||
READ CRED-FILE INTO WS-SECRET-KEY
|
||||
CLOSE CRED-FILE
|
||||
END-IF.
|
||||
|
||||
IF WS-PUBLIC-KEY = SPACES
|
||||
DISPLAY "Error: Could not resolve credentials"
|
||||
UPON SYSERR
|
||||
MOVE 1 TO RETURN-CODE
|
||||
STOP RUN
|
||||
END-IF.
|
||||
|
||||
HANDLE-EXECUTE.
|
||||
* Get credentials
|
||||
PERFORM GET-CREDENTIALS.
|
||||
IF WS-API-KEY = SPACES
|
||||
MOVE WS-PUBLIC-KEY TO WS-API-KEY
|
||||
END-IF.
|
||||
|
||||
* Check if file exists
|
||||
OPEN INPUT SOURCE-FILE.
|
||||
IF WS-FILE-STATUS NOT = "00"
|
||||
|
|
@ -168,25 +272,14 @@
|
|||
STOP RUN
|
||||
END-IF.
|
||||
|
||||
* Get API key from environment
|
||||
ACCEPT WS-API-KEY FROM ENVIRONMENT "UNSANDBOX_API_KEY".
|
||||
|
||||
IF WS-API-KEY = SPACES
|
||||
DISPLAY "Error: UNSANDBOX_API_KEY not set" UPON SYSERR
|
||||
MOVE 1 TO RETURN-CODE
|
||||
STOP RUN
|
||||
END-IF.
|
||||
|
||||
* Use curl to make request
|
||||
PERFORM MAKE-EXECUTE-REQUEST.
|
||||
|
||||
HANDLE-SESSION.
|
||||
* Get API key
|
||||
ACCEPT WS-API-KEY FROM ENVIRONMENT "UNSANDBOX_API_KEY".
|
||||
* Get credentials
|
||||
PERFORM GET-CREDENTIALS.
|
||||
IF WS-API-KEY = SPACES
|
||||
DISPLAY "Error: UNSANDBOX_API_KEY not set" UPON SYSERR
|
||||
MOVE 1 TO RETURN-CODE
|
||||
STOP RUN
|
||||
MOVE WS-PUBLIC-KEY TO WS-API-KEY
|
||||
END-IF.
|
||||
|
||||
* Initialize session parameters
|
||||
|
|
@ -209,27 +302,8 @@
|
|||
END-IF.
|
||||
|
||||
HANDLE-SERVICE.
|
||||
* Get API keys (try new format first, fall back to old)
|
||||
ACCEPT WS-PUBLIC-KEY FROM ENVIRONMENT "UNSANDBOX_PUBLIC_KEY".
|
||||
IF WS-PUBLIC-KEY NOT = SPACES
|
||||
ACCEPT WS-SECRET-KEY FROM ENVIRONMENT "UNSANDBOX_SECRET_KEY"
|
||||
IF WS-SECRET-KEY = SPACES
|
||||
DISPLAY "Error: UNSANDBOX_SECRET_KEY not set"
|
||||
UPON SYSERR
|
||||
MOVE 1 TO RETURN-CODE
|
||||
STOP RUN
|
||||
END-IF
|
||||
ELSE
|
||||
ACCEPT WS-API-KEY FROM ENVIRONMENT "UNSANDBOX_API_KEY"
|
||||
IF WS-API-KEY = SPACES
|
||||
DISPLAY "Error: UNSANDBOX_PUBLIC_KEY/SECRET_KEY or "
|
||||
"UNSANDBOX_API_KEY not set" UPON SYSERR
|
||||
MOVE 1 TO RETURN-CODE
|
||||
STOP RUN
|
||||
END-IF
|
||||
MOVE WS-API-KEY TO WS-PUBLIC-KEY
|
||||
MOVE WS-API-KEY TO WS-SECRET-KEY
|
||||
END-IF.
|
||||
* Get credentials
|
||||
PERFORM GET-CREDENTIALS.
|
||||
|
||||
* Initialize service parameters
|
||||
MOVE SPACES TO WS-NAME.
|
||||
|
|
@ -332,26 +406,7 @@
|
|||
END-IF.
|
||||
|
||||
MAKE-EXECUTE-REQUEST.
|
||||
* Get public/secret keys with fallback
|
||||
ACCEPT WS-PUBLIC-KEY FROM ENVIRONMENT "UNSANDBOX_PUBLIC_KEY".
|
||||
IF WS-PUBLIC-KEY NOT = SPACES
|
||||
ACCEPT WS-SECRET-KEY FROM ENVIRONMENT "UNSANDBOX_SECRET_KEY"
|
||||
IF WS-SECRET-KEY = SPACES
|
||||
DISPLAY "Error: UNSANDBOX_SECRET_KEY not set"
|
||||
UPON SYSERR
|
||||
MOVE 1 TO RETURN-CODE
|
||||
STOP RUN
|
||||
END-IF
|
||||
ELSE
|
||||
ACCEPT WS-PUBLIC-KEY FROM ENVIRONMENT "UNSANDBOX_API_KEY"
|
||||
IF WS-PUBLIC-KEY = SPACES
|
||||
DISPLAY "Error: UNSANDBOX_PUBLIC_KEY/SECRET_KEY or "
|
||||
"UNSANDBOX_API_KEY not set" UPON SYSERR
|
||||
MOVE 1 TO RETURN-CODE
|
||||
STOP RUN
|
||||
END-IF
|
||||
MOVE WS-PUBLIC-KEY TO WS-SECRET-KEY
|
||||
END-IF.
|
||||
* Credentials already resolved by caller (GET-CREDENTIALS)
|
||||
|
||||
* Build curl command using shell with HMAC signature
|
||||
STRING "TS=$(date +%s); "
|
||||
|
|
@ -943,12 +998,10 @@
|
|||
CALL "SYSTEM" USING WS-CURL-CMD.
|
||||
|
||||
HANDLE-KEY.
|
||||
* Get API key
|
||||
ACCEPT WS-API-KEY FROM ENVIRONMENT "UNSANDBOX_API_KEY".
|
||||
* Get credentials
|
||||
PERFORM GET-CREDENTIALS.
|
||||
IF WS-API-KEY = SPACES
|
||||
DISPLAY "Error: UNSANDBOX_API_KEY not set" UPON SYSERR
|
||||
MOVE 1 TO RETURN-CODE
|
||||
STOP RUN
|
||||
MOVE WS-PUBLIC-KEY TO WS-API-KEY
|
||||
END-IF.
|
||||
|
||||
* Parse key arguments
|
||||
|
|
@ -1124,27 +1177,8 @@
|
|||
CALL "SYSTEM" USING WS-CURL-CMD.
|
||||
|
||||
HANDLE-LANGUAGES.
|
||||
* Get API keys
|
||||
ACCEPT WS-PUBLIC-KEY FROM ENVIRONMENT "UNSANDBOX_PUBLIC_KEY".
|
||||
IF WS-PUBLIC-KEY NOT = SPACES
|
||||
ACCEPT WS-SECRET-KEY FROM ENVIRONMENT "UNSANDBOX_SECRET_KEY"
|
||||
IF WS-SECRET-KEY = SPACES
|
||||
DISPLAY "Error: UNSANDBOX_SECRET_KEY not set"
|
||||
UPON SYSERR
|
||||
MOVE 1 TO RETURN-CODE
|
||||
STOP RUN
|
||||
END-IF
|
||||
ELSE
|
||||
ACCEPT WS-API-KEY FROM ENVIRONMENT "UNSANDBOX_API_KEY"
|
||||
IF WS-API-KEY = SPACES
|
||||
DISPLAY "Error: UNSANDBOX_PUBLIC_KEY/SECRET_KEY or "
|
||||
"UNSANDBOX_API_KEY not set" UPON SYSERR
|
||||
MOVE 1 TO RETURN-CODE
|
||||
STOP RUN
|
||||
END-IF
|
||||
MOVE WS-API-KEY TO WS-PUBLIC-KEY
|
||||
MOVE WS-API-KEY TO WS-SECRET-KEY
|
||||
END-IF.
|
||||
* Get credentials
|
||||
PERFORM GET-CREDENTIALS.
|
||||
|
||||
* Parse --json flag
|
||||
MOVE SPACES TO WS-JSON-OUTPUT.
|
||||
|
|
@ -1219,27 +1253,8 @@
|
|||
CALL "SYSTEM" USING WS-CURL-CMD.
|
||||
|
||||
HANDLE-IMAGE.
|
||||
* Get API keys (try new format first, fall back to old)
|
||||
ACCEPT WS-PUBLIC-KEY FROM ENVIRONMENT "UNSANDBOX_PUBLIC_KEY".
|
||||
IF WS-PUBLIC-KEY NOT = SPACES
|
||||
ACCEPT WS-SECRET-KEY FROM ENVIRONMENT "UNSANDBOX_SECRET_KEY"
|
||||
IF WS-SECRET-KEY = SPACES
|
||||
DISPLAY "Error: UNSANDBOX_SECRET_KEY not set"
|
||||
UPON SYSERR
|
||||
MOVE 1 TO RETURN-CODE
|
||||
STOP RUN
|
||||
END-IF
|
||||
ELSE
|
||||
ACCEPT WS-API-KEY FROM ENVIRONMENT "UNSANDBOX_API_KEY"
|
||||
IF WS-API-KEY = SPACES
|
||||
DISPLAY "Error: UNSANDBOX_PUBLIC_KEY/SECRET_KEY or "
|
||||
"UNSANDBOX_API_KEY not set" UPON SYSERR
|
||||
MOVE 1 TO RETURN-CODE
|
||||
STOP RUN
|
||||
END-IF
|
||||
MOVE WS-API-KEY TO WS-PUBLIC-KEY
|
||||
MOVE WS-API-KEY TO WS-SECRET-KEY
|
||||
END-IF.
|
||||
* Get credentials
|
||||
PERFORM GET-CREDENTIALS.
|
||||
|
||||
* Initialize image parameters
|
||||
MOVE SPACES TO WS-ID.
|
||||
|
|
@ -1676,15 +1691,7 @@
|
|||
|
||||
HANDLE-SNAPSHOT.
|
||||
* Get credentials
|
||||
ACCEPT WS-PUBLIC-KEY FROM ENVIRONMENT
|
||||
"UNSANDBOX_PUBLIC_KEY".
|
||||
ACCEPT WS-SECRET-KEY FROM ENVIRONMENT
|
||||
"UNSANDBOX_SECRET_KEY".
|
||||
IF WS-PUBLIC-KEY = SPACES OR WS-SECRET-KEY = SPACES
|
||||
DISPLAY "Error: API keys not set" UPON SYSERR
|
||||
MOVE 1 TO RETURN-CODE
|
||||
STOP RUN
|
||||
END-IF.
|
||||
PERFORM GET-CREDENTIALS.
|
||||
|
||||
* Get second argument (operation or --list)
|
||||
ACCEPT WS-ARG2 FROM ARGUMENT-VALUE.
|
||||
|
|
|
|||
|
|
@ -97,8 +97,84 @@
|
|||
find-ext ext-lang
|
||||
;
|
||||
|
||||
\ Account index for --account N flag (-1 = not set)
|
||||
variable account-index
|
||||
-1 account-index !
|
||||
|
||||
\ Argument shift: 0 normally, 2 when --account N is prepended
|
||||
variable arg-shift
|
||||
0 arg-shift !
|
||||
|
||||
\ Shifted arg accessor - applies arg-shift to all handler arg accesses
|
||||
: sarg ( n -- addr len )
|
||||
arg-shift @ + arg
|
||||
;
|
||||
|
||||
\ Buffer for credentials loaded from CSV
|
||||
256 constant MAX-KEY-LEN
|
||||
create csv-pk-buf MAX-KEY-LEN allot
|
||||
variable csv-pk-len
|
||||
create csv-sk-buf MAX-KEY-LEN allot
|
||||
variable csv-sk-len
|
||||
|
||||
\ Load credentials from accounts.csv at given index (n)
|
||||
\ Writes PK/SK to /tmp/unsb_creds.txt; returns true if PK found
|
||||
: load-accounts-csv-index ( n -- flag )
|
||||
dup 0< if drop 0 exit then
|
||||
\ Write a shell script with the index embedded
|
||||
s" /tmp/unsb_cred_resolve.sh" w/o create-file throw >r
|
||||
s" #!/bin/bash" r@ write-line throw
|
||||
s" IDX=" r@ write-file throw
|
||||
dup 0 <# #s #> r@ write-file throw
|
||||
s" " r@ write-line throw
|
||||
s" CNT=-1; PK=''; SK=''" r@ write-line throw
|
||||
s" for CSV in \"$HOME/.unsandbox/accounts.csv\" \"./accounts.csv\"; do" r@ write-line throw
|
||||
s" [ -f \"$CSV\" ] || continue" r@ write-line throw
|
||||
s" while IFS= read -r line || [ -n \"$line\" ]; do" r@ write-line throw
|
||||
s" case \"$line\" in '#'*|'') continue ;; esac" r@ write-line throw
|
||||
s" CNT=$((CNT+1))" r@ write-line throw
|
||||
s" if [ \"$CNT\" -eq \"$IDX\" ]; then" r@ write-line throw
|
||||
s" PK=$(echo \"$line\" | cut -d',' -f1 | tr -d ' ')" r@ write-line throw
|
||||
s" SK=$(echo \"$line\" | cut -d',' -f2 | tr -d ' ')" r@ write-line throw
|
||||
s" break 2" r@ write-line throw
|
||||
s" fi" r@ write-line throw
|
||||
s" done < \"$CSV\"" r@ write-line throw
|
||||
s" done" r@ write-line throw
|
||||
s" printf '%s\\n%s\\n' \"$PK\" \"$SK\" > /tmp/unsb_creds.txt" r@ write-line throw
|
||||
s" [ -n \"$PK\" ]" r@ write-line throw
|
||||
r> close-file throw
|
||||
drop \ drop index
|
||||
s" bash /tmp/unsb_cred_resolve.sh" system
|
||||
0= if
|
||||
\ Script exited 0: PK was found; read results
|
||||
s" /tmp/unsb_creds.txt" r/o open-file
|
||||
0= if
|
||||
>r
|
||||
csv-pk-buf MAX-KEY-LEN r@ read-line throw
|
||||
drop csv-pk-len !
|
||||
csv-sk-buf MAX-KEY-LEN r@ read-line throw
|
||||
drop csv-sk-len !
|
||||
r> close-file throw
|
||||
-1
|
||||
else
|
||||
drop 0
|
||||
then
|
||||
else
|
||||
0
|
||||
then
|
||||
;
|
||||
|
||||
\ Get API keys from environment (HMAC or legacy)
|
||||
: get-public-key ( -- addr len )
|
||||
account-index @ dup 0>= if
|
||||
load-accounts-csv-index if
|
||||
csv-pk-buf csv-pk-len @ exit
|
||||
then
|
||||
s" Error: Account index not found in accounts.csv" type cr
|
||||
1 (bye)
|
||||
else
|
||||
drop
|
||||
then
|
||||
s" UNSANDBOX_PUBLIC_KEY" getenv
|
||||
dup 0= if
|
||||
2drop s" UNSANDBOX_API_KEY" getenv
|
||||
|
|
@ -110,6 +186,20 @@
|
|||
;
|
||||
|
||||
: get-secret-key ( -- addr len )
|
||||
account-index @ dup 0>= if
|
||||
\ CSV already loaded if pk-buf is non-empty
|
||||
csv-pk-len @ 0> if
|
||||
drop csv-sk-buf csv-sk-len @ exit
|
||||
then
|
||||
\ Load it now
|
||||
load-accounts-csv-index if
|
||||
csv-sk-buf csv-sk-len @ exit
|
||||
then
|
||||
\ Index not found - error was printed by get-public-key; return empty
|
||||
s" " exit
|
||||
else
|
||||
drop
|
||||
then
|
||||
s" UNSANDBOX_SECRET_KEY" getenv
|
||||
dup 0= if
|
||||
2drop s" UNSANDBOX_API_KEY" getenv
|
||||
|
|
@ -716,7 +806,7 @@
|
|||
0 (bye)
|
||||
then
|
||||
|
||||
2 arg 2dup s" --extend" compare 0= if
|
||||
2 sarg 2dup s" --extend" compare 0= if
|
||||
2drop
|
||||
1 validate-key
|
||||
0 (bye)
|
||||
|
|
@ -779,7 +869,7 @@
|
|||
1 (bye)
|
||||
then
|
||||
|
||||
2 arg 2dup s" --list" compare 0= if
|
||||
2 sarg 2dup s" --list" compare 0= if
|
||||
2drop session-list
|
||||
0 (bye)
|
||||
then
|
||||
|
|
@ -795,7 +885,7 @@
|
|||
s" Error: --kill requires session ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg session-kill
|
||||
3 sarg session-kill
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -835,7 +925,7 @@
|
|||
1 (bye)
|
||||
then
|
||||
|
||||
2 arg 2dup s" --list" compare 0= if
|
||||
2 sarg 2dup s" --list" compare 0= if
|
||||
2drop service-list
|
||||
0 (bye)
|
||||
then
|
||||
|
|
@ -856,7 +946,7 @@
|
|||
s" Error: --info requires service ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg service-info
|
||||
3 sarg service-info
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -866,7 +956,7 @@
|
|||
s" Error: --logs requires service ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg service-logs
|
||||
3 sarg service-logs
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -876,7 +966,7 @@
|
|||
s" Error: --freeze requires service ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg service-sleep
|
||||
3 sarg service-sleep
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -886,7 +976,7 @@
|
|||
s" Error: --unfreeze requires service ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg service-wake
|
||||
3 sarg service-wake
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -896,7 +986,7 @@
|
|||
s" Error: --destroy requires service ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg service-destroy
|
||||
3 sarg service-destroy
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -911,13 +1001,13 @@
|
|||
s" Error: --resize requires --vcpu N" type cr
|
||||
1 (bye)
|
||||
then
|
||||
4 arg 2dup s" --vcpu" compare 0= if
|
||||
4 sarg 2dup s" --vcpu" compare 0= if
|
||||
2drop
|
||||
argc @ 6 < if
|
||||
s" Error: --vcpu requires a value" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg 5 arg service-resize
|
||||
3 sarg 5 sarg service-resize
|
||||
0 (bye)
|
||||
then
|
||||
2dup s" -v" compare 0= if
|
||||
|
|
@ -926,7 +1016,7 @@
|
|||
s" Error: -v requires a value" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg 5 arg service-resize
|
||||
3 sarg 5 sarg service-resize
|
||||
0 (bye)
|
||||
then
|
||||
2drop
|
||||
|
|
@ -940,16 +1030,16 @@
|
|||
s" Error: --dump-bootstrap requires service ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg
|
||||
3 sarg
|
||||
\ Check for --dump-file
|
||||
argc @ 5 >= if
|
||||
4 arg 2dup s" --dump-file" compare 0= if
|
||||
4 sarg 2dup s" --dump-file" compare 0= if
|
||||
2drop
|
||||
argc @ 6 < if
|
||||
s" Error: --dump-file requires filename" type cr
|
||||
1 (bye)
|
||||
then
|
||||
5 arg
|
||||
5 sarg
|
||||
else
|
||||
2drop 0 0
|
||||
then
|
||||
|
|
@ -967,13 +1057,13 @@
|
|||
s" Usage: un.forth service env <status|set|export|delete> <service_id> [options]" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg 2dup s" status" compare 0= if
|
||||
3 sarg 2dup s" status" compare 0= if
|
||||
2drop
|
||||
argc @ 5 < if
|
||||
s" Error: status requires service ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
4 arg service-env-status
|
||||
4 sarg service-env-status
|
||||
0 (bye)
|
||||
then
|
||||
2dup s" set" compare 0= if
|
||||
|
|
@ -991,7 +1081,7 @@
|
|||
s" Error: export requires service ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
4 arg service-env-export
|
||||
4 sarg service-env-export
|
||||
0 (bye)
|
||||
then
|
||||
2dup s" delete" compare 0= if
|
||||
|
|
@ -1000,7 +1090,7 @@
|
|||
s" Error: delete requires service ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
4 arg service-env-delete
|
||||
4 sarg service-env-delete
|
||||
0 (bye)
|
||||
then
|
||||
2drop
|
||||
|
|
@ -1072,7 +1162,7 @@
|
|||
0 (bye)
|
||||
then
|
||||
|
||||
2 arg 2dup s" --json" compare 0= if
|
||||
2 sarg 2dup s" --json" compare 0= if
|
||||
2drop
|
||||
1 languages-list
|
||||
0 (bye)
|
||||
|
|
@ -1670,7 +1760,7 @@
|
|||
0 (bye)
|
||||
then
|
||||
|
||||
2 arg 2dup s" --list" compare 0= if
|
||||
2 sarg 2dup s" --list" compare 0= if
|
||||
2drop snapshot-list
|
||||
0 (bye)
|
||||
then
|
||||
|
|
@ -1686,7 +1776,7 @@
|
|||
s" Error: --info requires snapshot ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg snapshot-info
|
||||
3 sarg snapshot-info
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -1696,7 +1786,7 @@
|
|||
s" Error: --restore requires snapshot ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg snapshot-restore
|
||||
3 sarg snapshot-restore
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -1706,7 +1796,7 @@
|
|||
s" Error: --delete requires snapshot ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg snapshot-delete
|
||||
3 sarg snapshot-delete
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -1716,7 +1806,7 @@
|
|||
s" Error: --lock requires snapshot ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg snapshot-lock
|
||||
3 sarg snapshot-lock
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -1726,7 +1816,7 @@
|
|||
s" Error: --unlock requires snapshot ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg snapshot-unlock
|
||||
3 sarg snapshot-unlock
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -1736,7 +1826,7 @@
|
|||
s" Error: --clone requires snapshot ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg snapshot-clone
|
||||
3 sarg snapshot-clone
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -1752,7 +1842,7 @@
|
|||
1 (bye)
|
||||
then
|
||||
|
||||
2 arg 2dup s" --list" compare 0= if
|
||||
2 sarg 2dup s" --list" compare 0= if
|
||||
2drop image-list
|
||||
0 (bye)
|
||||
then
|
||||
|
|
@ -1768,7 +1858,7 @@
|
|||
s" Error: --info requires image ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg image-info
|
||||
3 sarg image-info
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -1778,7 +1868,7 @@
|
|||
s" Error: --delete requires image ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg image-delete
|
||||
3 sarg image-delete
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -1788,7 +1878,7 @@
|
|||
s" Error: --lock requires image ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg image-lock
|
||||
3 sarg image-lock
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -1798,7 +1888,7 @@
|
|||
s" Error: --unlock requires image ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg image-unlock
|
||||
3 sarg image-unlock
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -1818,7 +1908,7 @@
|
|||
s" Error: --visibility requires image ID and mode" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg 4 arg image-visibility
|
||||
3 sarg 4 sarg image-visibility
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -1828,7 +1918,7 @@
|
|||
s" Error: --spawn requires image ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg image-spawn
|
||||
3 sarg image-spawn
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -1838,7 +1928,7 @@
|
|||
s" Error: --clone requires image ID" type cr
|
||||
1 (bye)
|
||||
then
|
||||
3 arg image-clone
|
||||
3 sarg image-clone
|
||||
0 (bye)
|
||||
then
|
||||
|
||||
|
|
@ -1860,8 +1950,21 @@
|
|||
1 (bye)
|
||||
then
|
||||
|
||||
\ Get first argument (skip gforth and script name)
|
||||
1 arg
|
||||
\ Check for --account N as first argument (before arg-shift is applied)
|
||||
1 arg 2dup s" --account" compare 0= if
|
||||
2drop
|
||||
argc @ 3 < if
|
||||
s" Error: --account requires a numeric argument" type cr
|
||||
1 (bye)
|
||||
then
|
||||
2 arg s>number drop account-index !
|
||||
2 arg-shift !
|
||||
else
|
||||
2drop
|
||||
then
|
||||
|
||||
\ Get subcommand (adjusted for arg-shift)
|
||||
1 arg-shift @ + arg
|
||||
|
||||
\ Check for subcommands
|
||||
2dup s" session" compare 0= if
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@
|
|||
|
||||
:- initialization(main, main).
|
||||
|
||||
% Initialize global account index to -1 (not set)
|
||||
:- nb_setval(account_index, -1).
|
||||
|
||||
% Constants
|
||||
portal_base('https://unsandbox.com').
|
||||
languages_cache_ttl(3600). % 1 hour cache TTL
|
||||
|
|
@ -85,26 +88,91 @@ read_file_content(Filename, Content) :-
|
|||
read_string(Stream, _, Content),
|
||||
close(Stream).
|
||||
|
||||
% Get API keys from environment (HMAC or legacy)
|
||||
% Load credentials from accounts.csv at 0-indexed row
|
||||
% Tries ~/.unsandbox/accounts.csv first, then ./accounts.csv
|
||||
load_accounts_csv(Index, PK, SK) :-
|
||||
getenv('HOME', Home),
|
||||
atomic_list_concat([Home, '/.unsandbox/accounts.csv'], Path1),
|
||||
( exists_file(Path1)
|
||||
-> load_accounts_csv_file(Path1, Index, PK, SK)
|
||||
; exists_file('accounts.csv')
|
||||
-> load_accounts_csv_file('accounts.csv', Index, PK, SK)
|
||||
; fail
|
||||
).
|
||||
|
||||
load_accounts_csv_file(Path, Index, PK, SK) :-
|
||||
setup_call_cleanup(
|
||||
open(Path, read, Stream),
|
||||
load_accounts_csv_stream(Stream, 0, Index, PK, SK),
|
||||
close(Stream)
|
||||
).
|
||||
|
||||
load_accounts_csv_stream(Stream, Count, Index, PK, SK) :-
|
||||
read_line_to_string(Stream, Line),
|
||||
Line \= end_of_file,
|
||||
!,
|
||||
% Skip blank lines and comments
|
||||
( (Line = "" ; string_code(1, Line, 35)) % 35 = '#'
|
||||
-> load_accounts_csv_stream(Stream, Count, Index, PK, SK)
|
||||
; Count =:= Index
|
||||
-> split_string(Line, ",", " \t", [PKStr, SKStr|_]),
|
||||
atom_string(PK, PKStr),
|
||||
atom_string(SK, SKStr)
|
||||
; Next is Count + 1,
|
||||
load_accounts_csv_stream(Stream, Next, Index, PK, SK)
|
||||
).
|
||||
|
||||
% Get API keys from environment (HMAC or legacy), respecting --account N
|
||||
get_public_key(PublicKey) :-
|
||||
( getenv('UNSANDBOX_PUBLIC_KEY', PublicKey),
|
||||
PublicKey \= ''
|
||||
-> true
|
||||
; getenv('UNSANDBOX_API_KEY', PublicKey),
|
||||
PublicKey \= ''
|
||||
-> true
|
||||
; write(user_error, 'Error: UNSANDBOX_PUBLIC_KEY or UNSANDBOX_API_KEY environment variable not set\n'),
|
||||
halt(1)
|
||||
( nb_getval(account_index, Idx), Idx >= 0
|
||||
-> ( load_accounts_csv(Idx, PublicKey, _)
|
||||
-> true
|
||||
; format(user_error, 'Error: Account index ~w not found in accounts.csv~n', [Idx]),
|
||||
halt(1)
|
||||
)
|
||||
; ( getenv('UNSANDBOX_PUBLIC_KEY', PublicKey),
|
||||
PublicKey \= ''
|
||||
-> true
|
||||
; getenv('UNSANDBOX_API_KEY', PublicKey),
|
||||
PublicKey \= ''
|
||||
-> true
|
||||
; % Try accounts.csv with UNSANDBOX_ACCOUNT or row 0
|
||||
( getenv('UNSANDBOX_ACCOUNT', IdxStr),
|
||||
atom_number(IdxStr, DefaultIdx)
|
||||
-> true
|
||||
; DefaultIdx = 0
|
||||
),
|
||||
( load_accounts_csv(DefaultIdx, PublicKey, _)
|
||||
-> true
|
||||
; write(user_error, 'Error: UNSANDBOX_PUBLIC_KEY or UNSANDBOX_API_KEY environment variable not set\n'),
|
||||
halt(1)
|
||||
)
|
||||
)
|
||||
).
|
||||
|
||||
get_secret_key(SecretKey) :-
|
||||
( getenv('UNSANDBOX_SECRET_KEY', SecretKey),
|
||||
SecretKey \= ''
|
||||
-> true
|
||||
; getenv('UNSANDBOX_API_KEY', SecretKey),
|
||||
SecretKey \= ''
|
||||
-> true
|
||||
; SecretKey = ''
|
||||
( nb_getval(account_index, Idx), Idx >= 0
|
||||
-> ( load_accounts_csv(Idx, _, SecretKey)
|
||||
-> true
|
||||
; SecretKey = ''
|
||||
)
|
||||
; ( getenv('UNSANDBOX_SECRET_KEY', SecretKey),
|
||||
SecretKey \= ''
|
||||
-> true
|
||||
; getenv('UNSANDBOX_API_KEY', SecretKey),
|
||||
SecretKey \= ''
|
||||
-> true
|
||||
; % Try accounts.csv with UNSANDBOX_ACCOUNT or row 0
|
||||
( getenv('UNSANDBOX_ACCOUNT', IdxStr),
|
||||
atom_number(IdxStr, DefaultIdx)
|
||||
-> true
|
||||
; DefaultIdx = 0
|
||||
),
|
||||
( load_accounts_csv(DefaultIdx, _, SecretKey)
|
||||
-> true
|
||||
; SecretKey = ''
|
||||
)
|
||||
)
|
||||
).
|
||||
|
||||
% Get API key (legacy compatibility)
|
||||
|
|
@ -742,8 +810,22 @@ service_create_with_vault(Name, Ports, Bootstrap, BootstrapFile, ServiceType, In
|
|||
|
||||
% Main program
|
||||
main(Argv) :-
|
||||
% Initialize account_index global to -1 (not set)
|
||||
nb_setval(account_index, -1),
|
||||
|
||||
% Parse --account N global flag if present
|
||||
( Argv = ['--account', NStr|Rest]
|
||||
-> ( atom_number(NStr, N), integer(N)
|
||||
-> nb_setval(account_index, N),
|
||||
ActualArgv = Rest
|
||||
; write(user_error, 'Error: --account requires an integer argument\n'),
|
||||
halt(1)
|
||||
)
|
||||
; ActualArgv = Argv
|
||||
),
|
||||
|
||||
% Check arguments
|
||||
( Argv = []
|
||||
( ActualArgv = []
|
||||
-> write(user_error, 'Usage: un.pro [options] <source_file>\n'),
|
||||
write(user_error, ' un.pro session [options]\n'),
|
||||
write(user_error, ' un.pro service [options]\n'),
|
||||
|
|
@ -782,19 +864,19 @@ main(Argv) :-
|
|||
),
|
||||
|
||||
% Parse subcommands
|
||||
( Argv = ['session'|Rest]
|
||||
( ActualArgv = ['session'|Rest]
|
||||
-> handle_session(Rest)
|
||||
; Argv = ['service'|Rest]
|
||||
; ActualArgv = ['service'|Rest]
|
||||
-> handle_service(Rest)
|
||||
; Argv = ['snapshot'|Rest]
|
||||
; ActualArgv = ['snapshot'|Rest]
|
||||
-> handle_snapshot(Rest)
|
||||
; Argv = ['image'|Rest]
|
||||
; ActualArgv = ['image'|Rest]
|
||||
-> handle_image(Rest)
|
||||
; Argv = ['languages'|Rest]
|
||||
; ActualArgv = ['languages'|Rest]
|
||||
-> handle_languages(Rest)
|
||||
; Argv = ['key'|Rest]
|
||||
; ActualArgv = ['key'|Rest]
|
||||
-> handle_key(Rest)
|
||||
; Argv = [Filename|_]
|
||||
; ActualArgv = [Filename|_]
|
||||
-> execute_file(Filename)
|
||||
; write(user_error, 'Error: Invalid arguments\n'),
|
||||
halt(1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue