diff options
-rw-r--r-- | libftpconn/ftpcp.c | 316 | ||||
-rw-r--r-- | libftpconn/ftpdir.c | 308 |
2 files changed, 0 insertions, 624 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); -} diff --git a/libftpconn/ftpdir.c b/libftpconn/ftpdir.c deleted file mode 100644 index 36d15df0..00000000 --- a/libftpconn/ftpdir.c +++ /dev/null @@ -1,308 +0,0 @@ -#include <unistd.h> -#include <string.h> -#include <error.h> -#include <argp.h> -#include <time.h> -#include <netdb.h> - -#include <version.h> - -#include <ftpconn.h> - -#define COPY_SZ 65536 - -const char *argp_program_version = STANDARD_HURD_VERSION (ftpdir); - -static struct argp_option options[] = -{ - {"user", 'u', "USER",0, "User to login as on ftp server"}, - {"password", 'p', "PWD", 0, "USER's password"}, - {"account", 'a', "ACCT",0, "Account to login as"}, - {"separator",'S', "SEP", 0, "String to separate multiple listings"}, - {"prefix", 'P', "PFX", 0, "String to proceed listings; the first and second" - " occurances of %s are replace by HOST and DIR"}, - {"host", 'h', "HOST",0, "Use HOST as a default host"}, - {"debug", 'D', 0, 0, "Turn on debugging output for ftp connections"}, - {"intepret", 'i', 0, 0, "Parse the directory output"}, - {0, 0} -}; -static char *args_doc = "[([HOST:]DIR | HOST:)...]"; -static char *doc = "Get a directory listing over ftp from HOST:DIR." -"\vIf HOST is not supplied in an argument any default value set by --host is" -" used; if DIR is not supplied, the default directory of HOST is used." -"\nIf multiple DIRs are supplied on the command line, each listing is" -" prefixed by a newline (or SEP) and a line containing HOST:DIR: (or PFX)."; - -/* 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); -} - -struct ftpdir_host -{ - char *name; - struct ftp_conn_params params; - struct ftp_conn *conn; - struct ftpdir_host *next; -}; - -/* Return an ftp connection for the host NAME using PARAMS, and add an entry - for it to *HOSTS. If a connection already exists in HOSTS, it is returned - instead of making a new one. If an error occurrs, a message is printed and - 0 is returned. */ -static struct ftpdir_host * -get_host_conn (char *name, struct ftp_conn_params *params, - struct ftpdir_host **hosts) -{ - error_t err; - struct ftpdir_host *h; - struct hostent *he; - - for (h = *hosts; h; h = h->next) - if (strcmp (h->name, name) == 0) - return h; - - he = gethostbyname (name); - if (! he) - { - error (0, 0, "%s: %s", name, hstrerror (h_errno)); - return 0; - } - - for (h = *hosts; h; h = h->next) - if (he->h_addrtype == h->params.addr_type - && he->h_length == h->params.addr_len - && bcmp (he->h_addr_list[0], h->params.addr, he->h_length) == 0) - return h; - - h = malloc (sizeof (struct ftpdir_host)); - if (! h) - { - error (0, ENOMEM, "%s", name); - return 0; - } - - h->params = *params; - h->params.addr = malloc (he->h_length); - h->name = strdup (he->h_name); - - if (!h->name || !h->params.addr) - err = ENOMEM; - else - { - bcopy (he->h_addr_list[0], h->params.addr, he->h_length); - h->params.addr_len = he->h_length; - h->params.addr_type = he->h_addrtype; - err = ftp_conn_create (&h->params, &conn_hooks, &h->conn); - } - - if (err) - { - error (0, err, "%s", he->h_name); - if (h->name) - free (h->name); - if (h->params.addr) - free (h->params.addr); - free (h); - return 0; - } - - h->next = *hosts; - *hosts = h; - - return h; -} - -static int -ftpdir (char *dir, struct ftpdir_host *host) -{ - int data; - int rd; - error_t err; - static void *copy_buf = 0; - struct ftp_conn *conn = host->conn; - char *host_name = host->name; - - err = ftp_conn_start_dir (conn, dir, &data); - if (err) - { - error (0, err, "%s:%s", host_name, dir); - return err; - } - - if (! copy_buf) - { - copy_buf = valloc (COPY_SZ); - if (! copy_buf) - error (12, ENOMEM, "Cannot allocate copy buffer"); - } - - while ((rd = read (data, copy_buf, COPY_SZ)) > 0) - do - { - int wr = write (1, copy_buf, rd); - if (wr < 0) - error (13, errno, "stdout"); - rd -= wr; - } - while (rd > 0); - if (rd != 0) - { - error (0, errno, "%s:%s", host_name, dir); - return errno; - } - - close (data); - - err = ftp_conn_finish_transfer (conn); - if (err) - { - error (0, err, "%s:%s", host_name, dir); - return err; - } - - return 0; -} - -static error_t -pdirent (const char *name, const struct stat *st, const char *symlink_target, - void *hook) -{ - char timebuf[20]; - strftime (timebuf, sizeof timebuf, "%Y-%m-%d %H:%M", localtime (&st->st_mtime)); - printf ("%6o %2d %5d %5d %6ld %s %s\n", - st->st_mode, st->st_nlink, st->st_uid, st->st_gid, st->st_size, - timebuf, name); - if (symlink_target) - printf (" -> %s\n", - symlink_target); - return 0; -} - -static error_t -ftpdir2 (char *dir, struct ftpdir_host *host) -{ - error_t err = ftp_conn_get_stats (host->conn, dir, 1, pdirent, 0); - if (err == ENOTDIR) - err = ftp_conn_get_stats (host->conn, dir, 0, pdirent, 0); - if (err) - error (0, err, "%s:%s", host->name, dir); - return err; -} - -int -main (int argc, char **argv) -{ - struct ftpdir_host *hosts = 0; - char *default_host = 0; - int interpret = 0; - struct ftp_conn_params params = { 0 }; - char *sep = "\n"; - char *pfx = "%s:%s:\n"; - int use_pfx = 0; - int errs = 0; - - /* Parse our options... */ - error_t parse_opt (int key, char *arg, struct argp_state *state) - { - switch (key) - { - case ARGP_KEY_ARG: - { - char *host, *dir; - - if (state->next < state->argc) - use_pfx = 1; /* Multiple arguments. */ - - dir = index (arg, ':'); - if (dir) - { - host = arg; - *dir++ = '\0'; - if (*host == '\0') - /* An argument of `:' */ - host = default_host; - } - else - { - host = default_host; - dir = arg; - } - - if (host) - { - struct ftpdir_host *h = get_host_conn (host, ¶ms, &hosts); - if (h) - { - if (state->arg_num > 0) - fputs (sep, stdout); - if (use_pfx) - printf (pfx, h->name, dir); - if (interpret) - errs |= ftpdir2 (dir, h); - else - errs |= ftpdir (dir, h); - } - errs = 1; - } - else - { - error (0, 0, "%s: No default host", arg); - errs = 1; - } - } - break; - - case ARGP_KEY_NO_ARGS: - if (default_host) - { - struct ftpdir_host *h = - get_host_conn (default_host, ¶ms, &hosts); - if (h) - errs |= ftpdir (0, h); - } - else - { - error (0, 0, "No default host"); - errs = 1; - } - break; - - return EINVAL; - - case 'u': params.user = arg; break; - case 'p': params.pass = arg; break; - case 'a': params.acct = arg; break; - case 'h': default_host = arg; break; - case 'D': conn_hooks.cntl_debug = cntl_debug; break; - case 'P': pfx = arg; use_pfx = 1; break; - case 'S': sep = arg; break; - case 'i': interpret = 1; 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); - - if (errs) - exit (10); - else - exit (0); -} |