mirror of
https://github.com/upa/mscp.git
synced 2026-02-13 16:44:43 +08:00
implement fill_file
This commit is contained in:
111
src/main.c
111
src/main.c
@@ -3,14 +3,25 @@
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <list.h>
|
||||
#include <util.h>
|
||||
#include <ssh.h>
|
||||
#include <file.h>
|
||||
#include <platform.h>
|
||||
|
||||
int verbose = 0; /* util.h */
|
||||
|
||||
#define DEFAULT_MIN_CHUNK_SZ (64 << 20) /* 64MB */
|
||||
|
||||
struct sscp {
|
||||
char *host; /* remote host (and username) */
|
||||
sftp_session ctrl; /* control sftp session */
|
||||
|
||||
struct list_head file_list;
|
||||
char *target;
|
||||
bool target_is_remote;
|
||||
};
|
||||
|
||||
void usage(bool print_help) {
|
||||
printf("sscp: super scp, copy files over multiple ssh connections\n"
|
||||
"\n"
|
||||
@@ -22,8 +33,7 @@ void usage(bool print_help) {
|
||||
if (!print_help)
|
||||
return;
|
||||
|
||||
printf(" -r expand directory recusrively\n"
|
||||
" -n NR_CONNECTIONS max number of connections (default: # of cpu cores)\n"
|
||||
printf(" -n NR_CONNECTIONS max number of connections (default: # of cpu cores)\n"
|
||||
" -s MIN_CHUNKSIZE min chunk size (default: 64MB)\n"
|
||||
" -S MAX_CHUNKSIZE max chunk size (default: filesize / nr_conn)\n"
|
||||
"\n"
|
||||
@@ -43,22 +53,65 @@ void usage(bool print_help) {
|
||||
"\n");
|
||||
}
|
||||
|
||||
char *find_hostname(int ind, int argc, char **argv)
|
||||
{
|
||||
char *h, *hostnames[argc];
|
||||
int n, cnt = 0;
|
||||
|
||||
for (n = ind; n < argc; n++) {
|
||||
h = file_find_hostname(argv[n]);
|
||||
if (h)
|
||||
hostnames[cnt++] = h;
|
||||
}
|
||||
|
||||
if (cnt == 0)
|
||||
return NULL;
|
||||
|
||||
/* check all hostnames are identical */
|
||||
for (n = 1; n < cnt; n++) {
|
||||
int s1 = strlen(hostnames[n - 1]);
|
||||
int s2 = strlen(hostnames[n]);
|
||||
if (s1 != s2) {
|
||||
pr_err("different hostnames: %s and %s\n",
|
||||
hostnames[n - 1], hostnames[n]);
|
||||
goto err_out;
|
||||
}
|
||||
if (strncmp(hostnames[n - 1], hostnames[n], s1) != 0) {
|
||||
pr_err("different hostnames: %s and %s\n",
|
||||
hostnames[n - 1], hostnames[n]);
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
|
||||
for (n = 1; n < cnt; n++) {
|
||||
free(hostnames[n]);
|
||||
}
|
||||
|
||||
return hostnames[0];
|
||||
|
||||
err_out:
|
||||
for (n = 0; n < cnt; n++) {
|
||||
free(hostnames[n]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct sscp sscp;
|
||||
struct ssh_opts opts;
|
||||
int nr_conn = nr_cpus();
|
||||
bool recursive = false;
|
||||
int min_chunk_sz = DEFAULT_MIN_CHUNK_SZ;
|
||||
int max_chunk_sz = 0;
|
||||
int ret = 0;
|
||||
char ch;
|
||||
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
memset(&sscp, 0, sizeof(sscp));
|
||||
INIT_LIST_HEAD(&sscp.file_list);
|
||||
|
||||
while ((ch = getopt(argc, argv, "r:n:s:S:l:p:i:c:Cvh")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "n:s:S:l:p:i:c:Cvh")) != -1) {
|
||||
switch (ch) {
|
||||
case 'r':
|
||||
recursive = true;
|
||||
break;
|
||||
case 'n':
|
||||
nr_conn = atoi(optarg);
|
||||
if (nr_conn < 1) {
|
||||
@@ -113,6 +166,7 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
case 'v':
|
||||
opts.debuglevel++;
|
||||
verbose++;
|
||||
break;
|
||||
case 'h':
|
||||
usage(true);
|
||||
@@ -129,13 +183,44 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("opts.port %s\n", opts.port);
|
||||
|
||||
int n;
|
||||
for (n = 0; n < argc; n++) {
|
||||
printf("%d %s\n", n, argv[n]);
|
||||
if (argc - optind < 2) {
|
||||
/* sscp needs at lease 2 (src and target) argument */
|
||||
usage(false);
|
||||
return 1;
|
||||
}
|
||||
printf("optind %d", optind);
|
||||
|
||||
sscp.target = argv[argc - 1];
|
||||
sscp.target_is_remote = file_has_hostname(sscp.target);
|
||||
|
||||
/* create control session */
|
||||
sscp.host = find_hostname(optind, argc, argv);
|
||||
if (!sscp.host) {
|
||||
pr_err("no remote host given\n");
|
||||
return 1;
|
||||
}
|
||||
sscp.ctrl = ssh_make_sftp_session(sscp.host, &opts);
|
||||
if (!sscp.ctrl)
|
||||
return 1;
|
||||
|
||||
/* check target is directory */
|
||||
ret = file_is_directory(sscp.target, sscp.target_is_remote ? sscp.ctrl : NULL);
|
||||
if (ret < 0)
|
||||
return 1;
|
||||
if (ret == 0) {
|
||||
pr_err("target must be directory\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = file_fill(sscp.ctrl, &sscp.file_list, &argv[optind], argc - optind - 1);
|
||||
if (ret < 0) {
|
||||
ssh_sftp_close(sscp.ctrl);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
file_dump(&sscp.file_list);
|
||||
#endif
|
||||
|
||||
ssh_sftp_close(sscp.ctrl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user