diff --git a/Plugin/unraid/api/rsync_win_arrays.php b/Plugin/unraid/api/rsync_win_arrays.php new file mode 100644 index 0000000..ecd9138 --- /dev/null +++ b/Plugin/unraid/api/rsync_win_arrays.php @@ -0,0 +1,133 @@ +isFile() || strtolower($rf->getExtension()) !== 'sh') continue; + $rel = ltrim(str_replace($base, '', $rf->getPathname()), '/'); + $parts = explode('/', $rel); + if (count($parts) < 2 || in_array($parts[0], $exclude)) continue; + $folder = $parts[0]; + $label = str_replace('_', ' ', basename($rel, '.sh')); + $groups[$folder][] = ['id' => $rel, 'label' => $label]; + } + } catch (Exception $e) {} + ksort($groups); + foreach ($groups as &$g) usort($g, fn($a, $b) => strcmp($a['id'], $b['id'])); + echo json_encode(['ok' => true, 'groups' => $groups]); + exit; +} + +// ── Profile names from master.conf ──────────────────────────────────────────── +if ($action === 'list_profiles') { + $raw = vv_read_conf_raw('master.conf'); + preg_match_all('/^\s*PROFILE_([A-Z0-9_]+)_RSYNC_OPTS\s*=/m', $raw, $m); + $profiles = array_values(array_unique( + array_map(fn($n) => strtolower(str_replace('_', '-', $n)), $m[1] ?? []) + )); + echo json_encode(['ok' => true, 'profiles' => $profiles]); + exit; +} + +// ── Save scripts + shares for a window ─────────────────────────────────────── +if ($action === 'save' && $_SERVER['REQUEST_METHOD'] === 'POST') { + $winKey = trim($_POST['win_key'] ?? ''); + $scripts = json_decode($_POST['scripts'] ?? 'null', true); + $shares = json_decode($_POST['shares'] ?? 'null', true); + + $winMap = [ + 'critical' => ['CRITICAL_MAINTENANCE_SCRIPTS', 'CRITICAL_SYNC_SHARES'], + 'intermediate' => ['INTERMEDIATE_MAINTENANCE_SCRIPTS', 'INTERMEDIATE_SYNC_SHARES'], + 'daily' => ['DAILY_MAINTENANCE_SCRIPTS', 'DAILY_SYNC_SHARES'], + 'weekly' => ['WEEKLY_MAINTENANCE_SCRIPTS', 'WEEKLY_SYNC_SHARES'], + ]; + + if (!isset($winMap[$winKey])) { + echo json_encode(['ok' => false, 'error' => 'Invalid window']); exit; + } + + [$scriptsVar, $sharesBase] = $winMap[$winKey]; + $myId = strtoupper(vv_detect_host()); + $sharesVar = "{$myId}_{$sharesBase}"; + $errors = []; + + // ── Scripts → master.conf ───────────────────────────────────────────────── + if (is_array($scripts)) { + $confPath = CONF_DIR . '/master.conf'; + $lines = file($confPath, FILE_KEEP_BLANK_LINES) ?: []; + $esc = preg_quote($scriptsVar, '/'); + $blockStart = $blockEnd = null; + $depth = 0; + $origLines = []; + + foreach ($lines as $i => $line) { + if ($blockStart === null) { + if (preg_match('/^\s*' . $esc . '\s*=\s*\(/', $line)) { $blockStart = $i; $depth = 1; } + continue; + } + $depth += substr_count($line, '(') - substr_count($line, ')'); + if ($depth <= 0) { $blockEnd = $i; break; } + if (preg_match('/^\s*(?:#\s*)?"([^"]+)"/', $line, $m)) { + $path = explode(' ', trim($m[1]))[0]; + if (str_ends_with($path, '.sh') && !isset($origLines[$path])) + $origLines[$path] = '"' . $m[1] . '"'; + } + } + + if ($blockStart !== null && $blockEnd !== null) { + $newBlock = [$lines[$blockStart]]; + foreach ($scripts as $item) { + $id = trim((string)($item['id'] ?? '')); + $enabled = !isset($item['enabled']) || (bool)$item['enabled']; + if (!$id || str_contains($id, '..') || !preg_match('/^[A-Za-z0-9_.\-\/]+\.sh$/', $id)) continue; + $entry = $origLines[$id] ?? '"' . $id . '"'; + $prefix = $enabled ? ' ' : ' #'; + $newBlock[] = $prefix . $entry . "\n"; + } + $newBlock[] = $lines[$blockEnd]; + array_splice($lines, $blockStart, $blockEnd - $blockStart + 1, $newBlock); + if (file_put_contents($confPath, implode('', $lines)) === false) $errors[] = 'scripts write failed'; + } else { + $errors[] = "Array $scriptsVar not found in master.conf"; + } + } + + // ── Shares → host*.conf ─────────────────────────────────────────────────── + if (is_array($shares)) { + $confFile = strtolower($myId) . '.conf'; + $inner = ''; + foreach ($shares as $item) { + $path = trim((string)($item['path'] ?? '')); + $profile = trim((string)($item['profile'] ?? '')); + if (!$path || str_contains($path, '..') || !str_starts_with($path, '/')) continue; + $val = $profile ? "{$path}|{$profile}" : $path; + $inner .= ' "' . $val . '"' . "\n"; + } + $results = vv_conf_write_changes([[ + 'file' => $confFile, + 'key' => $sharesVar, + 'value' => rtrim($inner), + 'type' => 'array', + ]]); + if (in_array(false, $results, true)) $errors[] = 'shares write failed'; + } + + echo json_encode(['ok' => empty($errors), 'errors' => $errors]); + exit; +} + +echo json_encode(['ok' => false, 'error' => 'Unknown action']); diff --git a/Plugin/unraid/pages/rsync.php b/Plugin/unraid/pages/rsync.php index aaedf86..0fdf653 100644 --- a/Plugin/unraid/pages/rsync.php +++ b/Plugin/unraid/pages/rsync.php @@ -468,6 +468,57 @@