diff --git a/jtl-wafi-agent.py b/jtl-wafi-agent.py index 50d37e4..97eeb74 100644 --- a/jtl-wafi-agent.py +++ b/jtl-wafi-agent.py @@ -31,6 +31,7 @@ import ipaddress import signal import platform import threading +import fcntl import urllib.request import urllib.error from datetime import datetime, timedelta, timezone @@ -2596,13 +2597,6 @@ def add_shop_to_active(shop: str, monitor_only: Nur Monitoring, kein Blocking """ os.makedirs(os.path.dirname(ACTIVE_SHOPS_FILE), exist_ok=True) - shops = {} - if os.path.isfile(ACTIVE_SHOPS_FILE): - try: - with open(ACTIVE_SHOPS_FILE, 'r') as f: - shops = json.load(f) - except: - shops = {} shop_data = { "activated": datetime.now().isoformat(), @@ -2623,24 +2617,49 @@ def add_shop_to_active(shop: str, if unlimited_countries: shop_data["unlimited_countries"] = unlimited_countries - shops[shop] = shop_data - with open(ACTIVE_SHOPS_FILE, 'w') as f: - json.dump(shops, f, indent=2) + # File Locking für sichere parallele Zugriffe + lock_file = ACTIVE_SHOPS_FILE + '.lock' + with open(lock_file, 'w') as lf: + fcntl.flock(lf, fcntl.LOCK_EX) # Exklusiver Lock - wartet wenn gesperrt + try: + shops = {} + if os.path.isfile(ACTIVE_SHOPS_FILE): + try: + with open(ACTIVE_SHOPS_FILE, 'r') as f: + shops = json.load(f) + except: + shops = {} + + shops[shop] = shop_data + + with open(ACTIVE_SHOPS_FILE, 'w') as f: + json.dump(shops, f, indent=2) + finally: + fcntl.flock(lf, fcntl.LOCK_UN) # Lock freigeben def remove_shop_from_active(shop: str): """Entfernt einen Shop aus der aktiven Liste.""" if not os.path.isfile(ACTIVE_SHOPS_FILE): return - try: - with open(ACTIVE_SHOPS_FILE, 'r') as f: - shops = json.load(f) - if shop in shops: - del shops[shop] - with open(ACTIVE_SHOPS_FILE, 'w') as f: - json.dump(shops, f, indent=2) - except: - pass + + # File Locking für sichere parallele Zugriffe + lock_file = ACTIVE_SHOPS_FILE + '.lock' + with open(lock_file, 'w') as lf: + fcntl.flock(lf, fcntl.LOCK_EX) # Exklusiver Lock - wartet wenn gesperrt + try: + if not os.path.isfile(ACTIVE_SHOPS_FILE): + return + with open(ACTIVE_SHOPS_FILE, 'r') as f: + shops = json.load(f) + if shop in shops: + del shops[shop] + with open(ACTIVE_SHOPS_FILE, 'w') as f: + json.dump(shops, f, indent=2) + except: + pass + finally: + fcntl.flock(lf, fcntl.LOCK_UN) # Lock freigeben def get_shop_config(shop: str) -> Dict[str, Any]: