diff options
Diffstat (limited to 'libftpconn/ftpdir.c')
-rw-r--r-- | libftpconn/ftpdir.c | 308 |
1 files changed, 0 insertions, 308 deletions
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); -} |