diff --git a/iprange.c b/iprange.c index 63e7b81..86ca22c 100644 --- a/iprange.c +++ b/iprange.c @@ -349,6 +349,7 @@ int main(int argc, char **argv) { size_t ipset_reduce_factor = 120; size_t ipset_reduce_min_accepted = 16384; int ret = 0, quiet = 0; + int inputs = 0; ipset *root = NULL, *ips = NULL, *first = NULL, *second = NULL; int i, mode = MODE_COMBINE, header = 0, read_second = 0; @@ -565,9 +566,8 @@ int main(int argc, char **argv) { } else { if(!strcmp(argv[i], "-")) { - ips = ipset_load(NULL); - - if(!ips) { + inputs++; + if(!(ips = ipset_load(NULL))) { fprintf(stderr, "%s: Cannot load ipset from stdin\n", PROG); exit(1); } @@ -585,6 +585,8 @@ int main(int argc, char **argv) { } } else if(argv[i][0] == '@') { + inputs++; + /* Handle @filename as a file list or directory */ const char *listname = argv[i] + 1; /* Skip the @ character */ struct stat st; @@ -629,11 +631,10 @@ int main(int argc, char **argv) { fprintf(stderr, "%s: Loading file %s from directory %s\n", PROG, entry->d_name, listname); /* Load the file as an independent ipset */ - ips = ipset_load(filepath); - if(!ips) { + if(!(ips = ipset_load(filepath))) { fprintf(stderr, "%s: Cannot load file %s from directory %s\n", PROG, filepath, listname); - continue; + exit(1); } files_loaded = 1; @@ -700,11 +701,10 @@ int main(int argc, char **argv) { fprintf(stderr, "%s: Loading file %s from list (line %d)\n", PROG, s, lineid); /* Load the file as an independent ipset */ - ips = ipset_load(s); - if(!ips) { + if(!(ips = ipset_load(s))) { fprintf(stderr, "%s: Cannot load file %s from list %s (line %d)\n", PROG, s, listname, lineid); - continue; + exit(1); } files_loaded = 1; @@ -736,11 +736,10 @@ int main(int argc, char **argv) { } } else { - ips = ipset_load(argv[i]); - - if(!ips) { + inputs++; + if(!(ips = ipset_load(argv[i]))) { fprintf(stderr, "%s: Cannot load ipset: %s\n", PROG, argv[i]); - continue; /* Continue with other arguments instead of exiting */ + exit(1); } if(read_second) { @@ -760,21 +759,21 @@ int main(int argc, char **argv) { /* * if no ipset was given on the command line - * assume stdin, but only if no other filenames were specified + * assume stdin, regardless of whether other options were specified */ - if(!root && argc <= 1) { + if(!inputs) { if(unlikely(debug)) - fprintf(stderr, "%s: No inputs provided, reading from stdin\n", PROG); - - first = root = ipset_load(NULL); - if(!root) { - fprintf(stderr, "%s: No ipsets to merge.\n", PROG); + fprintf(stderr, "%s: No input files provided, reading from stdin\n", PROG); + + if(!(first = root = ipset_load(NULL))) { + fprintf(stderr, "%s: Cannot load ipset from stdin\n", PROG); exit(1); } } - else if(!root) { - /* We had parameters but still ended up with no valid ipsets */ + + if(!root) { + // impossible situation since we fail if no ipset is loaded fprintf(stderr, "%s: No valid ipsets to merge from the provided inputs.\n", PROG); exit(1); } diff --git a/ipset_load.c b/ipset_load.c index 2738b96..f13d1a5 100644 --- a/ipset_load.c +++ b/ipset_load.c @@ -610,13 +610,13 @@ ipset *ipset_load(const char *filename) { ips->flags |= IPSET_FLAG_OPTIMIZED; if(!fgets(line, MAX_LINE, fp)) { - if(likely(fp != stdin)) fclose(fp); - /* Empty file - if not stdin, consider it an error */ - if(likely(filename && *filename)) { - if(unlikely(debug)) fprintf(stderr, "%s: File %s is empty\n", PROG, filename); - ipset_free(ips); - return NULL; - } + if(likely(fp != stdin)) + fclose(fp); + + /* For normal files, an empty file is valid too (return empty ipset) */ + if(unlikely(debug)) + fprintf(stderr, "%s: %s is empty\n", PROG, filename && *filename?filename:"stdin"); + return ips; } diff --git a/tests.d/19-nonexistent-paths/cmd.sh b/tests.d/19-nonexistent-paths/cmd.sh index d95a72f..cb3d31f 100755 --- a/tests.d/19-nonexistent-paths/cmd.sh +++ b/tests.d/19-nonexistent-paths/cmd.sh @@ -2,22 +2,5 @@ # Test handling of non-existent files and directories # The program should gracefully handle these cases -echo "=== Test 1: Non-existent file ===" -if ../../iprange nonexistent_file input1 2>error.log; then - echo "FAILED: Should have shown error for non-existent file" -else - echo "PASSED: Correctly handled non-existent file" -fi - -echo "=== Test 2: Non-existent directory ===" -if ../../iprange @nonexistent_dir input1 2>error2.log; then - echo "FAILED: Should have shown error for non-existent directory" -else - echo "PASSED: Correctly handled non-existent directory" -fi - -echo "=== Test 3: Valid file works ===" -../../iprange input1 - -# Cleanup -rm -f error*.log \ No newline at end of file +../../iprange nonexistent_file input1 2>/dev/null || echo "FAILED AS EXPECTED 1" +../../iprange input1 @nonexistent_file 2>/dev/null || echo "FAILED AS EXPECTED 2" diff --git a/tests.d/19-nonexistent-paths/output b/tests.d/19-nonexistent-paths/output index 62f8755..2f3c313 100644 --- a/tests.d/19-nonexistent-paths/output +++ b/tests.d/19-nonexistent-paths/output @@ -1,7 +1,2 @@ -=== Test 1: Non-existent file === -192.168.1.1 -FAILED: Should have shown error for non-existent file -=== Test 2: Non-existent directory === -PASSED: Correctly handled non-existent directory -=== Test 3: Valid file works === -192.168.1.1 +FAILED AS EXPECTED 1 +FAILED AS EXPECTED 2 diff --git a/tests.d/22-binary-to-text/cmd.sh b/tests.d/22-binary-to-text/cmd.sh new file mode 100755 index 0000000..cdbf13c --- /dev/null +++ b/tests.d/22-binary-to-text/cmd.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Convert to binary and back to text +echo "250.250.250.250" | ../../iprange input1 --print-binary | ../../iprange diff --git a/tests.d/22-binary-to-text/input1 b/tests.d/22-binary-to-text/input1 new file mode 100644 index 0000000..338492b --- /dev/null +++ b/tests.d/22-binary-to-text/input1 @@ -0,0 +1,3 @@ +192.168.1.1 +192.168.1.2 +10.0.0.1 diff --git a/tests.d/22-binary-to-text/output b/tests.d/22-binary-to-text/output new file mode 100644 index 0000000..df5aad9 --- /dev/null +++ b/tests.d/22-binary-to-text/output @@ -0,0 +1,3 @@ +10.0.0.1 +192.168.1.1 +192.168.1.2 diff --git a/tests.d/23-empty-input-count/cmd.sh b/tests.d/23-empty-input-count/cmd.sh new file mode 100755 index 0000000..b74d18c --- /dev/null +++ b/tests.d/23-empty-input-count/cmd.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +# Input is an empty set (file) +echo >empty_file +../../iprange empty_file -C diff --git a/tests.d/23-empty-input-count/empty_file b/tests.d/23-empty-input-count/empty_file new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tests.d/23-empty-input-count/empty_file @@ -0,0 +1 @@ + diff --git a/tests.d/23-empty-input-count/output b/tests.d/23-empty-input-count/output new file mode 100644 index 0000000..15794e0 --- /dev/null +++ b/tests.d/23-empty-input-count/output @@ -0,0 +1 @@ +0,0 diff --git a/tests.d/24-nonexistent-file-count/cmd.sh b/tests.d/24-nonexistent-file-count/cmd.sh new file mode 100755 index 0000000..3b59728 --- /dev/null +++ b/tests.d/24-nonexistent-file-count/cmd.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +# Input file does not exist - -C should fail with exit code 1 + +../../iprange non_existent_file -C 2>/dev/null || echo "FAILED AS EXPECTED" diff --git a/tests.d/24-nonexistent-file-count/output b/tests.d/24-nonexistent-file-count/output new file mode 100644 index 0000000..15879d0 --- /dev/null +++ b/tests.d/24-nonexistent-file-count/output @@ -0,0 +1 @@ +FAILED AS EXPECTED diff --git a/tests.d/25-missing-file-in-list-count/cmd.sh b/tests.d/25-missing-file-in-list-count/cmd.sh new file mode 100755 index 0000000..f1d9ce7 --- /dev/null +++ b/tests.d/25-missing-file-in-list-count/cmd.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# Input file list exists, but a file in the list does not - -C should fail with exit code 1 + +echo "non_existent_file" > filelist +../../iprange @filelist -C 2>/dev/null || echo "FAILED AS EXPECTED" diff --git a/tests.d/25-missing-file-in-list-count/filelist b/tests.d/25-missing-file-in-list-count/filelist new file mode 100644 index 0000000..db5c695 --- /dev/null +++ b/tests.d/25-missing-file-in-list-count/filelist @@ -0,0 +1 @@ +non_existent_file diff --git a/tests.d/25-missing-file-in-list-count/output b/tests.d/25-missing-file-in-list-count/output new file mode 100644 index 0000000..15879d0 --- /dev/null +++ b/tests.d/25-missing-file-in-list-count/output @@ -0,0 +1 @@ +FAILED AS EXPECTED diff --git a/tests.d/26-empty-file-in-list-count/cmd.sh b/tests.d/26-empty-file-in-list-count/cmd.sh new file mode 100755 index 0000000..80927d9 --- /dev/null +++ b/tests.d/26-empty-file-in-list-count/cmd.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Input file list exists, but a file is empty, -C should output 0,0 and exit code should be 0 + +echo >empty_file +echo "empty_file" > filelist +../../iprange @filelist -C diff --git a/tests.d/26-empty-file-in-list-count/empty_file b/tests.d/26-empty-file-in-list-count/empty_file new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tests.d/26-empty-file-in-list-count/empty_file @@ -0,0 +1 @@ + diff --git a/tests.d/26-empty-file-in-list-count/filelist b/tests.d/26-empty-file-in-list-count/filelist new file mode 100644 index 0000000..86ff5d3 --- /dev/null +++ b/tests.d/26-empty-file-in-list-count/filelist @@ -0,0 +1 @@ +empty_file diff --git a/tests.d/26-empty-file-in-list-count/output b/tests.d/26-empty-file-in-list-count/output new file mode 100644 index 0000000..15794e0 --- /dev/null +++ b/tests.d/26-empty-file-in-list-count/output @@ -0,0 +1 @@ +0,0 diff --git a/tests.d/27-binary-save-load/cmd.sh b/tests.d/27-binary-save-load/cmd.sh new file mode 100755 index 0000000..2a3e83e --- /dev/null +++ b/tests.d/27-binary-save-load/cmd.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +# Binary files: read a plain text file with IPs and write a binary file + +echo "172.16.99.1" | ../../iprange input1 --print-binary | ../../iprange diff --git a/tests.d/27-binary-save-load/input1 b/tests.d/27-binary-save-load/input1 new file mode 100644 index 0000000..c266ace --- /dev/null +++ b/tests.d/27-binary-save-load/input1 @@ -0,0 +1,6 @@ +192.168.1.1 +192.168.1.2 +192.168.1.5 +192.168.1.6/31 +192.168.1.8/31 +192.168.1.10 diff --git a/tests.d/27-binary-save-load/output b/tests.d/27-binary-save-load/output new file mode 100644 index 0000000..c266ace --- /dev/null +++ b/tests.d/27-binary-save-load/output @@ -0,0 +1,6 @@ +192.168.1.1 +192.168.1.2 +192.168.1.5 +192.168.1.6/31 +192.168.1.8/31 +192.168.1.10 diff --git a/tests.d/28-binary-empty/cmd.sh b/tests.d/28-binary-empty/cmd.sh new file mode 100755 index 0000000..39dd0e8 --- /dev/null +++ b/tests.d/28-binary-empty/cmd.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +# Create binary file from empty input +echo >empty +echo "250.250.250.250" | ../../iprange empty --print-binary | ../../iprange diff --git a/tests.d/28-binary-empty/empty b/tests.d/28-binary-empty/empty new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tests.d/28-binary-empty/empty @@ -0,0 +1 @@ + diff --git a/tests.d/28-binary-empty/output b/tests.d/28-binary-empty/output new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tests.d/28-binary-empty/output @@ -0,0 +1 @@ + diff --git a/tests.d/29-mixed-text-binary/cmd.sh b/tests.d/29-mixed-text-binary/cmd.sh new file mode 100755 index 0000000..968ff38 --- /dev/null +++ b/tests.d/29-mixed-text-binary/cmd.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Mixing text and binary files: have input1 as text and pipe the output of another iprange that creates a binary version of input2 + +cat >input1 <input2 <