2007-12-07 22:28:16 +03:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2013-07-03 18:47:05 +04:00
Tar backup command extension
Copyright ( C ) Aurélien Aptel 2013
2007-12-07 22:28:16 +03:00
1996-05-04 11:50:46 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
1996-05-04 11:50:46 +04:00
( at your option ) any later version .
2007-12-07 22:28:16 +03:00
1996-05-04 11:50:46 +04:00
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2007-12-07 22:28:16 +03:00
1996-05-04 11:50:46 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1996-05-04 11:50:46 +04:00
*/
# include "includes.h"
2011-02-26 01:20:06 +03:00
# include "system/filesys.h"
2004-10-07 08:01:18 +04:00
# include "client/client_proto.h"
2013-07-08 20:09:47 +04:00
# include "client/clitar_proto.h"
2011-05-06 13:47:43 +04:00
# include "libsmb/libsmb.h"
2013-07-05 11:51:43 +04:00
# include <archive.h>
# define LEN(x) (sizeof(x) / sizeof((x)[0]))
2013-07-05 20:14:50 +04:00
# define TAR_MAX_BLOCK_SIZE 65535
1998-05-08 17:51:17 +04:00
2013-07-05 20:14:50 +04:00
enum tar_operation {
TAR_NO_OPERATION ,
TAR_CREATE , /* c flag */
TAR_EXTRACT , /* x flag */
} ;
enum tar_selection {
TAR_NO_SELECTION ,
2013-07-03 20:18:25 +04:00
TAR_INCLUDE , /* I flag, default */
2013-07-05 20:14:50 +04:00
TAR_INCLUDE_LIST , /* F flag */
TAR_EXCLUDE , /* X flag */
2013-07-03 20:18:25 +04:00
} ;
2013-07-05 11:51:43 +04:00
enum {
ATTR_UNSET ,
ATTR_SET ,
} ;
struct tar {
2013-07-09 17:10:44 +04:00
bool to_process ;
2013-07-03 20:18:25 +04:00
/* flags */
2013-07-05 20:14:50 +04:00
struct tar_mode {
enum tar_operation operation ; /* create, extract */
enum tar_selection selection ; /* inc, inc from file, exclude */
int blocksize ; /* size in bytes of a block in the tar file */
2013-07-03 20:18:25 +04:00
bool hidden ; /* backup hidden file? */
bool system ; /* backup system file? */
bool incremental ; /* backup _only_ archived file? */
bool reset ; /* unset archive bit? */
bool dry ; /* don't write tar file? */
2013-07-05 20:14:50 +04:00
bool regex ; /* XXX: never actually using regex... */
2013-07-05 11:51:43 +04:00
bool verbose ;
2013-07-03 20:18:25 +04:00
} mode ;
/* path to tar archive name */
char * tar_path ;
2013-07-08 20:09:47 +04:00
/* file descriptor of tar file */
int tar_fd ;
/* list of path to include or exclude */
char * * path_list ;
1998-09-18 16:47:46 +04:00
2013-07-05 11:51:43 +04:00
/* archive handle */
struct archive * archive ;
} ;
2013-07-03 20:18:25 +04:00
2013-07-08 20:09:47 +04:00
struct tar tar_ctx = {
2013-07-05 20:14:50 +04:00
. mode . selection = TAR_INCLUDE ,
. mode . blocksize = 20 ,
2013-07-09 15:09:56 +04:00
. mode . hidden = true ,
. mode . system = true ,
. mode . incremental = false ,
. mode . dry = false ,
2013-07-05 11:51:43 +04:00
} ;
2013-07-03 20:18:25 +04:00
2013-07-09 16:27:55 +04:00
static char * fix_unix_path ( char * path , bool removeprefix )
{
char * from = path , * to = path ;
if ( ! path | | ! * path )
return path ;
/* remove prefix:
* . / path = > path
* / path = > path
*/
if ( removeprefix ) {
/* /path */
if ( path [ 0 ] = = ' / ' | | path [ 0 ] = = ' \\ ' ) {
from + = 1 ;
}
/* ./path */
if ( path [ 1 ] & & path [ 0 ] = = ' . ' & & ( path [ 1 ] = = ' / ' | | path [ 1 ] = = ' \\ ' ) ) {
from + = 2 ;
}
}
/* replace \ with / */
while ( * from ) {
if ( * from = = ' \\ ' ) {
* to = ' / ' ;
} else {
* to = * from ;
}
from + + ; to + + ;
}
* to = 0 ;
return path ;
}
2013-07-09 13:41:06 +04:00
# define XSET(v) [v] = #v
# define XTABLE(v, t) DEBUG(2, ("DUMP:%-20.20s = %s\n", #v, t[v]))
# define XBOOL(v) DEBUG(2, ("DUMP:%-20.20s = %d\n", #v, v ? 1 : 0))
# define XSTR(v) DEBUG(2, ("DUMP:%-20.20s = %s\n", #v, v ? v : "NULL"))
# define XINT(v) DEBUG(2, ("DUMP:%-20.20s = %d\n", #v, v))
static void tar_dump ( struct tar * t )
{
int i ;
const char * op [ ] = {
XSET ( TAR_NO_OPERATION ) ,
XSET ( TAR_CREATE ) ,
XSET ( TAR_EXTRACT ) ,
} ;
const char * sel [ ] = {
XSET ( TAR_NO_SELECTION ) ,
XSET ( TAR_INCLUDE ) ,
XSET ( TAR_INCLUDE_LIST ) ,
XSET ( TAR_EXCLUDE ) ,
} ;
2013-07-09 17:10:44 +04:00
XBOOL ( t - > to_process ) ;
2013-07-09 13:41:06 +04:00
XTABLE ( t - > mode . operation , op ) ;
XTABLE ( t - > mode . selection , sel ) ;
XINT ( t - > mode . blocksize ) ;
XBOOL ( t - > mode . hidden ) ;
XBOOL ( t - > mode . system ) ;
XBOOL ( t - > mode . incremental ) ;
XBOOL ( t - > mode . reset ) ;
XBOOL ( t - > mode . dry ) ;
XBOOL ( t - > mode . verbose ) ;
XSTR ( t - > tar_path ) ;
XINT ( t - > tar_fd ) ;
for ( i = 0 ; t - > path_list & & t - > path_list [ i ] ; i + + ) {
DEBUG ( 2 , ( " DUMP: t->path_list[%2d] = %s \n " , i , t - > path_list [ i ] ) ) ;
}
DEBUG ( 2 , ( " DUMP:t->path_list @ %p (%d elem) \n " , t - > path_list , i ) ) ;
}
# undef XSET
# undef XTABLE
# undef XBOOL
# undef XSTR
# undef XINT
2013-07-05 20:14:50 +04:00
static int tar_set_blocksize ( struct tar * t , int size )
{
if ( size < = 0 | | size > TAR_MAX_BLOCK_SIZE ) {
return 0 ;
}
t - > mode . blocksize = size ;
return 1 ;
}
2013-07-09 13:41:06 +04:00
static bool tar_set_newer_than ( struct tar * t , const char * filename )
2013-07-05 20:14:50 +04:00
{
extern time_t newer_than ;
SMB_STRUCT_STAT stbuf ;
if ( sys_stat ( filename , & stbuf , false ) ! = 0 ) {
DEBUG ( 0 , ( " Error setting newer-than time \n " ) ) ;
return 0 ;
}
newer_than = convert_timespec_to_time_t ( stbuf . st_ex_mtime ) ;
DEBUG ( 1 , ( " Getting files newer than %s \n " , time_to_asc ( newer_than ) ) ) ;
return 1 ;
}
1996-05-04 11:50:46 +04:00
2013-07-08 20:09:47 +04:00
static bool tar_read_inclusion_file ( struct tar * t , const char * filename )
{
char * line ;
2013-07-09 13:41:06 +04:00
char * * list ;
2013-07-08 20:09:47 +04:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
int fd = open ( filename , O_RDONLY ) ;
if ( fd < 0 ) {
DEBUG ( 0 , ( " Can't open inclusion file '%s': %s \n " , filename , strerror ( errno ) ) ) ;
return 0 ;
}
list = str_list_make_empty ( ctx ) ;
while ( ( line = afdgets ( fd , ctx , 0 ) ) ) {
2013-07-09 16:27:55 +04:00
list = str_list_add ( ( const char * * ) list , fix_unix_path ( line , true ) ) ;
2013-07-08 20:09:47 +04:00
}
close ( fd ) ;
t - > path_list = list ;
return 1 ;
}
2013-07-09 17:10:44 +04:00
bool tar_to_process ( struct tar * t )
{
return t - > to_process ;
}
2013-07-05 13:33:55 +04:00
/**
* cmd_block - interactive command to change tar blocksize
*
* Read a size from the client command line and update the current
* blocksize .
*/
2001-10-09 23:12:18 +04:00
int cmd_block ( void )
1996-05-04 11:50:46 +04:00
{
2013-07-03 20:18:25 +04:00
/* XXX: from client.c */
const extern char * cmd_ptr ;
char * buf ;
2013-07-05 11:51:43 +04:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2013-07-03 20:18:25 +04:00
2013-07-05 11:51:43 +04:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
DEBUG ( 0 , ( " blocksize <n> \n " ) ) ;
return 1 ;
}
2013-07-03 20:18:25 +04:00
2013-07-05 20:14:50 +04:00
if ( ! tar_set_blocksize ( & tar_ctx , atoi ( buf ) ) ) {
DEBUG ( 0 , ( " invalid blocksize \n " ) ) ;
2013-07-05 11:51:43 +04:00
}
2013-07-03 20:18:25 +04:00
2013-07-05 20:14:50 +04:00
DEBUG ( 2 , ( " blocksize is now %d \n " , tar_ctx . mode . blocksize ) ) ;
2013-07-03 20:18:25 +04:00
2013-07-05 11:51:43 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
2013-07-05 13:33:55 +04:00
/**
* cmd_tarmode - interactive command to change tar behaviour
*
* Read one or more modes from the client command line and update the
* current tar mode .
*/
2001-10-09 23:12:18 +04:00
int cmd_tarmode ( void )
1996-05-04 11:50:46 +04:00
{
2013-07-05 11:51:43 +04:00
const extern char * cmd_ptr ;
char * buf ;
int i ;
TALLOC_CTX * ctx = talloc_tos ( ) ;
struct {
const char * cmd ;
bool * p ;
bool value ;
} table [ ] = {
2013-07-09 15:09:56 +04:00
{ " full " , & tar_ctx . mode . incremental , false } ,
{ " inc " , & tar_ctx . mode . incremental , true } ,
{ " reset " , & tar_ctx . mode . reset , true } ,
{ " noreset " , & tar_ctx . mode . reset , false } ,
{ " system " , & tar_ctx . mode . system , true } ,
{ " nosystem " , & tar_ctx . mode . system , false } ,
{ " hidden " , & tar_ctx . mode . hidden , true } ,
{ " nohidden " , & tar_ctx . mode . hidden , false } ,
{ " verbose " , & tar_ctx . mode . verbose , true } ,
{ " noquiet " , & tar_ctx . mode . verbose , true } ,
{ " quiet " , & tar_ctx . mode . verbose , false } ,
{ " noverbose " , & tar_ctx . mode . verbose , false } ,
2013-07-05 11:51:43 +04:00
} ;
while ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
for ( i = 0 ; i < LEN ( table ) ; i + + ) {
if ( strequal ( table [ i ] . cmd , buf ) ) {
* table [ i ] . p = table [ i ] . value ;
break ;
}
}
if ( i = = LEN ( table ) )
DEBUG ( 0 , ( " tarmode: unrecognised option %s \n " , buf ) ) ;
TALLOC_FREE ( buf ) ;
}
DEBUG ( 0 , ( " tarmode is now %s, %s, %s, %s, %s \n " ,
tar_ctx . mode . incremental ? " incremental " : " full " ,
tar_ctx . mode . system ? " system " : " nosystem " ,
tar_ctx . mode . hidden ? " hidden " : " nohidden " ,
tar_ctx . mode . reset ? " reset " : " noreset " ,
tar_ctx . mode . verbose ? " verbose " : " quiet " ) ) ;
2013-07-03 20:18:25 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
2013-07-05 13:33:55 +04:00
/**
* set_remote_attr - set DOS attributes of a remote file
* @ filename : path to the file name
* @ new_attr : attribute bit mask to use
* @ mode : one of ATTR_SET or ATTR_UNSET
*
* Update the file attributes with the one provided .
*/
2013-07-05 11:51:43 +04:00
static void set_remote_attr ( char * filename , uint16 new_attr , int mode )
{
extern struct cli_state * cli ;
uint16 old_attr ;
NTSTATUS status ;
if ( ! NT_STATUS_IS_OK ( cli_getatr ( cli , filename , & old_attr , NULL , NULL ) ) ) {
/* XXX: debug message */
return ;
}
if ( mode = = ATTR_SET ) {
new_attr | = old_attr ;
} else {
new_attr = old_attr & ~ new_attr ;
}
status = cli_setatr ( cli , filename , new_attr , 0 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 1 , ( " setatr failed: %s \n " , nt_errstr ( status ) ) ) ;
}
}
2013-07-05 13:33:55 +04:00
/**
* cmd_setmode - interactive command to set DOS attributes
*
* Read a filename and mode from the client command line and update
* the file DOS attributes .
*/
2001-10-09 23:12:18 +04:00
int cmd_setmode ( void )
1996-05-04 11:50:46 +04:00
{
2013-07-05 11:51:43 +04:00
const extern char * cmd_ptr ;
char * buf ;
char * fname = NULL ;
uint16 attr [ 2 ] = { 0 } ;
int mode = ATTR_SET ;
TALLOC_CTX * ctx = talloc_tos ( ) ;
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
DEBUG ( 0 , ( " setmode <filename> <[+|-]rsha> \n " ) ) ;
return 1 ;
}
fname = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! fname ) {
return 1 ;
}
while ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
const char * s = buf ;
while ( * s ) {
switch ( * s + + ) {
case ' + ' :
mode = ATTR_SET ;
break ;
case ' - ' :
mode = ATTR_UNSET ;
break ;
case ' r ' :
attr [ mode ] | = FILE_ATTRIBUTE_READONLY ;
break ;
case ' h ' :
attr [ mode ] | = FILE_ATTRIBUTE_HIDDEN ;
break ;
case ' s ' :
attr [ mode ] | = FILE_ATTRIBUTE_SYSTEM ;
break ;
case ' a ' :
attr [ mode ] | = FILE_ATTRIBUTE_ARCHIVE ;
break ;
default :
DEBUG ( 0 , ( " setmode <filename> <perm=[+|-]rsha> \n " ) ) ;
return 1 ;
}
}
}
if ( attr [ ATTR_SET ] = = 0 & & attr [ ATTR_UNSET ] = = 0 ) {
DEBUG ( 0 , ( " setmode <filename> <[+|-]rsha> \n " ) ) ;
return 1 ;
}
DEBUG ( 2 , ( " \n perm set %d %d \n " , attr [ ATTR_SET ] , attr [ ATTR_UNSET ] ) ) ;
set_remote_attr ( fname , attr [ ATTR_SET ] , ATTR_SET ) ;
set_remote_attr ( fname , attr [ ATTR_UNSET ] , ATTR_UNSET ) ;
2013-07-03 20:18:25 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
2007-12-19 23:59:28 +03:00
2013-07-08 20:09:47 +04:00
/**
* cmd_tar - interactive command to start a tar backup / restoration
*
* Check presence of argument , parse them and handle the request .
*/
2001-10-09 23:12:18 +04:00
int cmd_tar ( void )
1996-05-04 11:50:46 +04:00
{
2013-07-03 20:18:25 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
2013-07-09 17:24:40 +04:00
int tar_process ( struct tar * t )
1996-05-04 11:50:46 +04:00
{
2013-07-09 17:24:40 +04:00
int rc = 0 ;
switch ( t - > mode . operation ) {
case TAR_EXTRACT :
/* tar_extract(t); */
break ;
case TAR_CREATE :
/* tar_create(t); */
break ;
default :
DEBUG ( 0 , ( " Invalid tar state \n " ) ) ;
rc = 1 ;
}
return rc ;
1998-06-17 05:52:57 +04:00
}
2013-07-08 20:09:47 +04:00
/**
* tar_parse_args - parse and set tar command line arguments
* @ flag : string pointing to tar options
* @ val : number of tar arguments
* @ valsize : table of arguments after the flags ( number of element in val )
*
* tar arguments work in a weird way . For each flag f that takes a
* value v , the user is supposed to type :
*
* on the CLI :
* - Tf1f2f3 v1 v2 v3 TARFILE PATHS . . .
*
* in the interactive session :
* tar f1f2f3 v1 v2 v3 TARFILE PATHS . . .
*
* opt has only flags ( eg . " f1f2f3 " ) and val has the arguments
* ( values ) following them ( eg . [ " v1 " , " v2 " , " v3 " , " TARFILE " , " PATH1 " ,
* " PATH2 " ] ) .
*
* There are only 2 flags that take an arg : b and N . The other flags
* just change the semantic of PATH or TARFILE .
*
* PATH can be a list of included / excluded paths , the path to a file
* containing a list of included / excluded paths to use ( F flag ) . If no
* PATH is provided , the whole share is used ( / ) .
*/
int tar_parse_args ( struct tar * t , const char * flag , const char * * val , int valsize )
1996-05-04 11:50:46 +04:00
{
2013-07-08 20:09:47 +04:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
/* index of next value to use */
int ival = 0 ;
2013-07-05 20:14:50 +04:00
/*
* Reset back some options - could be from interactive version
2013-07-09 13:41:06 +04:00
* all other modes are left as they are
*/
2013-07-08 20:09:47 +04:00
t - > mode . operation = TAR_NO_OPERATION ;
t - > mode . selection = TAR_NO_SELECTION ;
2013-07-09 15:09:56 +04:00
t - > mode . dry = false ;
2013-07-09 17:10:44 +04:00
t - > to_process = false ;
2013-07-05 20:14:50 +04:00
2013-07-08 20:09:47 +04:00
while ( * flag ) {
switch ( * flag + + ) {
2013-07-05 20:14:50 +04:00
/* operation */
case ' c ' :
2013-07-08 20:09:47 +04:00
if ( t - > mode . operation ! = TAR_NO_OPERATION ) {
2013-07-05 20:14:50 +04:00
printf ( " Tar must be followed by only one of c or x. \n " ) ;
return 0 ;
}
2013-07-08 20:09:47 +04:00
t - > mode . operation = TAR_CREATE ;
2013-07-05 20:14:50 +04:00
break ;
case ' x ' :
2013-07-08 20:09:47 +04:00
if ( t - > mode . operation ! = TAR_NO_OPERATION ) {
2013-07-05 20:14:50 +04:00
printf ( " Tar must be followed by only one of c or x. \n " ) ;
return 0 ;
}
2013-07-09 13:41:06 +04:00
t - > mode . operation = TAR_EXTRACT ;
2013-07-05 20:14:50 +04:00
break ;
/* selection */
case ' I ' :
2013-07-08 20:09:47 +04:00
if ( t - > mode . selection ! = TAR_NO_SELECTION ) {
2013-07-05 20:14:50 +04:00
DEBUG ( 0 , ( " Only one of I,X,F must be specified \n " ) ) ;
return 0 ;
}
2013-07-08 20:09:47 +04:00
t - > mode . selection = TAR_INCLUDE ;
2013-07-05 20:14:50 +04:00
break ;
case ' X ' :
2013-07-08 20:09:47 +04:00
if ( t - > mode . selection ! = TAR_NO_SELECTION ) {
2013-07-05 20:14:50 +04:00
DEBUG ( 0 , ( " Only one of I,X,F must be specified \n " ) ) ;
return 0 ;
}
2013-07-08 20:09:47 +04:00
t - > mode . selection = TAR_EXCLUDE ;
2013-07-05 20:14:50 +04:00
break ;
case ' F ' :
2013-07-08 20:09:47 +04:00
if ( t - > mode . selection ! = TAR_NO_SELECTION ) {
2013-07-05 20:14:50 +04:00
DEBUG ( 0 , ( " Only one of I,X,F must be specified \n " ) ) ;
return 0 ;
}
2013-07-08 20:09:47 +04:00
t - > mode . selection = TAR_INCLUDE_LIST ;
2013-07-05 20:14:50 +04:00
break ;
/* blocksize */
case ' b ' :
2013-07-08 20:09:47 +04:00
if ( ival > = valsize ) {
2013-07-05 20:14:50 +04:00
DEBUG ( 0 , ( " Option b must be followed by a blocksize \n " ) ) ;
return 0 ;
}
2013-07-08 20:09:47 +04:00
if ( ! tar_set_blocksize ( t , atoi ( val [ ival ] ) ) ) {
2013-07-05 20:14:50 +04:00
DEBUG ( 0 , ( " Option b must be followed by a valid blocksize \n " ) ) ;
return 0 ;
}
2013-07-08 20:09:47 +04:00
ival + + ;
2013-07-05 20:14:50 +04:00
break ;
/* incremental mode */
case ' g ' :
2013-07-09 15:09:56 +04:00
t - > mode . incremental = true ;
2013-07-05 20:14:50 +04:00
break ;
/* newer than */
case ' N ' :
2013-07-08 20:09:47 +04:00
if ( ival > = valsize ) {
2013-07-05 20:14:50 +04:00
DEBUG ( 0 , ( " Option N must be followed by valid file name \n " ) ) ;
return 0 ;
}
2013-07-08 20:09:47 +04:00
if ( ! tar_set_newer_than ( t , val [ ival ] ) ) {
2013-07-05 20:14:50 +04:00
DEBUG ( 0 , ( " Error setting newer-than time \n " ) ) ;
return 0 ;
}
2013-07-08 20:09:47 +04:00
ival + + ;
2013-07-05 20:14:50 +04:00
break ;
/* reset mode */
case ' a ' :
2013-07-09 15:09:56 +04:00
t - > mode . reset = true ;
2013-07-05 20:14:50 +04:00
break ;
/* verbose */
case ' q ' :
2013-07-09 15:09:56 +04:00
t - > mode . verbose = true ;
2013-07-05 20:14:50 +04:00
break ;
/* regex match */
case ' r ' :
2013-07-09 15:09:56 +04:00
t - > mode . regex = true ;
2013-07-05 20:14:50 +04:00
break ;
/* dry run mode */
case ' n ' :
2013-07-08 20:09:47 +04:00
if ( t - > mode . operation ! = TAR_CREATE ) {
2013-07-05 20:14:50 +04:00
DEBUG ( 0 , ( " n is only meaningful when creating a tar-file \n " ) ) ;
return 0 ;
}
2013-07-09 15:09:56 +04:00
t - > mode . dry = true ;
2013-07-05 20:14:50 +04:00
DEBUG ( 0 , ( " dry_run set \n " ) ) ;
break ;
default :
DEBUG ( 0 , ( " Unknown tar option \n " ) ) ;
return 0 ;
}
}
2013-07-09 13:41:06 +04:00
/* no selection given? default selection is include */
if ( t - > mode . selection = = TAR_NO_SELECTION ) {
t - > mode . selection = TAR_INCLUDE ;
2013-07-05 20:14:50 +04:00
}
2013-07-08 20:09:47 +04:00
if ( valsize - ival < 1 ) {
DEBUG ( 0 , ( " No tar file given. \n " ) ) ;
return 0 ;
}
/* handle TARFILE */
t - > tar_path = talloc_strdup ( ctx , val [ ival ] ) ;
ival + + ;
/* handle PATHs... */
tar_ctx . path_list = str_list_make_empty ( ctx ) ;
/* flag F -> read file list */
if ( t - > mode . selection = = TAR_INCLUDE_LIST ) {
if ( valsize - ival ! = 1 ) {
2013-07-05 20:14:50 +04:00
DEBUG ( 0 , ( " Option F must be followed by exactly one filename. \n " ) ) ;
return 0 ;
}
2013-07-08 20:09:47 +04:00
2013-07-09 13:41:06 +04:00
if ( ! tar_read_inclusion_file ( t , val [ ival ] ) ) {
2013-07-08 20:09:47 +04:00
return 0 ;
}
ival + + ;
2013-07-05 20:14:50 +04:00
}
2013-07-08 20:09:47 +04:00
/* otherwise store all the PATHs on the command line */
else {
int i ;
for ( i = ival ; i < valsize ; i + + ) {
2013-07-09 13:41:06 +04:00
t - > path_list = str_list_add ( ( const char * * ) t - > path_list , val [ i ] ) ;
2013-07-09 16:27:55 +04:00
fix_unix_path ( t - > path_list [ i - ival ] , true ) ;
2013-07-08 20:09:47 +04:00
}
}
2013-07-05 20:14:50 +04:00
2013-07-09 17:10:44 +04:00
t - > to_process = true ;
2013-07-09 13:41:06 +04:00
tar_dump ( t ) ;
2013-07-08 20:09:47 +04:00
return 1 ;
1996-05-04 11:50:46 +04:00
}