1313<?
1414$ docroot ??= ($ _SERVER ['DOCUMENT_ROOT ' ] ?: '/usr/local/emhttp ' );
1515require_once "$ docroot/webGui/include/Helpers.php " ;
16+ require_once "$ docroot/plugins/dynamix/include/PopularDestinations.php " ;
1617
1718// add translations
1819$ _SERVER ['REQUEST_URI ' ] = '' ;
@@ -42,12 +43,23 @@ function validname($name) {
4243function escape ($ name ) {return escapeshellarg (validname ($ name ));}
4344function quoted ($ name ) {return is_array ($ name ) ? implode (' ' ,array_map ('escape ' ,$ name )) : escape ($ name );}
4445
45- switch ($ _POST ['mode ' ]) {
46+ switch ($ _POST ['mode ' ] ?? $ _GET [ ' mode ' ] ?? '' ) {
4647case 'upload ' :
47- $ file = validname (htmlspecialchars_decode (rawurldecode ($ _POST ['file ' ])));
48+ $ file = validname (htmlspecialchars_decode (rawurldecode ($ _POST ['file ' ] ?? $ _GET [ ' file ' ] ?? '' )));
4849 if (!$ file ) die ('stop ' );
50+ $ start = (int )($ _POST ['start ' ] ?? $ _GET ['start ' ] ?? 0 );
51+ $ cancel = (int )($ _POST ['cancel ' ] ?? $ _GET ['cancel ' ] ?? 0 );
4952 $ local = "/var/tmp/ " .basename ($ file ).".tmp " ;
50- if ($ _POST ['start ' ]==0 ) {
53+ // Check cancel BEFORE creating new file
54+ if ($ cancel ==1 ) {
55+ if (file_exists ($ local )) {
56+ $ file = file_get_contents ($ local );
57+ if ($ file !== false ) delete_file ($ file );
58+ }
59+ delete_file ($ local );
60+ die ('stop ' );
61+ }
62+ if ($ start === 0 ) {
5163 $ my = pathinfo ($ file ); $ n = 0 ;
5264 while (file_exists ($ file )) $ file = $ my ['dirname ' ].'/ ' .preg_replace ('/ \(\d+\)$/ ' ,'' ,$ my ['filename ' ]).' ( ' .++$ n .') ' .($ my ['extension ' ] ? '. ' .$ my ['extension ' ] : '' );
5365 file_put_contents ($ local ,$ file );
@@ -58,13 +70,26 @@ function quoted($name) {return is_array($name) ? implode(' ',array_map('escape',
5870 chmod ($ file ,0666 );
5971 }
6072 $ file = file_get_contents ($ local );
61- if ($ _POST ['cancel ' ]==1 ) {
62- delete_file ($ file );
63- die ('stop ' );
73+ // Temp file does not exist
74+ if ($ file === false ) {
75+ die ('error:tempfile ' );
76+ }
77+ // Support both legacy base64 method and new raw binary method
78+ if (isset ($ _POST ['data ' ])) {
79+ // Legacy base64 upload method (backward compatible)
80+ $ chunk = base64_decode ($ _POST ['data ' ]);
81+ } else {
82+ // New raw binary upload method (read from request body)
83+ $ chunk = file_get_contents ('php://input ' );
84+ if (strlen ($ chunk ) > 21000000 ) { // slightly more than 20MB to allow overhead
85+ unlink ($ local );
86+ die ('error:chunksize: ' .strlen ($ chunk ));
87+ }
6488 }
65- if (file_put_contents ($ file ,base64_decode ( $ _POST [ ' data ' ]) ,FILE_APPEND )===false ) {
89+ if (file_put_contents ($ file ,$ chunk ,FILE_APPEND )===false ) {
6690 delete_file ($ file );
67- die ('error ' );
91+ delete_file ($ local );
92+ die ('error:write ' );
6893 }
6994 die ();
7095case 'calc ' :
@@ -109,11 +134,13 @@ function quoted($name) {return is_array($name) ? implode(' ',array_map('escape',
109134 $ file = '/var/tmp/file.manager.jobs ' ;
110135 $ rows = file_exists ($ file ) ? file ($ file ,FILE_IGNORE_NEW_LINES ) : [];
111136 $ job = 1 ;
112- for ($ x = 0 ; $ x < count ($ rows ); $ x +=9 ) {
113- $ data = parse_ini_string (implode ("\n" ,array_slice ($ rows ,$ x ,9 )));
114- $ task = $ data ['task ' ];
115- $ source = explode ("\r" ,$ data ['source ' ]);
116- $ target = $ data ['target ' ];
137+ foreach ($ rows as $ row ) {
138+ if (empty ($ row )) continue ;
139+ $ data = json_decode ($ row , true );
140+ if (!$ data ) continue ;
141+ $ task = $ data ['task ' ] ?? '' ;
142+ $ source = explode ("\r" ,$ data ['source ' ] ?? '' );
143+ $ target = $ data ['target ' ] ?? '' ;
117144 $ more = count ($ source ) > 1 ? " ( " .sprintf ("and %s more " ,count ($ source )-1 ).") " : "" ;
118145 $ jobs [] = '<i id="queue_ ' .$ job .'" class="fa fa-fw fa-square-o blue-text job" onclick="selectOne(this.id,false)"></i> ' ._ ('Job ' )." [ " .sprintf ("%'.04d " ,$ job ++)."] - $ task " .$ source [0 ].$ more .($ target ? " --> $ target " : "" );
119146 }
@@ -134,48 +161,77 @@ function quoted($name) {return is_array($name) ? implode(' ',array_map('escape',
134161 $ jobs = '/var/tmp/file.manager.jobs ' ;
135162 $ start = '0 ' ;
136163 if (file_exists ($ jobs )) {
137- exec ("sed -n '2,9 p' $ jobs > $ active " );
138- exec ("sed -i '1,9 d' $ jobs " );
139- $ start = filesize ($ jobs ) > 0 ? '2 ' : '1 ' ;
140- if ($ start =='1 ' ) delete_file ($ jobs );
164+ // read first JSON line from jobs file and write to active
165+ $ lines = file ($ jobs , FILE_IGNORE_NEW_LINES );
166+ if (!empty ($ lines )) {
167+ file_put_contents ($ active , $ lines [0 ]);
168+ // remove first line from jobs file
169+ array_shift ($ lines );
170+ if (count ($ lines ) > 0 ) {
171+ file_put_contents ($ jobs , implode ("\n" , $ lines )."\n" );
172+ $ start = '2 ' ;
173+ } else {
174+ delete_file ($ jobs );
175+ $ start = '1 ' ;
176+ }
177+ }
141178 }
142179 die ($ start );
143180case 'undo ' :
144181 $ jobs = '/var/tmp/file.manager.jobs ' ;
145182 $ undo = '0 ' ;
146183 if (file_exists ($ jobs )) {
147184 $ rows = array_reverse (explode (', ' ,$ _POST ['row ' ]));
185+ $ lines = file ($ jobs , FILE_IGNORE_NEW_LINES );
148186 foreach ($ rows as $ row ) {
149- $ end = $ row + 8 ;
150- exec ("sed -i ' $ row, $ end d' $ jobs " );
187+ $ line_number = $ row - 1 ; // Convert 1-based job number to 0-based array index
188+ if (isset ($ lines [$ line_number ])) {
189+ unset($ lines [$ line_number ]);
190+ }
191+ }
192+ if (count ($ lines ) > 0 ) {
193+ file_put_contents ($ jobs , implode ("\n" , $ lines )."\n" );
194+ $ undo = '2 ' ;
195+ } else {
196+ delete_file ($ jobs );
197+ $ undo = '1 ' ;
151198 }
152- $ undo = filesize ($ jobs ) > 0 ? '2 ' : '1 ' ;
153- if ($ undo =='1 ' ) delete_file ($ jobs );
154199 }
155200 die ($ undo );
156201case 'read ' :
157202 $ active = '/var/tmp/file.manager.active ' ;
158- $ read = file_exists ($ active ) ? json_encode ( parse_ini_file ( $ active) ) : '' ;
203+ $ read = file_exists ($ active ) ? file_get_contents ( $ active ) : '' ;
159204 die ($ read );
160205case 'file ' :
161206 $ active = '/var/tmp/file.manager.active ' ;
162207 $ jobs = '/var/tmp/file.manager.jobs ' ;
163- $ data [] = 'action=" ' .($ _POST ['action ' ]??'' ).'" ' ;
164- $ data [] = 'title=" ' .rawurldecode ($ _POST ['title ' ]??'' ).'" ' ;
165- $ data [] = 'source=" ' .htmlspecialchars_decode (rawurldecode ($ _POST ['source ' ]??'' )).'" ' ;
166- $ data [] = 'target=" ' .rawurldecode ($ _POST ['target ' ]??'' ).'" ' ;
167- $ data [] = 'H=" ' .(empty ($ _POST ['hdlink ' ]) ? '' : 'H ' ).'" ' ;
168- $ data [] = 'sparse=" ' .(empty ($ _POST ['sparse ' ]) ? '' : '--sparse ' ).'" ' ;
169- $ data [] = 'exist=" ' .(empty ($ _POST ['exist ' ]) ? '--ignore-existing ' : '' ).'" ' ;
170- $ data [] = 'zfs=" ' .rawurldecode ($ _POST ['zfs ' ]??'' ).'" ' ;
208+ $ data = [
209+ 'action ' => $ _POST ['action ' ] ?? '' ,
210+ 'title ' => rawurldecode ($ _POST ['title ' ] ?? '' ),
211+ 'source ' => htmlspecialchars_decode (rawurldecode ($ _POST ['source ' ] ?? '' )),
212+ 'target ' => htmlspecialchars_decode (rawurldecode ($ _POST ['target ' ] ?? '' )),
213+ 'H ' => empty ($ _POST ['hdlink ' ]) ? '' : 'H ' ,
214+ 'sparse ' => empty ($ _POST ['sparse ' ]) ? '' : '--sparse ' ,
215+ 'exist ' => empty ($ _POST ['exist ' ]) ? '--ignore-existing ' : '' ,
216+ 'zfs ' => rawurldecode ($ _POST ['zfs ' ] ?? '' )
217+ ];
171218 if (isset ($ _POST ['task ' ])) {
172219 // add task to queue
173- $ task = rawurldecode ($ _POST ['task ' ]);
174- $ data = "task= \"$ task \"\n" .implode ("\n" ,$ data )."\n" ;
175- file_put_contents ($ jobs ,$ data ,FILE_APPEND );
220+ $ data ['task ' ] = rawurldecode ($ _POST ['task ' ]);
221+ file_put_contents ($ jobs , json_encode ($ data )."\n" , FILE_APPEND );
222+
223+ // Update popular destinations for copy/move operations
224+ if (in_array ($ data ['action ' ], ['3 ' , '4 ' , '8 ' , '9 ' ]) && !empty ($ data ['target ' ])) {
225+ updatePopularDestinations ($ data ['target ' ]);
226+ }
176227 } else {
177228 // start operation
178- file_put_contents ($ active ,implode ("\n" ,$ data ));
229+ file_put_contents ($ active , json_encode ($ data ));
230+
231+ // Update popular destinations for copy/move operations
232+ if (in_array ($ data ['action ' ], ['3 ' , '4 ' , '8 ' , '9 ' ]) && !empty ($ data ['target ' ])) {
233+ updatePopularDestinations ($ data ['target ' ]);
234+ }
179235 }
180236 die ();
181237}
0 commit comments