Subj : awk script for nodelists To : All From : Javier Sturman Date : Wed Apr 22 2026 05:03 pm Hello everybody! Based on ndl2binkd I (99% Gemini) created an awk script to generate the same output. It takes a nodelist as argument and it produces binkd expected node values. For sure it can be pefected. it assumes there are domains in binkd.conf named, fidonet, nixnet, fsxnet. Tested on FreeBSD. ---ndl.awk--- #!/usr/bin/awk -f BEGIN { # 1. Argument Validation if (ARGC < 2) { print "Error: No input file provided." > "/dev/stderr" print "Usage: ./ndl.awk " > "/dev/stderr" print "Example: ./ndl.awk nodelist.360" > "/dev/stderr" exit 1 } FS = "," current_zone = 1 current_net = 0 # Set DEBUG=1 via command line to see the parsing process: # awk -v DEBUG=1 -f ndl.awk if (DEBUG == "") DEBUG = 0 } # 2. Dynamic Domain Detection (based on filename) FNR == 1 { fname = toupper(FILENAME); if (fname ~ /NODELIST\./) dom = "fidonet"; else if (fname ~ /NIXLIST\./) dom = "nixnet"; else if (fname ~ /FSXNET\./) dom = "fsxnet"; else dom = "fidonet"; if (DEBUG) print "--- Debug: Processing file " FILENAME " as domain @" dom " ---" > "/dev/stderr" } # Skip comments and empty lines /^;/ || !NF { next } { gsub(/\r/, "", $0); # Normalize keyword to lowercase for robust matching keyword = tolower($1); number = $2; sysname = $3; sysop = $5; # 3. Filter DOWN and HOLD states if (keyword == "down" || keyword == "hold") { if (DEBUG) printf "--- Debug: Skipping node %d:%d/%d (Status: %s) ---\n", current_zone, current_net, number, keyword > "/dev/stderr" next; } # 4. Hierarchy Logic (Pascal Style) if (keyword == "zone") { current_zone = number; current_net = number; node_num = 0; } else if (keyword == "host" || keyword == "region") { current_net = number; node_num = 0; } else { node_num = number; } host_ip = ""; port = ""; # Priority tracking: 0=none, 1=ITN (Telnet), 2=IBN/INA (BinkP/Mail) p_priority = 0; # 5. Technical Flag Scanning (Case-Insensitive) for (i = 7; i <= NF; i++) { field_data = tolower($i); if (field_data ~ /^(ina|ibn|ifc|itn):/) { # Use original field $i for splitting to preserve Host casing n_sub = split($i, parts, ":"); tag = tolower(parts[1]); # Capture Hostname (INA/IBN have preference) if (n_sub >= 2 && parts[2] ~ /[A-Za-z\.]/ && host_ip == "") { host_ip = parts[2]; } # Port Priority Logic # According to FTSC, IBN is the primary BinkP mail port. # ITN (Telnet) should not overwrite it. current_tag_priority = (tag == "itn") ? 1 : 2; # Check for port in sub-part 2 (e.g., IBN:24555 or ITN:60177) if (n_sub >= 2 && parts[2] ~ /^[0-9]+$/) { if (current_tag_priority >= p_priority) { port = parts[2]; p_priority = current_tag_priority; if (DEBUG) printf " [Debug] Port %s set by %s (Priority %d)\n", port, tag, p_priority > "/dev/stderr" } } # Check for port in sub-part 3 (e.g., IBN:host:24555) if (n_sub >= 3 && parts[3] ~ /^[0-9]+$/) { if (current_tag_priority >= p_priority) { port = parts[3]; p_priority = current_tag_priority; if (DEBUG) printf " [Debug] Port %s set by %s (Priority %d)\n", port, tag, p_priority > "/dev/stderr" } } } } # 6. Final Output Generation if (host_ip != "") { gsub(/_/, " ", sysop); gsub(/_/, " ", sysname); full_dest = (port != "") ? host_ip ":" port : host_ip; gsub(/[[:space:]]+$/, "", full_dest); printf "# %s | %s\n", sysop, sysname; printf "node %d:%d/%d@%s -nd %s\n\n", current_zone, current_net, node_num, dom, full_dest; } } Javier --- GoldED+/BSD 1.1.5-b20170303-b20170303 + HPT 1.9.0 + Binkd 1.1a-115 * Origin: FIDONODO DE JAS | ¯\_(O,O)_/¯ (4:900/733) .