/*
 * mars-nwe-dosutils - NetWare/DOS utility tools.
 *
 * Copyright (C) 2026 Mario Fetka
 * Copyright (C) 1993,1996 Martin Stover, Marburg, Germany
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

/*
 * Purpose: SLIST utility for listing visible NetWare file servers.
 * Depends on: net.h, netcall.c requester helpers, ncpcall.c bindery/server helpers, tools.c shared utility routines.
 */


#include "net.h"

#define NCP_BINDERY_FSERVER 0x0004

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

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 explicit_server = 0;
  int found = 0;
  int result;
  int i;
  int continuous = 0;
  int line_count = 0;

  (void)mode;

  strcpy(pattern, "*");

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

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

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

  upstr(pattern);

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

    found++;
    last_id = obj.object_id;

    if (found == 1) {
      fprintf(stdout, "%-48sNetwork   Node Address Status\n",
              "Known NetWare File Servers");
      fprintf(stdout, "%-48s-------   ------------ ------\n",
              "--------------------------");
    }

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

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

    fprintf(stdout, "\n");
    tool_page_line(&line_count, &continuous);

    if (last_id == MAX_U32) break;
  }

  if (explicit_server && !found) {
    fprintf(stdout, "Server %s not found.\n", pattern);
    return(0);
  }

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

  return(0);
}
