2020-01-18 08:38:21 +00:00
/*
* Copyright ( c ) 2018 - 2020 , Andreas Kling < kling @ serenityos . org >
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are met :
*
* 1. Redistributions of source code must retain the above copyright notice , this
* list of conditions and the following disclaimer .
*
* 2. Redistributions in binary form must reproduce the above copyright notice ,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS "
* AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
* DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY ,
* OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
2020-02-06 14:04:03 +00:00
# include <LibCore/ArgsParser.h>
2019-08-03 03:25:51 +00:00
# include <stdio.h>
# include <sys/stat.h>
# include <unistd.h>
enum TruncateOperation {
OP_Set ,
OP_Grow ,
OP_Shrink ,
} ;
int main ( int argc , char * * argv )
{
2020-01-27 17:25:36 +00:00
const char * resize = nullptr ;
const char * reference = nullptr ;
const char * file = nullptr ;
2020-02-02 11:34:39 +00:00
Core : : ArgsParser args_parser ;
2020-01-27 17:25:36 +00:00
args_parser . add_option ( resize , " Resize the target file to (or by) this size. Prefix with + or - to expand or shrink the file, or a bare number to set the size exactly " , " size " , ' s ' , " size " ) ;
args_parser . add_option ( reference , " Resize the target file to match the size of this one " , " reference " , ' r ' , " file " ) ;
args_parser . add_positional_argument ( file , " File path " , " file " ) ;
args_parser . parse ( argc , argv ) ;
if ( ! resize & & ! reference ) {
args_parser . print_usage ( stderr , argv [ 0 ] ) ;
return 1 ;
2019-08-03 03:25:51 +00:00
}
2020-01-27 17:25:36 +00:00
if ( resize & & reference ) {
args_parser . print_usage ( stderr , argv [ 0 ] ) ;
return 1 ;
2019-08-03 03:25:51 +00:00
}
auto op = OP_Set ;
int size = 0 ;
2020-01-27 17:25:36 +00:00
if ( resize ) {
String str = resize ;
2019-08-03 03:25:51 +00:00
switch ( str [ 0 ] ) {
case ' + ' :
op = OP_Grow ;
str = str . substring ( 1 , str . length ( ) - 1 ) ;
break ;
case ' - ' :
op = OP_Shrink ;
str = str . substring ( 1 , str . length ( ) - 1 ) ;
break ;
}
2020-06-12 19:07:52 +00:00
auto size_opt = str . to_int ( ) ;
if ( ! size_opt . has_value ( ) ) {
2020-01-27 17:25:36 +00:00
args_parser . print_usage ( stderr , argv [ 0 ] ) ;
return 1 ;
2019-08-03 03:25:51 +00:00
}
2020-06-12 19:07:52 +00:00
size = size_opt . value ( ) ;
2019-08-03 03:25:51 +00:00
}
2020-01-27 17:25:36 +00:00
if ( reference ) {
2019-08-03 03:25:51 +00:00
struct stat st ;
2020-01-27 17:25:36 +00:00
int rc = stat ( reference , & st ) ;
2019-08-03 03:25:51 +00:00
if ( rc < 0 ) {
perror ( " stat " ) ;
2020-01-27 17:25:36 +00:00
return 1 ;
2019-08-03 03:25:51 +00:00
}
size = st . st_size ;
}
2020-01-27 17:25:36 +00:00
int fd = open ( file , O_RDWR | O_CREAT , 0666 ) ;
2019-08-03 03:25:51 +00:00
if ( fd < 0 ) {
perror ( " open " ) ;
2020-01-27 17:25:36 +00:00
return 1 ;
2019-08-03 03:25:51 +00:00
}
struct stat st ;
if ( fstat ( fd , & st ) < 0 ) {
perror ( " fstat " ) ;
2020-01-27 17:25:36 +00:00
return 1 ;
2019-08-03 03:25:51 +00:00
}
switch ( op ) {
case OP_Set :
break ;
case OP_Grow :
size = st . st_size + size ;
break ;
case OP_Shrink :
size = st . st_size - size ;
break ;
}
if ( ftruncate ( fd , size ) < 0 ) {
perror ( " ftruncate " ) ;
2020-01-27 17:25:36 +00:00
return 1 ;
2019-08-03 03:25:51 +00:00
}
if ( close ( fd ) < 0 ) {
perror ( " close " ) ;
2020-01-27 17:25:36 +00:00
return 1 ;
2019-08-03 03:25:51 +00:00
}
return 0 ;
}