/*
 * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <openssl/opensslconf.h>

#include <openssl/crypto.h>
#include <openssl/e_os2.h>
#include <openssl/rand.h>

/*
 * Query an EGD
 */

#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_UEFI)
int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
{
    return -1;
}

int RAND_egd(const char *path)
{
    return -1;
}

int RAND_egd_bytes(const char *path, int bytes)
{
    return -1;
}

#else

# include <unistd.h>
# include <stddef.h>
# include <sys/types.h>
# include <sys/socket.h>
# ifndef NO_SYS_UN_H
#  ifdef OPENSSL_SYS_VXWORKS
#   include <streams/un.h>
#  else
#   include <sys/un.h>
#  endif
# else
struct sockaddr_un {
    short sun_family;           /* AF_UNIX */
    char sun_path[108];         /* path name (gag) */
};
# endif                         /* NO_SYS_UN_H */
# include <string.h>
# include <errno.h>

# if defined(OPENSSL_SYS_TANDEM)
/*
 * HPNS:
 *
 *  Our current MQ 5.3 EGD requires compatability-mode sockets
 *  This code forces the mode to compatibility if required
 *  and then restores the mode.
 *
 *  Needs review:
 *
 *  The better long-term solution is to either run two EGD's each in one of
 *  the two modes or revise the EGD code to listen on two different sockets
 *  (each in one of the two modes).
 */
_variable
int hpns_socket(int family,
                int type,
                int protocol,
                char* transport)
{
    int  socket_rc;
    char current_transport[20];

#  define AF_UNIX_PORTABILITY    "$ZAFN2"
#  define AF_UNIX_COMPATIBILITY  "$ZPLS"

    if (!_arg_present(transport) || transport == NULL || transport[0] == '\0')
        return socket(family, type, protocol);

    socket_transport_name_get(AF_UNIX, current_transport, 20);

    if (strcmp(current_transport, transport) == 0)
        return socket(family, type, protocol);

    /* set the requested socket transport */
    if (socket_transport_name_set(AF_UNIX, transport))
        return -1;

    socket_rc = socket(family, type, protocol);

    /* set mode back to what it was */
    if (socket_transport_name_set(AF_UNIX, current_transport))
        return -1;

    return socket_rc;
}

/*#define socket(a,b,c,...) hpns_socket(a,b,c,__VA_ARGS__) */

static int hpns_connect_attempt = 0;

# endif /* defined(OPENSSL_SYS_HPNS) */


int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
{
    FILE *fp = NULL;
    struct sockaddr_un addr;
    int mybuffer, ret = -1, i, numbytes, fd;
    unsigned char tempbuf[255];

    if (bytes > (int)sizeof(tempbuf))
        return -1;

    /* Make socket. */
    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    if (strlen(path) >= sizeof(addr.sun_path))
        return -1;
    strcpy(addr.sun_path, path);
    i = offsetof(struct sockaddr_un, sun_path) + strlen(path);
#if defined(OPENSSL_SYS_TANDEM)
    fd = hpns_socket(AF_UNIX, SOCK_STREAM, 0, AF_UNIX_COMPATIBILITY);
#else
    fd = socket(AF_UNIX, SOCK_STREAM, 0);
#endif
    if (fd == -1 || (fp = fdopen(fd, "r+")) == NULL)
        return -1;
    setbuf(fp, NULL);

    /* Try to connect */
    for (;;) {
        if (connect(fd, (struct sockaddr *)&addr, i) == 0)
            break;
# ifdef EISCONN
        if (errno == EISCONN)
            break;
# endif
        switch (errno) {
# ifdef EINTR
        case EINTR:
# endif
# ifdef EAGAIN
        case EAGAIN:
# endif
# ifdef EINPROGRESS
        case EINPROGRESS:
# endif
# ifdef EALREADY
        case EALREADY:
# endif
            /* No error, try again */
            break;
        default:
# if defined(OPENSSL_SYS_TANDEM)
            if (hpns_connect_attempt == 0) {
                /* try the other kind of AF_UNIX socket */
                close(fd);
                fd = hpns_socket(AF_UNIX, SOCK_STREAM, 0, AF_UNIX_PORTABILITY);
                if (fd == -1)
                    return -1;
                ++hpns_connect_attempt;
                break;  /* try the connect again */
            }
# endif

            ret = -1;
            goto err;
        }
    }

    /* Make request, see how many bytes we can get back. */
    tempbuf[0] = 1;
    tempbuf[1] = bytes;
    if (fwrite(tempbuf, sizeof(char), 2, fp) != 2 || fflush(fp) == EOF)
        goto err;
    if (fread(tempbuf, sizeof(char), 1, fp) != 1 || tempbuf[0] == 0)
        goto err;
    numbytes = tempbuf[0];

    /* Which buffer are we using? */
    mybuffer = buf == NULL;
    if (mybuffer)
        buf = tempbuf;

    /* Read bytes. */
    i = fread(buf, sizeof(char), numbytes, fp);
    if (i < numbytes)
        goto err;
    ret = numbytes;
    if (mybuffer)
        RAND_add(tempbuf, i, i);

 err:
    if (fp != NULL)
        fclose(fp);
    return ret;
}

int RAND_egd_bytes(const char *path, int bytes)
{
    int num;

    num = RAND_query_egd_bytes(path, NULL, bytes);
    if (num < 0)
        return -1;
    if (RAND_status() != 1)
        return -1;
    return num;
}

int RAND_egd(const char *path)
{
    return RAND_egd_bytes(path, 255);
}

#endif
