/*
 * BRLTTY - A background process providing access to the console screen (when in
 *          text mode) for a blind person using a refreshable braille display.
 *
 * Copyright (C) 1995-2023 by The BRLTTY Developers.
 *
 * BRLTTY comes with ABSOLUTELY NO WARRANTY.
 *
 * This is free software, placed under the terms of the
 * GNU Lesser General Public License, as published by the Free Software
 * Foundation; either version 2.1 of the License, or (at your option) any
 * later version. Please see the file LICENSE-LGPL for details.
 *
 * Web Page: http://brltty.app/
 *
 * This software is maintained by Dave Mielke <dave@mielke.cc>.
 */

#include "prologue.h"

#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>

#ifdef __MINGW32__
#include <ws2tcpip.h>
#include "system_windows.h"
#else /* __MINGW32__ */
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif /* __MINGW32__ */
#include "get_select.h"

#if !defined(AF_LOCAL) && defined(AF_UNIX)
#define AF_LOCAL AF_UNIX
#endif /* !defined(AF_LOCAL) && defined(AF_UNIX) */
 
#if !defined(PF_LOCAL) && defined(PF_UNIX)
#define PF_LOCAL PF_UNIX
#endif /* !defined(PF_LOCAL) && defined(PF_UNIX) */
 
#ifdef WINDOWS
#undef AF_LOCAL
#endif /* WINDOWS */

#ifdef __MINGW32__
#define close(fd) CloseHandle((HANDLE)(fd))
#define LogSocketError(msg) logWindowsSocketError(msg)
#else /* __MINGW32__ */
#define LogSocketError(msg) logSystemError(msg)
#endif /* __MINGW32__ */

#include "log.h"
#include "io_misc.h"
#include "parse.h"
#include "async_wait.h"
#include "charset.h"
#include "cmd.h"

#define BRL_STATUS_FIELDS sfGeneric
#define BRL_HAVE_STATUS_CELLS
#include "brl_driver.h"
#include "braille.h"

static int fileDescriptor = -1;

#define INPUT_SIZE 0X200
static char inputBuffer[INPUT_SIZE];
static size_t inputLength;
static size_t inputStart;
static int inputEnd;
static int inputCarriageReturn;
static const char *inputDelimiters = " ";

#define OUTPUT_SIZE 0X200
static char outputBuffer[OUTPUT_SIZE];
static size_t outputLength;

typedef struct {
  const CommandEntry *entry;
  unsigned int count;
} CommandDescriptor;
static CommandDescriptor *commandDescriptors = NULL;
static const size_t commandSize = sizeof(*commandDescriptors);
static size_t commandCount;

static int brailleColumns;
static int brailleRows;
static int brailleCount;
static unsigned char *brailleCells = NULL;
static wchar_t *textCharacters = NULL;

static int statusColumns;
static int statusRows;
static int statusCount;
static unsigned char *statusCells = NULL;
static unsigned char genericCells[GSC_COUNT];

typedef struct {
#ifdef AF_LOCAL
  int (*getLocalConnection) (const struct sockaddr_un *address);
#endif /* AF_LOCAL */

#ifdef __MINGW32__
  int (*getNamedPipeConnection) (const char *path);
#endif /* __MINGW32__ */

  int (*getInetConnection) (const struct sockaddr_in *address);
} ModeEntry;
static const ModeEntry *mode;

typedef struct {
  int (*read) (int descriptor, void *buffer, int size);
} OperationsEntry;
static const OperationsEntry *operations;

static int
readNetworkSocket (int descriptor, void *buffer, int size) {
  if (awaitSocketInput(descriptor, 0)) {
    int count = recv(descriptor, buffer, size, 0);
    if (count != -1) return count;
    LogSocketError("recv");
  }

  return -1;
}

static const OperationsEntry socketOperationsEntry = {
  readNetworkSocket
};

static char *
formatSocketAddress (const struct sockaddr *address) {
  char *string;

  switch (address->sa_family) {
#ifdef AF_LOCAL
    case AF_LOCAL: {
      const struct sockaddr_un *localAddress = (const struct sockaddr_un *)address;

      string = strdup(localAddress->sun_path);
      break;
    }
#endif /* AF_LOCAL */

    case AF_INET: {
      const struct sockaddr_in *inetAddress = (const struct sockaddr_in *)address;
      const char *host = inet_ntoa(inetAddress->sin_addr);
      unsigned short port = ntohs(inetAddress->sin_port);
      char buffer[strlen(host) + 7];

      snprintf(buffer, sizeof(buffer), "%s:%u", host, port);
      string = strdup(buffer);
      break;
    }

    default:
      string = strdup("");
      break;
  }

  if (!string) logMallocError();
  return string;
}

static int
acceptSocketConnection (
  int (*getSocket) (void),
  int (*prepareQueue) (int socket),
  void (*unbindAddress) (const struct sockaddr *address),
  const struct sockaddr *localAddress, socklen_t localSize,
  struct sockaddr *remoteAddress, socklen_t *remoteSize
) {
  int serverSocket = -1;
  int queueSocket;

  if ((queueSocket = getSocket()) != -1) {
    if (!prepareQueue || prepareQueue(queueSocket)) {
      if (bind(queueSocket, localAddress, localSize) != -1) {
        if (listen(queueSocket, 1) != -1) {
          int attempts = 0;

          {
            char *address = formatSocketAddress(localAddress);

            if (address) {
              logMessage(LOG_NOTICE, "listening on: %s", address);
              free(address);
            }
          }

          while (1) {
            fd_set readMask;
            struct timeval timeout;

            FD_ZERO(&readMask);
            FD_SET(queueSocket, &readMask);

            memset(&timeout, 0, sizeof(timeout));
            timeout.tv_sec = 10;

            ++attempts;
            switch (select(queueSocket+1, &readMask, NULL, NULL, &timeout)) {
              case -1:
                if (errno == EINTR) continue;
                LogSocketError("select");
                break;

              case 0:
                logMessage(LOG_DEBUG, "no connection yet, still waiting (%d).", attempts);
                continue;

              default: {
                if (!FD_ISSET(queueSocket, &readMask)) continue;

                if ((serverSocket = accept(queueSocket, remoteAddress, remoteSize)) != -1) {
                  char *address = formatSocketAddress(remoteAddress);

                  if (address) {
                    logMessage(LOG_NOTICE, "client is: %s", address);
                    free(address);
                  }
                } else {
                  LogSocketError("accept");
                }
              }
            }
            break;
          }
        } else {
          LogSocketError("listen");
        }

        if (unbindAddress) unbindAddress(localAddress);
      } else {
        LogSocketError("bind");
      }
    }

    close(queueSocket);
  } else {
    LogSocketError("socket");
  }

  operations = &socketOperationsEntry;
  return serverSocket;
}

static int
requestConnection (
  int (*getSocket) (void),
  const struct sockaddr *remoteAddress, socklen_t remoteSize
) {
  int clientSocket;

  {
    char *address = formatSocketAddress(remoteAddress);

    if (address) {
      logMessage(LOG_DEBUG, "connecting to: %s", address);
      free(address);
    }
  }

  if ((clientSocket = getSocket()) != -1) {
    if (connect(clientSocket, remoteAddress, remoteSize) != -1) {
      {
        char *address = formatSocketAddress(remoteAddress);

        if (address) {
          logMessage(LOG_NOTICE, "connected to: %s", address);
          free(address);
        }
      }

      operations = &socketOperationsEntry;
      return clientSocket;
    } else {
      logMessage(LOG_WARNING, "connect error: %s", strerror(errno));
    }

    close(clientSocket);
  } else {
    LogSocketError("socket");
  }

  return -1;
}

static int
setSocketReuseAddress (int socket) {
  int yes = 1;

  if (setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes)) != -1) {
    return 1;
  } else {
    LogSocketError("setsockopt REUSEADDR");
  }
  return 0;
}

#ifdef AF_LOCAL
static int
setLocalAddress (const char *string, struct sockaddr_un *address) {
  int ok = 1;

  memset(address, 0, sizeof(*address));
  address->sun_family = AF_LOCAL;

  if (strlen(string) < sizeof(address->sun_path)) {
    strncpy(address->sun_path, string, sizeof(address->sun_path)-1);
  } else {
    ok = 0;
    logMessage(LOG_WARNING, "Local socket path too long: %s", string);
  }

  return ok;
}

static int
getLocalSocket (void) {
  return socket(PF_LOCAL, SOCK_STREAM, 0);
}

static void
unbindLocalAddress (const struct sockaddr *address) {
  const struct sockaddr_un *localAddress = (const struct sockaddr_un *)address;
  if (unlink(localAddress->sun_path) == -1) {
    logSystemError("unlink");
  }
}

static int
acceptLocalConnection (const struct sockaddr_un *localAddress) {
  struct sockaddr_un remoteAddress;
  socklen_t remoteSize = sizeof(remoteAddress);

  return acceptSocketConnection(getLocalSocket, NULL, unbindLocalAddress,
                                (const struct sockaddr *)localAddress, sizeof(*localAddress),
                                (struct sockaddr *)&remoteAddress, &remoteSize);
}

static int
requestLocalConnection (const struct sockaddr_un *remoteAddress) {
  return requestConnection(getLocalSocket,
                           (const struct sockaddr *)remoteAddress, sizeof(*remoteAddress));
}
#endif /* AF_LOCAL */

#ifdef __MINGW32__
static int
readNamedPipe (int descriptor, void *buffer, int size) {
  {
    DWORD available;

    if (!PeekNamedPipe((HANDLE)descriptor, NULL, 0, NULL, &available, NULL)) {
      logWindowsSystemError("PeekNamedPipe");
      return 0;
    }

    if (!available) {
      errno = EAGAIN;
      return -1;
    }

    if (available < size) size = available;
  }

  {
    DWORD received;
    OVERLAPPED overl = {0, 0, {{0, 0}}, NULL};
    overl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    if (!ReadFile((HANDLE)descriptor, buffer, size, &received, &overl)) {
      if (GetLastError() != ERROR_IO_PENDING) {
        logWindowsSystemError("ReadPipe");
        received = 0;
      } else if (!GetOverlappedResult((HANDLE)descriptor, &overl, &received, TRUE)) {
        logWindowsSystemError("GetOverlappedResult");
        received = 0;
      }
    }

    CloseHandle(overl.hEvent);
    return received;
  }
}

static const OperationsEntry namedPipeOperationsEntry = {
  readNamedPipe
};

static int
acceptNamedPipeConnection (const char *path) {
  HANDLE h;
  OVERLAPPED overl = {0, 0, {{0, 0}}, NULL};
  DWORD res;
  int attempts = 0;

  if ((h = CreateNamedPipe(path, 
                                PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
                                PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
                                1, 0, 0, 0, NULL)) == INVALID_HANDLE_VALUE) {
    logWindowsSystemError("CreateNamedPipe");
    return -1;
  }

  overl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  if (!ConnectNamedPipe(h, &overl)) {
    switch (GetLastError()) {
      case ERROR_IO_PENDING:
        while ((res = WaitForSingleObject(overl.hEvent, 10000)) != WAIT_OBJECT_0) {
          if (res == WAIT_TIMEOUT) {
            ++attempts;
            logMessage(LOG_DEBUG, "no connection yet, still waiting (%d).", attempts);
          } else {
            logWindowsSystemError("ConnectNamedPipe");
            CloseHandle(h);
            h = (HANDLE) -1;
            break;
          }
        }

      case ERROR_PIPE_CONNECTED:
        break;

      default:
        logWindowsSystemError("ConnectNamedPipe");
        CloseHandle(h);
        h = (HANDLE) -1;
        break;
    }
  }

  CloseHandle(overl.hEvent);
  operations = &namedPipeOperationsEntry;
  return (int)h;
}

static int
requestNamedPipeConnection (const char *path) {
  HANDLE h;

  if ((h = CreateFile(path,
                      GENERIC_READ|GENERIC_WRITE,
                      FILE_SHARE_READ|FILE_SHARE_WRITE,
                      NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) {
    logWindowsSystemError("Connect to named pipe");
    return -1;
  }

  operations = &namedPipeOperationsEntry;
  return (int)h;
}
#endif /* __MINGW32__ */

static int
setInetAddress (const char *string, struct sockaddr_in *address) {
  int ok = 1;
  char *hostName = strdup(string);

  if (hostName) {
    char *portNumber = strchr(hostName, ':');

    if (portNumber) {
      *portNumber++ = 0;
      if (!*portNumber) portNumber = NULL;
    }

    memset(address, 0, sizeof(*address));
    address->sin_family = AF_INET;

    if (*hostName) {
      const struct hostent *host = gethostbyname(hostName);
      if (host && (host->h_addrtype == AF_INET) && (host->h_length == sizeof(address->sin_addr))) {
        memcpy(&address->sin_addr, host->h_addr, sizeof(address->sin_addr));
      } else {
        ok = 0;
        logMessage(LOG_WARNING, "Unknown host name: %s", hostName);
      }
    } else {
      address->sin_addr.s_addr = INADDR_ANY;
    }

    if (portNumber) {
      int port;

      if (isInteger(&port, portNumber)) {
        if ((port > 0) && (port <= 0XFFFF)) {
          address->sin_port = htons(port);
        } else {
          ok = 0;
          logMessage(LOG_WARNING, "Invalid port number: %s", portNumber);
        }
      } else {
        const struct servent *service = getservbyname(portNumber, "tcp");

        if (service) {
          address->sin_port = service->s_port;
        } else {
          ok = 0;
          logMessage(LOG_WARNING, "Unknown service: %s", portNumber);
        }
      }
    } else {
      address->sin_port = htons(VR_DEFAULT_PORT);
    }

    free(hostName);
  } else {
    ok = 0;
    logMallocError();
  }

  return ok;
}

static int
getInetSocket (void) {
  return socket(PF_INET, SOCK_STREAM, 0);
}

static int
prepareInetQueue (int socket) {
  if (setSocketReuseAddress(socket)) return 1;
  return 0;
}

static int
acceptInetConnection (const struct sockaddr_in *localAddress) {
  struct sockaddr_in remoteAddress;
  socklen_t remoteSize = sizeof(remoteAddress);

  return acceptSocketConnection(getInetSocket, prepareInetQueue, NULL,
                                (const struct sockaddr *)localAddress, sizeof(*localAddress),
                                (struct sockaddr *)&remoteAddress, &remoteSize);
}

static int
requestInetConnection (const struct sockaddr_in *remoteAddress) {
  return requestConnection(getInetSocket,
                           (const struct sockaddr *)remoteAddress, sizeof(*remoteAddress));
}

static char *
makeString (const char *characters, int count) {
  char *string = malloc(count+1);

  if (string) {
    memcpy(string, characters, count);
    string[count] = 0;
  } else {
    logMallocError();
  }

  return string;
}

static char *
copyString (const char *string) {
  return makeString(string, strlen(string));
}

static int
fillInputBuffer (void) {
  if ((inputLength < INPUT_SIZE) && !inputEnd) {
    int count = operations->read(fileDescriptor, &inputBuffer[inputLength], INPUT_SIZE-inputLength);
    if (!count) {
      inputEnd = 1;
    } else if (count != -1) {
      inputLength += count;
    } else if (errno != EAGAIN) {
      return 0;
    }
  }
  return 1;
}

static char *
readCommandLine (void) {
  if (fillInputBuffer()) {
    if (inputStart < inputLength) {
      const char *newline = memchr(&inputBuffer[inputStart], '\n', inputLength-inputStart);

      if (newline) {
        char *string;
        int stringLength = newline - inputBuffer;
        inputCarriageReturn = 0;

        if ((newline != inputBuffer) && (*(newline-1) == '\r')) {
          inputCarriageReturn = 1;
          stringLength -= 1;
        }

        string = makeString(inputBuffer, stringLength);
        inputLength -= ++newline - inputBuffer;
        memmove(inputBuffer, newline, inputLength);
        inputStart = 0;
        return string;
      } else {
        inputStart = inputLength;
      }
    } else if (inputEnd) {
      char *string;

      if (inputLength) {
        string = makeString(inputBuffer, inputLength);
        inputLength = 0;
        inputStart = 0;
      } else {
        string = copyString("quit");
      }

      return string;
    }
  }

  return NULL;
}

static const char *
nextWord (void) {
  return strtok(NULL, inputDelimiters);
}

static int
compareWords (const char *word1, const char *word2) {
  return strcasecmp(word1, word2);
}

static int
testWord (const char *suppliedWord, const char *desiredWord) {
  return compareWords(suppliedWord, desiredWord) == 0;
}

static int
flushOutput (void) {
  const char *buffer = outputBuffer;
  size_t length = outputLength;

  while (length) {
#ifdef __MINGW32__
    DWORD sent;
    OVERLAPPED overl = {0, 0, {{0, 0}}, CreateEvent(NULL, TRUE, FALSE, NULL)};
    if ((!WriteFile((HANDLE) fileDescriptor, buffer, length, &sent, &overl)
      && GetLastError() != ERROR_IO_PENDING) ||
      !GetOverlappedResult((HANDLE) fileDescriptor, &overl, &sent, TRUE)) {
        LogSocketError("WriteFile");
        CloseHandle(overl.hEvent);
        memmove(outputBuffer, buffer, (outputLength = length));
        return 0;
      }
    CloseHandle(overl.hEvent);
#else /* __MINGW32__ */
    int sent;
    sent = send(fileDescriptor, buffer, length, 0);

    if (sent == -1) {
      if (errno == EINTR) continue;
      LogSocketError("send");
      memmove(outputBuffer, buffer, (outputLength = length));
      return 0;
    }
#endif /* __MINGW32__ */

    buffer += sent;
    length -= sent;
  }

  outputLength = 0;
  return 1;
}

static int
writeBytes (const char *bytes, size_t length) {
  while (length) {
    size_t count = OUTPUT_SIZE - outputLength;
    if (length < count) count = length;
    memcpy(&outputBuffer[outputLength], bytes, count);
    bytes += count;
    length -= count;
    if ((outputLength += count) == OUTPUT_SIZE)
      if (!flushOutput())
        return 0;
  }

  return 1;
}

static int
writeByte (char byte) {
  return writeBytes(&byte, 1);
}

static int
writeString (const char *string) {
  return writeBytes(string, strlen(string));
}

static int
writeCharacter (wchar_t character) {
  Utf8Buffer buffer;
  size_t count = convertWcharToUtf8(character, buffer);
  return writeBytes(buffer, count);
}

static int
writeDots (const unsigned char *cells, int count) {
  const unsigned char *cell = cells;

  while (count-- > 0) {
    char dots[9];
    char *d = dots;

    if (cell != cells) *d++ = '|';
    if (*cell) {
      if (*cell & BRL_DOT1) *d++ = '1';
      if (*cell & BRL_DOT2) *d++ = '2';
      if (*cell & BRL_DOT3) *d++ = '3';
      if (*cell & BRL_DOT4) *d++ = '4';
      if (*cell & BRL_DOT5) *d++ = '5';
      if (*cell & BRL_DOT6) *d++ = '6';
      if (*cell & BRL_DOT7) *d++ = '7';
      if (*cell & BRL_DOT8) *d++ = '8';
    } else {
      *d++ = ' ';
    }
    ++cell;

    if (!writeBytes(dots, d-dots)) return 0;
  }

  return 1;
}

static int
writeLine (void) {
  if (inputCarriageReturn)
    if (!writeByte('\r'))
      return 0;

  if (writeByte('\n'))
    if (flushOutput())
      return 1;

  return 0;
}

static void
sortCommands (int (*compareCommands) (const void *item1, const void *item2)) {
  qsort(commandDescriptors, commandCount, commandSize, compareCommands);
}

static int
compareCommandCodes (const void *item1, const void *item2) {
  const CommandDescriptor *descriptor1 = item1;
  const CommandDescriptor *descriptor2 = item2;

  int code1 = descriptor1->entry->code;
  int code2 = descriptor2->entry->code;

  if (code1 < code2) return -1;
  if (code1 > code2) return 1;
  return 0;
}

static void
sortCommandsByCode (void) {
  sortCommands(compareCommandCodes);
}

static int
compareCommandNames (const void *item1, const void *item2) {
  const CommandDescriptor *descriptor1 = item1;
  const CommandDescriptor *descriptor2 = item2;

  return strcmp(descriptor1->entry->name, descriptor2->entry->name);
}

static void
sortCommandsByName (void) {
  sortCommands(compareCommandNames);
}

static int
allocateCommandDescriptors (void) {
  if (!commandDescriptors) {
    commandCount = getCommandCount();
    commandDescriptors = malloc(commandCount * commandSize);

    if (!commandDescriptors) {
      logMallocError();
      return 0;
    }

    {
      CommandDescriptor *descriptor = commandDescriptors;
      const CommandEntry *entry = commandTable;
      while (entry->name) {
        descriptor->entry = entry++;
        descriptor->count = 0;
        ++descriptor;
      }
    }

    sortCommandsByCode();
    {
      CommandDescriptor *descriptor = commandDescriptors + commandCount;
      int previousBlock = -1;

      while (descriptor-- != commandDescriptors) {
        int code = descriptor->entry->code;
        int currentBlock = code & BRL_MSK_BLK;

        if (currentBlock != previousBlock) {
          if (currentBlock) {
            descriptor->count = (BRL_MSK_ARG + 1) - (code & BRL_MSK_ARG);
          }
          previousBlock = currentBlock;
        }
      }
    }

    sortCommandsByName();
  }

  return 1;
}

static void
deallocateCommandDescriptors (void) {
  if (commandDescriptors) {
    free(commandDescriptors);
    commandDescriptors = NULL;
  }
}

static int
compareCommandName (const void *key, const void *item) {
  const char *name = key;
  const CommandDescriptor *descriptor = item;
  return compareWords(name, descriptor->entry->name);
}

static const CommandDescriptor *
findCommand (const char *name) {
  return bsearch(name, commandDescriptors, commandCount, commandSize, compareCommandName);
}

static int
dimensionsChanged (BrailleDisplay *brl) {
  int ok = 1;
  const char *word;

  int columns1;
  int rows1;

  int columns2 = 0;
  int rows2 = 0;

  if ((word = nextWord())) {
    if (isInteger(&columns1, word) && (columns1 > 0)) {
      rows1 = 1;

      if ((word = nextWord())) {
        if (isInteger(&rows1, word) && (rows1 > 0)) {
          if ((word = nextWord())) {
            if (isInteger(&columns2, word) && (columns2 > 0)) {
              rows2 = 0;

              if ((word = nextWord())) {
                if (isInteger(&rows2, word) && (rows2 > 0)) {
                } else {
                  logMessage(LOG_WARNING, "invalid status row count: %s", word);
                  ok = 0;
                }
              }
            } else {
              logMessage(LOG_WARNING, "invalid status column count: %s", word);
              ok = 0;
            }
          }
        } else {
          logMessage(LOG_WARNING, "invalid text row count: %s", word);
          ok = 0;
        }
      }
    } else {
      logMessage(LOG_WARNING, "invalid text column count: %s", word);
      ok = 0;
    }
  } else {
    logMessage(LOG_WARNING, "missing text column count");
    ok = 0;
  }

  if (ok) {
    int count1 = columns1 * rows1;
    int count2 = columns2 * rows2;
    unsigned char *braille;
    wchar_t *text;
    unsigned char *status;

    if ((braille = calloc(count1, sizeof(*braille)))) {
      if ((text = calloc(count1, sizeof(*text)))) {
        if ((status = calloc(count2, sizeof(*status)))) {
          brailleColumns = columns1;
          brailleRows = rows1;
          brailleCount = count1;

          statusColumns = columns2;
          statusRows = rows2;
          statusCount = count2;

          if (brailleCells) free(brailleCells);
          brailleCells = braille;
          memset(brailleCells, 0, count1);

          if (textCharacters) free(textCharacters);
          textCharacters = text;
          wmemset(textCharacters, WC_C(' '), count1);

          if (statusCells) free(statusCells);
          statusCells = status;
          memset(statusCells, 0, count2);
          memset(genericCells, 0, GSC_COUNT);

          brl->textColumns = brailleColumns;
          brl->textRows = brailleRows;
          brl->statusColumns = statusColumns;
          brl->statusRows = statusRows;
          return 1;
        }

        free(text);
      }

      free(braille);
    }
  }

  return 0;
}

static int
brl_construct (BrailleDisplay *brl, char **parameters, const char *device) {
  if (!allocateCommandDescriptors()) return 0;

  inputLength = 0;
  inputStart = 0;
  inputEnd = 0;
  outputLength = 0;

  if (hasQualifier(&device, "client")) {
    static const ModeEntry clientModeEntry = {
#ifdef AF_LOCAL
      requestLocalConnection,
#endif /* AF_LOCAL */

#ifdef __MINGW32__
      requestNamedPipeConnection,
#endif /* __MINGW32__ */

      requestInetConnection
    };
    mode = &clientModeEntry;
  } else if (hasQualifier(&device, "server")) {
    static const ModeEntry serverModeEntry = {
#ifdef AF_LOCAL
      acceptLocalConnection,
#endif /* AF_LOCAL */

#ifdef __MINGW32__
      acceptNamedPipeConnection,
#endif /* __MINGW32__ */

      acceptInetConnection
    };
    mode = &serverModeEntry;
  } else {
    unsupportedDeviceIdentifier(device);
    goto failed;
  }
  if (!*device) device = VR_DEFAULT_SOCKET;

#ifdef AF_LOCAL
  if (device[0] == '/') {
    struct sockaddr_un address;
    if (setLocalAddress(device, &address)) {
      fileDescriptor = mode->getLocalConnection(&address);
    }
  } else
#endif /* AF_LOCAL */

#ifdef __MINGW32__
  if (device[0] == '\\') {
    fileDescriptor = mode->getNamedPipeConnection(device);
  } else {
    static WSADATA wsadata;
    if (WSAStartup(MAKEWORD(1, 1), &wsadata)) {
      logWindowsSystemError("socket library start");
      goto failed;
    }
  }
#endif /* __MINGW32__ */

  {
    struct sockaddr_in address;
    if (setInetAddress(device, &address)) {
      fileDescriptor = mode->getInetConnection(&address);
    }
  }

  if (fileDescriptor != -1) {
    char *line = NULL;

    while (1) {
      if (line) free(line);
      if ((line = readCommandLine())) {
        const char *word;
        logMessage(LOG_DEBUG, "command received: %s", line);

        if ((word = strtok(line, inputDelimiters))) {
          if (testWord(word, "cells")) {
            if (dimensionsChanged(brl)) {
              free(line);
              return 1;
            }
          } else if (testWord(word, "quit")) {
            break;
          } else {
            logMessage(LOG_WARNING, "unexpected command: %s", word);
          }
        }
      } else {
        asyncWait(1000);
      }
    }
    if (line) free(line);

    close(fileDescriptor);
    fileDescriptor = -1;
  }

failed:
  deallocateCommandDescriptors();
  return 0;
}

static void
brl_destruct (BrailleDisplay *brl) {
  if (statusCells) {
    free(statusCells);
    statusCells = NULL;
  }

  if (textCharacters) {
    free(textCharacters);
    textCharacters = NULL;
  }

  if (brailleCells) {
    free(brailleCells);
    brailleCells = NULL;
  }

  if (fileDescriptor != -1) {
    close(fileDescriptor);
    fileDescriptor = -1;
  }

  deallocateCommandDescriptors();
}

static int
brl_writeWindow (BrailleDisplay *brl, const wchar_t *text) {
  if (text) {
    if (wmemcmp(text, textCharacters, brailleCount) != 0) {
      const wchar_t *address = text;
      int count = brailleCount;

      writeString("Visual \"");

      while (count-- > 0) {
        wchar_t character = *address++;

        switch (character) {
          case WC_C('"'):
          case WC_C('\\'):
            writeCharacter(WC_C('\\'));
            /* fall through */
          default:
            writeCharacter(character);
            break;
        }
      }

      writeString("\"");
      writeLine();

      wmemcpy(textCharacters, text, brailleCount);
    }
  }

  if (cellsHaveChanged(brailleCells, brl->buffer, brailleCount, NULL, NULL, NULL)) {
    writeString("Braille \"");
    writeDots(brl->buffer, brailleCount);
    writeString("\"");
    writeLine();
  }

  return 1;
}

static int
brl_writeStatus (BrailleDisplay *brl, const unsigned char *status) {
  int generic = status[GSC_FIRST] == GSC_MARKER;
  unsigned char *cells;
  int count;

  if (generic) {
    cells = genericCells;
    count = GSC_COUNT;
  } else {
    cells = statusCells;
    count = statusCount;
  }

  if (cellsHaveChanged(cells, status, count, NULL, NULL, NULL)) {
    if (generic) {
      int all = cells[GSC_FIRST] != GSC_MARKER;
      int i;

      for (i=1; i<count; ++i) {
        unsigned char value = status[i];
        if (all || (value != cells[i])) {
          static const char *const names[] = {
            [GSC_FIRST] = NULL,
            [gscBrailleWindowColumn] = "BRLCOL",
            [gscBrailleWindowRow] = "BRLROW",
            [gscScreenCursorColumn] = "CSRCOL",
            [gscScreenCursorRow] = "CSRROW",
            [gscScreenNumber] = "SCRNUM",
            [gscFrozenScreen] = "FREEZE",
            [gscDisplayMode] = "DISPMD",
            [gscSixDotComputerBraille] = "SIXDOTS",
            [gscContractedBraille] = "CONTRACTED",
            [gscSlidingBrailleWindow] = "SLIDEWIN",
            [gscSkipIdenticalLines] = "SKPIDLNS",
            [gscSkipBlankBrailleWindows] = "SKPBLNKWINS",
            [gscShowScreenCursor] = "CSRVIS",
            [gscHideScreenCursor] = "CSRHIDE",
            [gscTrackScreenCursor] = "CSRTRK",
            [gscScreenCursorStyle] = "CSRSIZE",
            [gscBlinkingScreenCursor] = "CSRBLINK",
            [gscShowAttributes] = "ATTRVIS",
            [gscBlinkingAttributes] = "ATTRBLINK",
            [gscBlinkingCapitals] = "CAPBLINK",
            [gscAlertTunes] = "TUNES",
            [gscAutorepeat] = "AUTOREPEAT",
            [gscAutospeak] = "AUTOSPEAK",
            [gscBrailleTypingMode] = "BRLUCDOTS"
          };
          const int nameCount = ARRAY_COUNT(names);

          if (i < nameCount) {
            const char *name = names[i];
            if (name) {
              char buffer[0X40];
              snprintf(buffer, sizeof(buffer), "%s %d", name, value);
              writeString(buffer);
              writeLine();
            }
          }
        }
      }
    } else {
      writeString("Status \"");
      writeDots(cells, count);
      writeString("\"");
      writeLine();
    }
  }

  return 1;
}

static int
brl_readCommand (BrailleDisplay *brl, KeyTableCommandContext context) {
  int command = EOF;
  char *line = readCommandLine();

  if (line) {
    const char *word;
    logMessage(LOG_DEBUG, "Command received: %s", line);

    if ((word = strtok(line, inputDelimiters))) {
      if (testWord(word, "cells")) {
        if (dimensionsChanged(brl)) brl->resizeRequired = 1;
      } else if (testWord(word, "quit")) {
        command = BRL_CMD_RESTARTBRL;
      } else {
        const CommandDescriptor *descriptor = findCommand(word);
        if (descriptor) {
          int needsNumber = descriptor->count > 0;
          int numberSpecified = 0;
          int switchSpecified = 0;
          int block;

          command = descriptor->entry->code;
          block = command & BRL_MSK_BLK;

          while ((word = nextWord())) {
            if (block == 0) {
              if (!switchSpecified) {
                if (testWord(word, "on")) {
                  switchSpecified = 1;
                  command |= BRL_FLG_TOGGLE_ON;
                  continue;
                }

                if (testWord(word, "off")) {
                  switchSpecified = 1;
                  command |= BRL_FLG_TOGGLE_OFF;
                  continue;
                }
              }
            }

            if (needsNumber && !numberSpecified) {
              int number;
              if (isInteger(&number, word)) {
                if ((number > 0) && (number <= descriptor->count)) {
                  numberSpecified = 1;
                  command += number;
                  continue;
                } else {
                  logMessage(LOG_WARNING, "Number out of range.");
                }
              }
            }

            logMessage(LOG_WARNING, "unknown option: %s", word);
          }

          if (needsNumber && !numberSpecified) {
            logMessage(LOG_WARNING, "Number not specified.");
            command = EOF;
          }
        } else {
          logMessage(LOG_WARNING, "unknown command: %s", word);
        }
      }
    }

    free(line);
  }

  return command;
}
