summaryrefslogtreecommitdiff
path: root/libftpconn/ftpcp.c
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1997-06-04 18:21:19 +0000
committerMiles Bader <miles@gnu.org>1997-06-04 18:21:19 +0000
commit178b779a967a2ffd93fa649ee0cbaba5b1391be4 (patch)
tree11341df6903195718db42ca8208a2737e4bd977e /libftpconn/ftpcp.c
parent78ab51858d077a2d1594965aec14fb4e66d75f45 (diff)
Moved to ../utils
Diffstat (limited to 'libftpconn/ftpcp.c')
-rw-r--r--libftpconn/ftpcp.c316
1 files changed, 0 insertions, 316 deletions
diff --git a/libftpconn/ftpcp.c b/libftpconn/ftpcp.c
deleted file mode 100644
index 03bd3d57..00000000
--- a/libftpconn/ftpcp.c
+++ /dev/null
@@ -1,316 +0,0 @@
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <error.h>
-#include <argp.h>
-#include <netdb.h>
-#include <fcntl.h>
-
-#include <version.h>
-
-#include <ftpconn.h>
-
-#define COPY_SZ 65536
-
-const char *argp_program_version = STANDARD_HURD_VERSION (ftpcp);
-
-#define OPT_SRC_U -3
-#define OPT_SRC_A -4
-#define OPT_SRC_P -5
-#define OPT_DST_U -6
-#define OPT_DST_A -7
-#define OPT_DST_P -8
-
-
-static struct argp_option options[] =
-{
- {"user", 'u', "USER",0, "User to login as on both ftp servers"},
- {"password", 'p', "PWD", 0, "USER's password"},
- {"account", 'a', "ACCT",0, "Account to login as"},
- {"src-user", OPT_SRC_U, "USER",0, "User to login as on the src ftp server"},
- {"src-password",OPT_SRC_P, "PWD", 0, "The src USER's password"},
- {"src-account", OPT_SRC_A, "ACCT",0, "Account to login as on the source server"},
- {"dst-user", OPT_DST_U, "USER",0, "User to login as on the dst ftp server"},
- {"dst-password",OPT_DST_P, "PWD", 0, "The dst USER's password"},
- {"dst-account", OPT_DST_A, "ACCT",0, "Account to login as on the source server"},
- {"debug", 'D', 0, 0, "Turn on debugging output for ftp connections"},
- {0, 0}
-};
-static char *args_doc = "SRC [DST]";
-static char *doc = "Copy file SRC over ftp to DST."
-"\vBoth SRC and DST may have the form HOST:FILE, FILE, or -, where - is"
-" standard input for SRC or standard output for DST, and FILE is a local"
-" file. DST may be a directory, in which case the basename of SRC is"
-" appended to make the actual destination filename.";
-
-/* customization hooks. */
-static struct ftp_conn_hooks conn_hooks = { 0 };
-
-static void
-cntl_debug (struct ftp_conn *conn, int type, const char *txt)
-{
- char *type_str;
-
- switch (type)
- {
- case FTP_CONN_CNTL_DEBUG_CMD: type_str = "."; break;
- case FTP_CONN_CNTL_DEBUG_REPLY: type_str = "="; break;
- default: type_str = "?"; break;
- }
-
- fprintf (stderr, "%s%s\n", type_str, txt);
-}
-
-/* Return an ftp connection for the host NAME using PARAMS. If an error
- occurrs, a message is printed the program exits. If CNAME is non-zero,
- the host's canonical name, in mallocated storage, is returned in it. */
-struct ftp_conn *
-get_host_conn (char *name, struct ftp_conn_params *params, char **cname)
-{
- error_t err;
- struct hostent *he;
- struct ftp_conn *conn;
-
- he = gethostbyname (name);
- if (! he)
- error (10, 0, "%s: %s", name, hstrerror (h_errno));
-
- params->addr = malloc (he->h_length);
- if (! params->addr)
- error (11, ENOMEM, "%s", name);
-
- bcopy (he->h_addr_list[0], params->addr, he->h_length);
- params->addr_len = he->h_length;
- params->addr_type = he->h_addrtype;
-
- err = ftp_conn_create (params, &conn_hooks, &conn);
- if (err)
- error (12, err, "%s", he->h_name);
-
- if (cname)
- *cname = strdup (he->h_name);
-
- return conn;
-}
-
-static void
-cp (int src, const char *src_name, int dst, const char *dst_name)
-{
- ssize_t rd;
- static void *copy_buf = 0;
-
- if (! copy_buf)
- {
- copy_buf = valloc (COPY_SZ);
- if (! copy_buf)
- error (13, ENOMEM, "Cannot allocate copy buffer");
- }
-
- while ((rd = read (src, copy_buf, COPY_SZ)) > 0)
- do
- {
- int wr = write (dst, copy_buf, rd);
- if (wr < 0)
- error (14, errno, "%s", dst_name);
- rd -= wr;
- }
- while (rd > 0);
-
- if (rd != 0)
- error (15, errno, "%s", src_name);
-}
-
-struct epoint
-{
- char *name; /* Name, of the form HOST:FILE, FILE, or -. */
- char *file; /* If remote, the FILE portion, or 0. */
- int fd; /* A file descriptor to use. */
- struct ftp_conn *conn; /* An ftp connection to use. */
- struct ftp_conn_params params;
-};
-
-static void
-econnect (struct epoint *e, struct ftp_conn_params *def_params)
-{
- char *rmt;
-
- if (! e->name)
- e->name = "-";
-
- rmt = strchr (e->name, ':');
- if (rmt)
- {
- error_t err;
-
- *rmt++ = 0;
-
- if (! e->params.user)
- e->params.user = def_params->user;
- if (! e->params.pass)
- e->params.pass = def_params->pass;
- if (! e->params.acct)
- e->params.acct = def_params->acct;
-
- e->conn = get_host_conn (e->name, &e->params, &e->name);
- e->name = realloc (e->name, strlen (e->name) + 1 + strlen (rmt) + 1);
- if (! e->name)
- error (22, ENOMEM, "Cannot allocate name storage");
-
- err = ftp_conn_set_type (e->conn, "I");
- if (err)
- error (23, err, "%s: Cannot set connection type to binary",
- e->name);
-
- strcat (e->name, ":");
- strcat (e->name, rmt);
-
- e->file = rmt;
- }
- else if (e->params.user || e->params.pass || e->params.acct)
- error (20, 0,
- "%s: Ftp login parameter specified for a local endpoint (%s,%s,%s)",
- e->name, e->params.user, e->params.pass, e->params.acct);
- else
- e->file = strdup (e->name);
-}
-
-static error_t
-eopen_wr (struct epoint *e, int *fd)
-{
- if (e->conn)
- return ftp_conn_start_store (e->conn, e->file, fd);
- else if (strcmp (e->name, "-") == 0)
- *fd = 1;
- else
- {
- *fd = open (e->name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
- if (*fd < 0)
- return errno;
- }
- return 0;
-}
-
-static error_t
-eopen_rd (struct epoint *e, int *fd)
-{
- if (e->conn)
- return ftp_conn_start_retrieve (e->conn, e->file, fd);
- else if (strcmp (e->name, "-") == 0)
- *fd = 0;
- else
- {
- *fd = open (e->name, O_RDONLY, 0666);
- if (*fd < 0)
- return errno;
- }
- return 0;
-}
-
-static void
-efinish (struct epoint *e)
-{
- if (e->conn)
- {
- error_t err = ftp_conn_finish_transfer (e->conn);
- if (err)
- error (31, err, "%s", e->name);
- }
-}
-
-int
-main (int argc, char **argv)
-{
- error_t err;
- struct epoint rd = { 0 }, wr = { 0 };
- struct ftp_conn_params def_params = { 0 }; /* default params */
-
- /* Parse our options... */
- error_t parse_opt (int key, char *arg, struct argp_state *state)
- {
- switch (key)
- {
- case ARGP_KEY_ARG:
- switch (state->arg_num)
- {
- case 0: rd.name = arg; break;
- case 1: wr.name = arg; break;
- default: return ARGP_ERR_UNKNOWN;
- }
- break;
- case ARGP_KEY_NO_ARGS:
- argp_usage (state);
-
- case 'u': def_params.user = arg; break;
- case 'p': def_params.pass = arg; break;
- case 'a': def_params.acct = arg; break;
-
- case OPT_SRC_U: rd.params.user = arg; break;
- case OPT_SRC_P: rd.params.pass = arg; break;
- case OPT_SRC_A: rd.params.acct = arg; break;
-
- case OPT_DST_U: wr.params.user = arg; break;
- case OPT_DST_P: wr.params.pass = arg; break;
- case OPT_DST_A: wr.params.acct = arg; break;
-
- case 'D': conn_hooks.cntl_debug = cntl_debug; break;
-
- default:
- return ARGP_ERR_UNKNOWN;
- }
- return 0;
- }
- struct argp argp = {options, parse_opt, args_doc, doc};
-
- argp_parse (&argp, argc, argv, 0, 0, 0);
-
- econnect (&rd, &def_params);
- econnect (&wr, &def_params);
-
- if (rd.conn && wr.conn)
- {
- err = ftp_conn_rmt_copy (rd.conn, rd.file, wr.conn, wr.file);
- if (err)
- error (30, err, "Remote copy");
- }
- else
- {
- int rd_fd, wr_fd;
-
- err = eopen_rd (&rd, &rd_fd);
- if (err)
- error (31, err, "%s", rd.name);
-
- err = eopen_wr (&wr, &wr_fd);
- if (err == EISDIR)
- /* The destination name is a directory; try again with the source
- basename appended. */
- {
- char *bname = basename (rd.file);
- size_t bname_len = strlen (bname);
- char *dir = wr.file;
- char *name = malloc (strlen (dir) + 1 + bname_len + 1);
-
- if (! name)
- error (99, ENOMEM, "%s", dir);
-
- strcpy (name, dir);
- strcat (name, "/");
- strcat (name, bname);
- wr.file = name;
-
- err = eopen_wr (&wr, &wr_fd);
- }
- if (err)
- error (32, err, "%s", wr.name);
-
- cp (rd_fd, rd.name, wr_fd, wr.name);
-
- close (rd_fd);
- close (wr_fd);
-
- efinish (&rd);
- efinish (&wr);
- }
-
- exit (0);
-}