@ -436,32 +436,44 @@ filecopy(void)
return response ( false , " No file data received " ) ;
return response ( false , " No file data received " ) ;
}
}
if ( lseek ( st . tempfd , 0 , SEEK_SET ) < 0 )
{
close ( st . tempfd ) ;
return response ( false , " Failed to rewind temp file " ) ;
}
snprintf ( buf , sizeof ( buf ) , " /proc/self/fd/%d " , st . tempfd ) ;
st . filefd = open ( st . filename , O_CREAT | O_TRUNC | O_WRONLY , 0600 ) ;
if ( st . filefd < 0 )
if ( unlink ( st . filename ) < 0 & & errno ! = ENOENT )
{
{
close ( st . tempfd ) ;
close ( st . tempfd ) ;
return response ( false , " Failed to open target file " ) ;
return response ( false , " Failed to unlink existing file " ) ;
}
}
while ( ( len = read ( st . tempfd , buf , sizeof ( buf ) ) ) > 0 )
if ( linkat ( AT_FDCWD , buf , AT_FDCWD , st . filename , AT_SYMLINK_FOLLOW ) < 0 )
{
{
if ( write ( st . filefd , buf , len ) ! = len )
if ( lseek ( st . tempfd , 0 , SEEK_SET ) < 0 )
{
close ( st . tempfd ) ;
return response ( false , " Failed to rewind temp file " ) ;
}
st . filefd = open ( st . filename , O_CREAT | O_TRUNC | O_WRONLY , 0600 ) ;
if ( st . filefd < 0 )
{
{
close ( st . tempfd ) ;
close ( st . tempfd ) ;
close ( st . filefd ) ;
return response ( false , " I/O failure while writing target file " ) ;
return response ( false , " Failed to open target file " ) ;
}
}
while ( ( len = read ( st . tempfd , buf , sizeof ( buf ) ) ) > 0 )
{
if ( write ( st . filefd , buf , len ) ! = len )
{
close ( st . tempfd ) ;
close ( st . filefd ) ;
return response ( false , " I/O failure while writing target file " ) ;
}
}
close ( st . filefd ) ;
}
}
close ( st . tempfd ) ;
close ( st . tempfd ) ;
close ( st . filefd ) ;
if ( chmod ( st . filename , st . filemode ) )
if ( chmod ( st . filename , st . filemode ) )
return response ( false , " Failed to chmod target file " ) ;
return response ( false , " Failed to chmod target file " ) ;
@ -510,8 +522,6 @@ header_value(multipart_parser *p, const char *data, size_t len)
static int
static int
data_begin_cb ( multipart_parser * p )
data_begin_cb ( multipart_parser * p )
{
{
char tmpname [ 24 ] = " /tmp/luci-upload.XXXXXX " ;
if ( st . parttype = = PART_FILEDATA )
if ( st . parttype = = PART_FILEDATA )
{
{
if ( ! st . sessionid )
if ( ! st . sessionid )
@ -523,12 +533,10 @@ data_begin_cb(multipart_parser *p)
if ( ! session_access ( st . sessionid , " file " , st . filename , " write " ) )
if ( ! session_access ( st . sessionid , " file " , st . filename , " write " ) )
return response ( false , " Access to path denied by ACL " ) ;
return response ( false , " Access to path denied by ACL " ) ;
st . tempfd = mkstemp ( tmpname ) ;
st . tempfd = open ( " /tmp " , O_TMPFILE | O_RDWR , S_IRUSR | S_IWUSR ) ;
if ( st . tempfd < 0 )
if ( st . tempfd < 0 )
return response ( false , " Failed to create temporary file " ) ;
return response ( false , " Failed to create temporary file " ) ;
unlink ( tmpname ) ;
}
}
return 0 ;
return 0 ;