@@ -137,9 +137,9 @@ export class NavContextMenu {
137137 } ) ;
138138 }
139139
140- async download ( e ) {
140+ async download ( e ) {
141141 let download_target = "" ;
142- let result ; // function-scoped so we can reference later
142+ let result ;
143143
144144 if ( this . nav_window_ref . selected_entries . size === 1 &&
145145 ! ( this . nav_window_ref . selected_entry ( ) instanceof NavDir ) ) {
@@ -149,7 +149,6 @@ export class NavContextMenu {
149149 try {
150150 result = await this . zip_for_download ( ) ;
151151 download_target = new NavFile ( result [ "archive-path" ] , result [ "stat" ] , this . nav_window_ref ) ;
152- console . log ( "prepared archive for download:" , result [ "archive-path" ] ) ;
153152 } catch ( err ) {
154153 this . nav_window_ref . stop_load ( ) ;
155154 this . nav_window_ref . modal_prompt . alert ( err . message ) ;
@@ -158,34 +157,85 @@ export class NavContextMenu {
158157 this . nav_window_ref . stop_load ( ) ;
159158 }
160159 }
161- if ( result ?. [ "archive-path" ] ) {
162- const unitName = `nav-clean-on-open-${ Date . now ( ) } -${ Math . random ( ) . toString ( 36 ) . slice ( 2 , 8 ) } ` ;
163- const script = [
164- 'set -euo pipefail' ,
165- 'if ! command -v inotifywait >/dev/null 2>&1; then ' +
166- 'sleep 300; rm -f -- "$ARCHIVE"; ' +
167- '[ -n "${TEMPDIR:-}" ] && [[ "$TEMPDIR" == /tmp/navigator-* ]] && rm -rf -- "$TEMPDIR"; ' +
168- 'exit 0; fi' ,
169- 'inotifywait -q -t 1800 -e open -- "$ARCHIVE" || true' ,
170- 'rm -f -- "$ARCHIVE"' ,
171- 'sleep 3600' ,
172- '[ -n "${TEMPDIR:-}" ] && [[ "$TEMPDIR" == /tmp/navigator-* ]] && rm -rf -- "$TEMPDIR" || :'
173- ] . join ( ' && ' ) ;
174- const cmd = [
175- 'systemd-run' ,
176- '--property=CollectMode=inactive-or-failed' ,
177- '--property=RuntimeMaxSec=90000' ,
178- '--unit' , unitName ,
179- '--setenv=ARCHIVE=' + result [ 'archive-path' ] ,
180- ...( result [ 'temp-dir' ] ? [ '--setenv=TEMPDIR=' + result [ 'temp-dir' ] ] : [ ] ) ,
181- '/bin/bash' , '-lc' , script
182- ] ;
183-
184- await cockpit . spawn ( cmd , { superuser : 'require' , err : 'out' } ) . then ( out => console . log ( out ) ) ;
185- console . log ( "scheduled cleanup:" , unitName ) ;
186- console . log ( "Deleting :" , result [ 'archive-path' ] , "in 30 minutes or after download starts." ) ;
187- }
188-
160+ if ( result ?. [ "archive-path" ] ) {
161+ const unitName = `nav-clean-sweep-on-close-${ Date . now ( ) } -${ Math . random ( ) . toString ( 36 ) . slice ( 2 , 8 ) } ` ;
162+
163+ const script = `
164+ set -euo pipefail
165+
166+ ARCHIVE="$ARCHIVE"
167+ DIR="$(dirname -- "$ARCHIVE")"
168+ BASE="$(basename -- "$ARCHIVE")"
169+ ROOT="/tmp/navigator"
170+ PATTERN="navigator-download*"
171+
172+ if ! command -v inotifywait >/dev/null 2>&1; then
173+ sleep 300
174+ rm -f -- "$ARCHIVE" || true
175+ # Sweep everything matching PATTERN that's not in use
176+ find "$ROOT" -mindepth 1 -maxdepth 1 -name "$PATTERN" -print0 | \
177+ while IFS= read -r -d '' p; do
178+ if command -v lsof >/dev/null 2>&1 && lsof -t -- "$p" >/dev/null 2>&1; then
179+ continue
180+ fi
181+ rm -rf -- "$p"
182+ done
183+ [ -n "\${TEMPDIR:-}" ] && [[ "$TEMPDIR" == /tmp/navigator-* ]] && rm -rf -- "$TEMPDIR" || :
184+ exit 0
185+ fi
186+
187+ if ! timeout 1800 bash -lc '
188+ inotifywait -q -m -e open --format "%e %f" -- "$DIR" |
189+ while read ev f; do
190+ if [ "$f" = "$BASE" ]; then exit 0; fi
191+ done
192+ '; then
193+ find "$ROOT" -mindepth 1 -maxdepth 1 -name "$PATTERN" -print0 | \
194+ while IFS= read -r -d '' p; do
195+ if command -v lsof >/dev/null 2>&1 && lsof -t -- "$p" >/dev/null 2>&1; then
196+ continue
197+ fi
198+ rm -rf -- "$p"
199+ done
200+ exit 0
201+ fi
202+
203+ if command -v lsof >/dev/null 2>&1; then
204+ # Ensure no process holds ARCHIVE open
205+ sleep 1
206+ while lsof -t -- "$ARCHIVE" >/dev/null 2>&1; do sleep 1; done
207+ else
208+ timeout 86400 bash -lc '
209+ inotifywait -q -m -e close --format "%e %f" -- "$DIR" |
210+ while read ev f; do
211+ if [ "$f" = "$BASE" ]; then exit 0; fi
212+ done
213+ ' || true
214+ fi
215+
216+ rm -f -- "$ARCHIVE" || true
217+
218+ # (uncomment -mmin +5 to keep very fresh ones)
219+ find "$ROOT" -mindepth 1 -maxdepth 1 -name "$PATTERN" -print0 | \
220+ while IFS= read -r -d '' p; do
221+ if command -v lsof >/dev/null 2>&1 && lsof -t -- "$p" >/dev/null 2>&1; then
222+ continue
223+ fi
224+ rm -rf -- "$p"
225+ done
226+ [ -n "\${TEMPDIR:-}" ] && [[ "$TEMPDIR" == /tmp/navigator-* ]] && rm -rf -- "$TEMPDIR" || :
227+ ` ;
228+ const cmd = [
229+ 'systemd-run' ,
230+ '--property=CollectMode=inactive-or-failed' ,
231+ '--property=RuntimeMaxSec=90000' ,
232+ '--unit' , unitName ,
233+ '--setenv=ARCHIVE=' + result [ 'archive-path' ] ,
234+ ...( result [ 'temp-dir' ] ? [ '--setenv=TEMPDIR=' + result [ 'temp-dir' ] ] : [ ] ) ,
235+ '/bin/bash' , '-lc' , script
236+ ] ;
237+ await cockpit . spawn ( cmd , { superuser : 'require' , err : 'out' } ) ;
238+ }
189239 const downloader = new NavDownloader ( download_target ) ;
190240 downloader . download ( ) ;
191241 }
0 commit comments