18
18
19
19
static const char doc_cptofs [] = "Copy files to a filesystem image" ;
20
20
static const char doc_cpfromfs [] = "Copy files from a filesystem image" ;
21
- static const char args_doc_cptofs [] = "-t fstype -i fsimage path fs_path" ;
22
- static const char args_doc_cpfromfs [] = "-t fstype -i fsimage fs_path path" ;
21
+ static const char args_doc_cptofs [] = "-t fstype -i fsimage path... fs_path" ;
22
+ static const char args_doc_cpfromfs [] = "-t fstype -i fsimage fs_path... path" ;
23
23
24
24
static struct argp_option options [] = {
25
25
{"enable-printk" , 'p' , 0 , 0 , "show Linux printks" },
@@ -37,8 +37,8 @@ static struct cl_args {
37
37
int part ;
38
38
const char * fsimg_type ;
39
39
const char * fsimg_path ;
40
- const char * src_path ;
41
- const char * dst_path ;
40
+ int npaths ;
41
+ char * * paths ;
42
42
const char * selinux ;
43
43
} cla ;
44
44
@@ -65,18 +65,13 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
65
65
cla -> selinux = arg ;
66
66
break ;
67
67
case ARGP_KEY_ARG :
68
- if (!cla -> src_path ) {
69
- cla -> src_path = arg ;
70
- } else if (!cla -> dst_path ) {
71
- cla -> dst_path = arg ;
72
- } else {
73
- argp_usage (state );
74
- return -1 ;
75
- }
68
+ // Capture all remaining arguments in our paths array and stop
69
+ // parsing here. We treat the last one as the destination and
70
+ // everything before it as sources, just like cp does.
71
+ cla -> paths = & state -> argv [state -> next - 1 ];
72
+ cla -> npaths = state -> argc - state -> next + 1 ;
73
+ state -> next = state -> argc ;
76
74
break ;
77
- case ARGP_KEY_END :
78
- if (state -> arg_num < 2 || !cla -> fsimg_type || !cla -> fsimg_path )
79
- argp_usage (state );
80
75
default :
81
76
return ARGP_ERR_UNKNOWN ;
82
77
}
@@ -485,12 +480,31 @@ static int searchdir(const char *src, const char *dst, const char *match)
485
480
return ret ;
486
481
}
487
482
483
+ int copy_one (const char * src , const char * mpoint , const char * dst )
484
+ {
485
+ char * src_path_dir , * src_path_base ;
486
+ char src_path [PATH_MAX ], dst_path [PATH_MAX ];
487
+
488
+ if (cptofs ) {
489
+ snprintf (src_path , sizeof (src_path ), "%s" , src );
490
+ snprintf (dst_path , sizeof (dst_path ), "%s/%s" , mpoint , dst );
491
+ } else {
492
+ snprintf (src_path , sizeof (src_path ), "%s/%s" , mpoint , src );
493
+ snprintf (dst_path , sizeof (dst_path ), "%s" , dst );
494
+ }
495
+
496
+ src_path_dir = dirname (strdup (src_path ));
497
+ src_path_base = basename (strdup (src_path ));
498
+
499
+ return searchdir (src_path_dir , dst_path , src_path_base );
500
+ }
501
+
488
502
int main (int argc , char * * argv )
489
503
{
490
504
struct lkl_disk disk ;
491
505
long ret ;
492
- char mpoint [ 32 ], src_path [ PATH_MAX ], dst_path [ PATH_MAX ] ;
493
- char * src_path_dir , * src_path_base ;
506
+ int i ;
507
+ char mpoint [ 32 ] ;
494
508
unsigned int disk_id ;
495
509
496
510
if (strstr (argv [0 ], "cptofs" )) {
@@ -531,21 +545,12 @@ int main(int argc, char **argv)
531
545
goto out_close ;
532
546
}
533
547
534
- if (cptofs ) {
535
- snprintf (src_path , sizeof (src_path ), "%s" , cla .src_path );
536
- snprintf (dst_path , sizeof (dst_path ), "%s/%s" , mpoint ,
537
- cla .dst_path );
538
- } else {
539
- snprintf (src_path , sizeof (src_path ), "%s/%s" , mpoint ,
540
- cla .src_path );
541
- snprintf (dst_path , sizeof (dst_path ), "%s" , cla .dst_path );
548
+ for (i = 0 ; i < cla .npaths - 1 ; i ++ ) {
549
+ ret = copy_one (cla .paths [i ], mpoint , cla .paths [cla .npaths - 1 ]);
550
+ if (ret )
551
+ break ;
542
552
}
543
553
544
- src_path_dir = dirname (strdup (src_path ));
545
- src_path_base = basename (strdup (src_path ));
546
-
547
- ret = searchdir (src_path_dir , dst_path , src_path_base );
548
-
549
554
ret = lkl_umount_dev (disk_id , cla .part , 0 , 1000 );
550
555
551
556
out_close :
0 commit comments