Compare what user entered to the specific value. If they mismatch  - ask again. Also there are several utility methods in %Prompt class for number/yes-no/etc input:

  • GetNumber
  • GetString
  • GetYesNo
  • GetArray - Prompt for a number or entry in a displayed menu. Returns the selected item.
  • GetMenu - Prompt for a number in a displayed menu.
  • GetMore - Prompt for More or Quit.

For example:

do ##class(%Prompt).GetYesNo("Enter Yes or No:", .result)

User can input only Yes (Y) or No (N). result variable would hold 1 or 0.

You can also check %Prompt code and write something based on that.

Turns out Java Gateway can instantiate objects and call their methods.  Here's a rewrite of the above code, but all connecting is done in constructor:

package com.isc.rabbitmq;

import com.rabbitmq.client.*;

public class Wrapper {
    private final Channel _channel;

    private final String _queueName;

    public Wrapper(String hostName, String queueName)  throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost(hostName);
        Connection connection = factory.newConnection();
        _channel = connection.createChannel();
        _channel.queueDeclare(queueName, false, false, false, null);
        _queueName = queueName;
    }

    public void sendMsg(byte[] msg) throws Exception {
        _channel.basicPublish("", _queueName, null, msg);
    }

    public int readMsg(byte[] msg) throws Exception {
        boolean autoAck = true;
        GetResponse response = _channel.basicGet(_queueName, autoAck);
        int len = 0;
        if (response == null) {
            // No message retrieved.
        } else {
            AMQP.BasicProperties props = response.getProps();
            len = response.getBody().length;
            System.arraycopy(response.getBody(),0,msg,0,len);
        }
        return len;
    }

}

You can use deprecated %Net.RemoteConnection:

Set rc=##class(%Net.RemoteConnection).%New()
Set Status=rc.Connect("127.0.0.1","SAMPLES",1972,"_SYSTEM","SYS")
Write Status

If you don't know login/pass just use _SYSTEM/SYS defaults - you'll get either Access Denied error upon successful connection or TCP error.

Alternatively try to open TCP device to the target:

ClassMethod Test(host = "localhost", port = 1972, timeout = 10) As %Boolean {
      set oldIO = $IO
      set io = "|TCP|1" _ port
      open io:(/Hostname=host:/Port=port):timeout
      set success = $Test
      use oldIO
      close io
      quit success
}

Your options are:

  • Try to compile crypt only under win x64 (libc as a whole can't be compiled under windows, but maybe you can compile crypt module)
  • PHP doc you referenced states that PHP has it's own fallback implementation when OS does not provide crypt implementation. Check where does PHP search for crypt implementation on windows - it's probably some C lib and call it too
  • Write the algorithm yourself, here's  a good guide on that
  • Use another more secure hashing algorithm, for example SHA-512

There is also CNA project - it provides an interface for using native C-compatible shared libraries without anything but Caché ObjectScript code. CNA is a wrapper for libffi. CNA consists of native library (libcna) and Caché class (CNA.CNA). It is a wrapper around $zf functions (you can use them directly too).

Here's the code to call crypt using CNA:

Class CNA.Crypt
{

/// do ##class(CNA.Crypt).Crypt()
ClassMethod Crypt(key = "2Ggaobjb", salt = "$1$1a2b3c4d$")
{
    set cna = ##class(CNA.CNA).%New("/InterSystems/forCLM/libcna.so") ; Creates object of CNA.CNA class.
    do cna.LoadLibrary("/lib/x86_64-linux-gnu/libcrypt-2.23.so")      ; Loads C standard library (crypto) in CNA

    set keyPointer = cna.ConvertStringToPointer(key) ; Converts the string into char array, and saves pointer to the first element

    set saltPointer = cna.ConvertStringToPointer(salt)

    set argTypes = $lb(cna.#POINTER, cna.#POINTER)   ; function argument types
    set result = cna.CallFunction("crypt",          ; Passes the name of the function,
                                cna.#POINTER,       ; type of return value,
                                argTypes,         ; list of argument types,
                                keyPointer, saltPointer)           ; and comma-separated arguments */    
    write cna.ConvertPointerToString(result), !      
   
    do cna.FreeLibrary()
}

}

Sample output:

do ##class(CNA.Crypt).Crypt()
>$1$1a2b3c4d$Y5tt50CQ12xW2saeYnI43.

do ##class(CNA.Crypt).Crypt("ABC", "$1$12345678$") 
>$1$12345678$0QgUhxfT5h1pvtkhF5pzx/