// handles mounting/unmounting the USB drive import { execSync } from 'node:child_process'; import { mkdirSync, rmdirSync, readFileSync, realpathSync, existsSync } from 'node:fs'; export function isMounted(mountPath) { try { return readFileSync('/proc/mounts', 'utf8').includes(` ${mountPath} `); } catch { return false; } } export function mountDrive(devNode, mountPath) { if (isMounted(mountPath)) { console.log(`[MOUNT] ${mountPath} is already mounted.`); return true; } try { // ensure the directory exists first mkdirSync(mountPath, { recursive: true }); // mount with open permissions so copyparty/rsync don't hit EACCES execSync(`mount -o umask=000,uid=1000,gid=1000 ${devNode} ${mountPath}`); console.log(`[MOUNT] success: ${devNode} -> ${mountPath}`); return true; } catch (err) { console.error(`[MOUNT] failed:`, err.message); return false; } } export function unmountDrive(mountPath) { if (!isMounted(mountPath)) { // cleanup orphaned directory just in case try { rmdirSync(mountPath); } catch {} return; } try { console.log(`[UNMOUNT] flushing buffers and unmounting ${mountPath}...`); execSync('sync'); // force kernel to write any pending data to the usb execSync(`umount -l ${mountPath}`); // lazy unmount in case a process is stuck reading rmdirSync(mountPath); console.log(`[UNMOUNT] cleanly unmounted and removed directory.`); } catch (err) { console.error(`[UNMOUNT] failed:`, err.message); } } export function driveExists(targetuid) { const linuidpath = '/dev/disk/by-uid/${targetuid}' if (!existsSync(linuidpath)) { return null; } try { return realpathSync(linuidpath) } catch { return null; } }