/* slist.c - list known NetWare file servers, DOS mars-dosutils version */

#include "net.h"

#define NCP_BINDERY_FSERVER 0x0004

static int usage(void)
{
  fprintf(stdout, "Usage: SLIST [Server] [/Continue]\n");
  return(0);
}

static int same_arg(char *a, char *b)
{
  while (*a || *b) {
    int ca = *a++;
    int cb = *b++;
    if (ca >= 'a' && ca <= 'z') ca -= 32;
    if (cb >= 'a' && cb <= 'z') cb -= 32;
    if (ca != cb) return(0);
  }
  return(1);
}

static int is_help_arg(char *s)
{
  if (!s) return(0);
  return(same_arg(s, "/?") || same_arg(s, "-?") || same_arg(s, "?"));
}

static unsigned long node_to_number(uint8 *addr)
{
  unsigned long n = 0;
  int i;

  for (i = 4; i < 10; i++)
    n = (n << 8) + addr[i];

  return(n);
}

static void print_net_node_status(uint8 *addr, int is_default)
{
  fprintf(stdout, "[%08lX][%12lu]%s",
          (unsigned long)GET_BE32(addr),
          node_to_number(addr),
          is_default ? "Default" : "");
}

int func_slist(int argc, char *argv[], int mode)
{
  BINDERY_OBJECT obj;
  uint32 last_id = MAX_U32;
  uint8 pattern[50];
  int found = 0;
  int result;
  int i;

  (void)mode;

  strcpy(pattern, "*");

  for (i = 1; i < argc; i++) {
    if (is_help_arg(argv[i])) return(usage());

    if (argv[i][0] == '/' || argv[i][0] == '-') {
      if (same_arg(argv[i], "/C") || same_arg(argv[i], "/CONTINUE") ||
          same_arg(argv[i], "-C") || same_arg(argv[i], "-CONTINUE")) {
        continue;
      }
      return(usage());
    }

    strmaxcpy(pattern, argv[i], sizeof(pattern) - 1);
  }

  upstr(pattern);

  /*
   * Novell-like layout from the DOS client:
   * Known NetWare File Servers                    Network  Node Address Status
   * -------------------------                    -------- -------------------
   */
  fprintf(stdout, "%-44sNetwork  Node Address Status\n",
          "Known NetWare File Servers");
  fprintf(stdout, "%-44s-------   ----------- ------\n",
          "--------------------------");

  while ((result = ncp_17_37(last_id, NCP_BINDERY_FSERVER,
                             pattern, &obj)) == 0) {
    NW_PROPERTY prop;

    found++;
    last_id = obj.object_id;

    fprintf(stdout, "%-44s", obj.object_name);

    if (!ncp_17_3d(NCP_BINDERY_FSERVER, obj.object_name,
                   1, "NET_ADDRESS", &prop)) {
      print_net_node_status(prop.value, found == 1);
    }

    fprintf(stdout, "\n");

    if (last_id == MAX_U32) break;
  }

  fprintf(stdout, "\nTotal of %d file servers found\n", found);

  return(0);
}
