@@ -70,4 +70,103 @@ backup_if_exists() {
7070}
7171
7272is_domain () {
73- local s
73+ local s=" $1 "
74+ [[ " $s " =~ ^([A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])? \. )+[A-Za-z]{2,}$ ]]
75+ }
76+
77+ is_ipv4 () {
78+ local s=" $1 "
79+ [[ " $s " =~ ^([0-9]{1,3}\. ){3}[0-9]{1,3}$ ]]
80+ }
81+
82+ is_cidr () {
83+ local s=" $1 "
84+ [[ " $s " =~ ^([0-9]{1,3}\. ){3}[0-9]{1,3}/[0-9]{1,2}$ ]]
85+ }
86+
87+ already_in_file () {
88+ local needle=" $1 "
89+ local file=" $2 "
90+ grep -qE -- " ^${needle// ./ \\ .} ([[:space:]]|$)" " $file "
91+ }
92+
93+ add_postfix () {
94+ local v=" $1 "
95+ if already_in_file " $v " " $POSTFIX_FILE " ; then
96+ msg " ℹ️ Already in Postfix: $v "
97+ return 1
98+ fi
99+ msg " ➕ Adding to Postfix: $v OK"
100+ [[ $DRY -eq 0 ]] && echo " $v OK" >> " $POSTFIX_FILE "
101+ return 0
102+ }
103+
104+ add_postgrey () {
105+ local v=" $1 "
106+ if already_in_file " $v " " $POSTGREY_FILE " ; then
107+ msg " ℹ️ Already in Postgrey: $v "
108+ return 1
109+ fi
110+ msg " ➕ Adding to Postgrey: $v "
111+ [[ $DRY -eq 0 ]] && echo " $v " >> " $POSTGREY_FILE "
112+ return 0
113+ }
114+
115+ process_entry () {
116+ local raw=" $1 "
117+ local entry
118+ entry=" $( echo " $raw " | tr ' [:upper:]' ' [:lower:]' | xargs) "
119+ [[ -z " $entry " ]] && return 0
120+ [[ " $entry " =~ ^# ]] && return 0
121+
122+ if is_cidr " $entry " ; then
123+ msg " ⚠️ CIDR '$entry ' not supported in hash map."
124+ return 0
125+ elif is_ipv4 " $entry " ; then
126+ add_postfix " $entry " && CHANGED_POSTFIX=1 || true
127+ elif is_domain " $entry " ; then
128+ add_postfix " $entry " && CHANGED_POSTFIX=1 || true
129+ add_postgrey " $entry " && CHANGED_POSTGREY=1 || true
130+ else
131+ msg " ❌ Invalid entry: $entry "
132+ ERRORS=$(( ERRORS + 1 ))
133+ return 1
134+ fi
135+ }
136+
137+ require_root
138+ msg " 🔧 Dry-run: $DRY "
139+
140+ ensure_file " $POSTFIX_FILE "
141+ ensure_file " $POSTGREY_FILE "
142+ backup_if_exists " $POSTFIX_FILE "
143+ backup_if_exists " $POSTGREY_FILE "
144+
145+ CHANGED_POSTFIX= 0
146+ CHANGED_POSTGREY= 0
147+ ERRORS= 0
148+
149+ if [[ -n " $LIST_FILE " ]]; then
150+ [[ -f " $LIST_FILE " ]] || die " File not found: $LIST_FILE "
151+ while IFS= read -r line || [[ -n " $line " ]]; do
152+ process_entry " $line " || true
153+ done < " $LIST_FILE "
154+ else
155+ process_entry " $SINGLE_TARGET " || true
156+ fi
157+
158+ if [[ $DRY -eq 0 ]]; then
159+ if [[ $CHANGED_POSTFIX -eq 1 ]]; then
160+ msg " 🧰 postmap $POSTFIX_FILE "
161+ postmap " $POSTFIX_FILE "
162+ msg " 🔄 Restarting Postfix"
163+ systemctl restart postfix
164+ fi
165+ if [[ $CHANGED_POSTGREY -eq 1 ]]; then
166+ msg " 🔄 Restarting Postgrey"
167+ systemctl restart postgrey || true
168+ fi
169+ msg " ✅ Done. Changes: Postfix=${CHANGED_POSTFIX} , Postgrey=${CHANGED_POSTGREY} , Errors=${ERRORS} "
170+ else
171+ msg " 🔎 Dry-run complete. Would change: Postfix=${CHANGED_POSTFIX} , Postgrey=${CHANGED_POSTGREY} , Errors=${ERRORS} "
172+ fi
0 commit comments