コード例 #1
0
ファイル: commands.c プロジェクト: Celelibi/yafc
void cmd_cat(int argc, char **argv)
{
	int i;
	struct option longopts[] = {
		{"type", required_argument, 0, 't'},
		{"help", no_argument, 0, 'h'},
		{0, 0, 0, 0}
	};
	int c;
	transfer_mode_t mode = tmAscii;

	optind = 0;
	while((c = getopt_long(argc, argv, "t:h", longopts, 0)) != EOF) {
		switch(c) {
		case 't':
			if(strncmp(optarg, "ascii", strlen(optarg)) == 0)
				mode = tmAscii;
			else if(strncmp(optarg, "binary", strlen(optarg)) == 0)
				mode = tmBinary;
			else {
				fprintf(stderr,
						_("Invalid option argument --type=%s\n"), optarg);
				return;
			}
			break;
		case 'h':
      show_help(_("Print file(s) on standard output."), "cat [options] <file>...",
					_("  -t, --type=TYPE    set transfer TYPE to ascii or binary\n"));
			return;
		case '?':
			optind = -1;
			return;
		}
	}

	minargs(optind);
	need_connected();
	need_loggedin();

	for(i = optind; i < argc; i++) {
		listitem *gli;
		list *gl = rglob_create();
		stripslash(argv[i]);
		if(rglob_glob(gl, argv[i], true, false, 0) == -1)
			fprintf(stderr, _("%s: no matches found\n"), argv[i]);
		for(gli = gl->first; gli; gli=gli->next) {
			rfile *rf = (rfile *)gli->data;
			const char *fn = base_name_ptr(rf->path);
			if(strcmp(fn, ".") != 0 && strcmp(fn, "..") != 0) {
				ftp_receive(rf->path, stdout, mode, 0);
				fflush(stdout);
			}
		}
		rglob_destroy(gl);
	}
}
コード例 #2
0
ファイル: ssh_cmd.c プロジェクト: wmene/yafc-1.1.2
int ssh_send(const char *path, FILE *fp, putmode_t how,
			 transfer_mode_t mode, ftp_transfer_func hookf)
{
	int r;
	long offset = ftp->restart_offset;
	char *p;

	reset_transfer_info();
	ftp->ti.size = ftp->ti.restart_size = offset;
	ftp->restart_offset = 0L;

	ftp->ti.transfer_is_put = true;

	if(how == putUnique) {
		ftp_err("Unique put with SSH not implemented yet\n");
		return -1;
#if 0
		/* try to figure out remote filename */
		char *e = strstr(ftp->reply, " for ");
		if(e) {
			int l;
			e += 5;
			l = strlen(e);
			if(l) {
				free(ftp->ti.local_name);
				if(*e == '\'')
					ftp->ti.local_name = xstrndup(e+1, l-3);
				else
					ftp->ti.local_name = xstrndup(e, l-1);
				ftp_trace("parsed unique filename as '%s'\n",
						  ftp->ti.local_name);
			}
		}
#endif
	}

	p = ftp_path_absolute(path);
	stripslash(p);

	ftp_cache_flush_mark_for(p);

	if(how == putAppend) {
		ftp_set_tmp_verbosity(vbNone);
		offset = ftp_filesize(p);
	}

	r = ssh_send_binary(p, fp, hookf, offset);
	free(p);

	transfer_finished();

	return 0;
}
コード例 #3
0
ファイル: ftp.c プロジェクト: casualuser/yafc
rdirectory *ftp_get_directory(const char *path)
{
    rdirectory *rdir;
    char *ap;

    ap = ftp_path_absolute(path);
    stripslash(ap);

    rdir = ftp_cache_get_directory(ap);
    if(!rdir)
        rdir = ftp_read_directory(ap);
    free(ap);
    return rdir;
}
コード例 #4
0
ファイル: ssh_cmd.c プロジェクト: casualuser/yafc
int ssh_rename(const char *oldname, const char *newname)
{
  char* on = ftp_path_absolute(oldname);
  char* nn = ftp_path_absolute(newname);
  stripslash(on);
  stripslash(nn);

  int rc = sftp_rename(ftp->sftp_session, on, nn);
  if (rc != SSH_OK)
  {
    ftp_err(_("Couldn't rename file '%s' to '%s': %s\n"),
        on, nn, ssh_get_error(ftp->session));
    free(on);
    free(nn);
    return -1;
  }

  ftp_cache_flush_mark_for(on);
  ftp_cache_flush_mark_for(nn);
  free(on);
  free(nn);
  return 0;
}
コード例 #5
0
ファイル: ssh_cmd.c プロジェクト: wmene/yafc-1.1.2
int ssh_rename(const char *oldname, const char *newname)
{
	Buffer msg;
	u_int status, id;
	char *on, *nn;

	buffer_init(&msg);

	on = ftp_path_absolute(oldname);
	nn = ftp_path_absolute(newname);
	stripslash(on);
	stripslash(nn);

	/* Send rename request */
	id = ftp->ssh_id++;
	buffer_put_char(&msg, SSH2_FXP_RENAME);
	buffer_put_int(&msg, id);
	buffer_put_cstring(&msg, on);
	buffer_put_cstring(&msg, nn);
	ssh_cmd( &msg);
	buffer_free(&msg);

	status = ssh_get_status(id);
	if(status != SSH2_FX_OK) {
		ftp_err("Couldn't rename file \"%s\" to \"%s\": %s\n",
				on, nn, fx2txt(status));
		free(on);
		free(nn);
		return -1;
	}

	ftp_cache_flush_mark_for(on);
	ftp_cache_flush_mark_for(nn);
	free(on);
	free(nn);
	return 0;
}
コード例 #6
0
ファイル: ftp.c プロジェクト: casualuser/yafc
int ftp_chdir(const char *path)
{
#ifdef HAVE_LIBSSH
    if (ftp->session)
        return ssh_chdir(path);
#endif

    ftp_set_tmp_verbosity(vbCommand);
    ftp_cmd("CWD %s", path);
    if(ftp->code == ctComplete) {
        /* Now, try to be smart ;-)
         * Many ftp servers include the current directory in the CWD reply
         * try to parse it, so we don't need to issue a PWD command
         */

        if(strncasecmp(ftp->reply, "250 Changed to ", 15) == 0) {
            /* this is what Troll-ftpd replies: 250 Changed to /foo/bar */
            ftp_update_curdir_x(ftp->reply+15);
            ftp_trace("Parsed cwd '%s' from reply\n", ftp->curdir);
        } else if(strncasecmp(ftp->reply,
                              "250 OK. Current directory is ", 29) == 0) {
            /* PureFTPd responds: "250 OK. Current directory is /foo/bar */
            ftp_update_curdir_x(ftp->reply+29);
            ftp_trace("Parsed cwd '%s' from reply\n", ftp->curdir);
        } else if(strstr(ftp->reply, " is current directory") != 0) {
            /* WarFTPD answers: 250 "/foo/bar/" is current directory */
            char *edq;
            char *sdq = strchr(ftp->reply, '\"');
            if(sdq) {
                edq = strchr(sdq+1, '\"');
                if(edq) {
                    char *e = xstrndup(sdq+1, edq-sdq-1);
                    stripslash(e);
                    ftp_update_curdir_x(e);
                    free(e);
                    ftp_trace("Parsed cwd '%s' from reply\n", ftp->curdir);
                }
            }
        } else if(strncasecmp(ftp->reply,
                              "250 Directory changed to ", 25) == 0) {
            /* Serv-U FTP Server for WinSock */
            ftp_update_curdir_x(ftp->reply + 25);
            ftp_trace("Parsed cwd '%s' from reply\n", ftp->curdir);
        } else
            ftp_update_curdir();
        return 0;
    }
    return -1;
}
コード例 #7
0
ファイル: ltag.c プロジェクト: Celelibi/yafc
void cmd_ltag(int argc, char **argv)
{
	int i;
	int c;
	struct option longopts[] = {
		{"clear", no_argument, 0, 'c'},
		{"info", no_argument, 0, 'i'},
		{"list", no_argument, 0, 'l'},
		{"load", optional_argument, 0, 'L'},
		{"save", optional_argument, 0, 's'},
		{"help", no_argument, 0, 'h'},
		{0, 0, 0, 0}
	};

	optind = 0;
	while((c = getopt_long(argc, argv, "ciL::lhs::", longopts, 0)) != EOF) {
		switch(c) {
		  case 'c':
			list_clear(gvLocalTagList);
			return;
		  case 's':
			save_ltaglist(optarg);
			return;
		  case 'l':
			show_ltaglist();
			return;
		  case 'L':
			load_ltaglist(true, true, optarg);
			return;
		  case 'i':
			show_ltaglist_info();
			return;
		  case 'h':
			print_ltag_syntax();
			/* fall through */
		  case '?':
			return;
		}
	}

	minargs(1);

	for(i=1;i<argc;i++) {
		stripslash(argv[i]);
		lglob_glob(gvLocalTagList, argv[i], true, &lglob_exclude_dotdirs);
	}
}
コード例 #8
0
ファイル: ssh_cmd.c プロジェクト: casualuser/yafc
int ssh_mkdir_verb(const char *path, verbose_t verb)
{
  char* abspath = ftp_path_absolute(path);
  stripslash(abspath);

  int rc = sftp_mkdir(ftp->sftp_session, abspath, S_IRWXU);
  if (rc != SSH_OK && sftp_get_error(ftp->sftp_session) != SSH_FX_FILE_ALREADY_EXISTS)
  {
    ftp_err(_("Couldn't create directory: %s\n"), ssh_get_error(ftp->session));
    free(abspath);
    return rc;
  }

  ftp_cache_flush_mark_for(abspath);
  free(abspath);
  return 0;
}
コード例 #9
0
ファイル: ssh_cmd.c プロジェクト: casualuser/yafc
int ssh_chdir(const char *path)
{
  char* tmp = ftp_path_absolute(path);
  char *p = sftp_canonicalize_path(ftp->sftp_session, tmp);
  free(tmp);
  if (!p)
  {
    ftp_err("%s: %s\n", path, ssh_get_error(ftp->session));
    return -1;
  }

  bool isdir = false;

  /* First check if this file is cached and is a directory, else we
   * need to stat the file to see if it really is a directory
   */

  stripslash(p);
  isdir = (ftp_cache_get_directory(p) != 0);
  if(!isdir) {
    rfile *rf = ftp_cache_get_file(p);
    isdir = (rf && risdir(rf));
  }
  if (!isdir)
  {
    sftp_attributes attrib = sftp_stat(ftp->sftp_session, p);
    if (!attrib)
    {
      ftp_err(_("Couldn't stat directory: %s\n"), ssh_get_error(ftp->session));
      free(p);
      return -1;
    }
    if (!S_ISDIR(attrib->permissions)) {
      ftp_err(_("%s: not a directory\n"), p);
      sftp_attributes_free(attrib);
      free(p);
      return -1;
    }
    sftp_attributes_free(attrib);
  }
  ftp_update_curdir_x(p);
  free(p);

  return 0;
}
コード例 #10
0
ファイル: ssh_cmd.c プロジェクト: casualuser/yafc
int ssh_rmdir(const char *path)
{
  char* abspath = ftp_path_absolute(path);
  stripslash(abspath);

  int rc = sftp_rmdir(ftp->sftp_session, abspath);
  if (rc != SSH_OK && sftp_get_error(ftp->sftp_session) != SSH_FX_NO_SUCH_FILE)
  {
    ftp_err(_("Couldn't remove directory: %s\n"), ssh_get_error(ftp->session));
    free(abspath);
    return rc;
  }

  ftp_cache_flush_mark(abspath);
  ftp_cache_flush_mark_for(abspath);
  free(abspath);
  return 0;
}
コード例 #11
0
ファイル: ftp.c プロジェクト: casualuser/yafc
static int ftp_mkdir_verb(const char *path, verbose_t verb)
{
    char *p;

#ifdef HAVE_LIBSSH
    if(ftp->session)
        return ssh_mkdir_verb(path, verb);
#endif

    p = xstrdup(path);
    stripslash(p);

    ftp_set_tmp_verbosity(verb);
    ftp_cmd("MKD %s", p);
    if(ftp->code == ctComplete)
        ftp_cache_flush_mark_for(p);
    free(p);
    return ftp->code == ctComplete ? 0 : -1;
}
コード例 #12
0
ファイル: ftp.c プロジェクト: casualuser/yafc
int ftp_rmdir(const char *path)
{
    char *p;

#ifdef HAVE_LIBSSH
    if(ftp->session)
        return ssh_rmdir(path);
#endif

    p = xstrdup(path);
    stripslash(p);
    ftp_set_tmp_verbosity(vbError);
    ftp_cmd("RMD %s", p);
    if(ftp->code == ctComplete) {
        ftp_cache_flush_mark(p);
        ftp_cache_flush_mark_for(p);
    }
    free(p);
    return ftp->code == ctComplete ? 0 : -1;
}
コード例 #13
0
ファイル: dirutil.c プロジェクト: froggatt/edimax-br-6528n
/* ensure dirname exists, creating it if necessary. */
int make_valid_path(char *dir, mode_t mode) {
  struct stat st;
  char *tmp=NULL, *path = stripslash(strdup(dir));
  int retval;
  if (stat(path, &st) == 0) { /* file exists */
    if (S_ISDIR(st.st_mode)) { retval=1; goto end; }
    else { retval=0; goto end; } /* not a directory.  Oops. */
  }
  /* Directory doesn't exist.  Let's make it. */
  /*   Make parent first. */
  if (!make_valid_path(tmp = dirname(path), mode)) { retval=0; goto end; }
  /*   Now make this 'un. */
  if (mkdir(path, mode) < 0) { retval=0; goto end; }
  /* Success. */
  retval=1;

end:
  if (tmp!=NULL) free(tmp);
  if (path!=NULL) free(path);
  return retval;
}
コード例 #14
0
ファイル: ftp.c プロジェクト: casualuser/yafc
/* returns the rfile at PATH
 * if it's not in the cache, reads the directory
 * returns 0 if not found
 */
rfile *ftp_get_file(const char *path)
{
    rfile *f;
    char *ap;

    if(!path)
        return 0;

    ap = ftp_path_absolute(path);
    stripslash(ap);

    f = ftp_cache_get_file(ap);
    if(!f) {
        char *p = base_dir_xptr(ap);
        rdirectory *rdir = ftp_get_directory(p);
        free(p);
        if(rdir)
            f = rdir_get_file(rdir, base_name_ptr(ap));
    }
    free(ap);
    return f;
}
コード例 #15
0
ファイル: ssh_cmd.c プロジェクト: wmene/yafc-1.1.2
int ssh_rmdir(const char *path)
{
	char *p;
	u_int status, id;

	p = ftp_path_absolute(path);
	stripslash(p);

	id = ftp->ssh_id++;
	ssh_send_string_request(id, SSH2_FXP_RMDIR, p, strlen(p));

	status = ssh_get_status(id);
	if(status != SSH2_FX_OK) {
		ftp_err("Couldn't remove directory: %s\n", fx2txt(status));
		free(p);
		return -1;
	}
	ftp_cache_flush_mark(p);
	ftp_cache_flush_mark_for(p);
	free(p);

	return 0;
}
コード例 #16
0
ファイル: ssh_cmd.c プロジェクト: wmene/yafc-1.1.2
int ssh_chdir(const char *path)
{
	Attrib *aa;
	char *p = ftp_path_absolute(path);
	bool isdir = false;

	/* First check if this file is cached and is a directory, else we
	 * need to stat the file to see if it really is a directory
	 */

	stripslash(p);
	isdir = (ftp_cache_get_directory(p) != 0);
	if(!isdir) {
		rfile *rf = ftp_cache_get_file(p);
		isdir = (rf && risdir(rf));
	}
	if(!isdir) {
		if ((aa = ssh_stat(p)) == 0) {
			free(p);
			return -1;
		}
		if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
			ftp_err("Can't change directory: Can't check target");
			free(p);
			return -1;
		}
		if (!S_ISDIR(aa->perm)) {
			ftp_err("%s: not a directory\n", p);
			free(p);
			return -1;
		}
	}
	ftp_update_curdir_x(p);

	return 0;
}
コード例 #17
0
ファイル: ftp.c プロジェクト: casualuser/yafc
rdirectory *ftp_read_directory(const char *path)
{
    FILE *fp = 0;
    rdirectory *rdir;
    bool is_curdir = false;
    bool _failed = false;
    char *dir;
    bool is_mlsd = false;

#ifdef HAVE_LIBSSH
    if(ftp->session)
        return ssh_read_directory(path);
#endif

    dir = ftp_path_absolute(path);
    stripslash(dir);

    is_curdir = (strcmp(dir, ftp->curdir) == 0);

    if((fp = tmpfile()) == NULL) {	/* can't create a tmpfile */
	    ftp_err("Unable to create temp file: %s\n", strerror(errno));
            free(dir);
            return 0;
    }

    /* we do a "CWD" before the listing, because: we want a listing of
     *  the directory contents, not the directory itself, and some
     *  servers misunderstand this. If the target is a link to a
     *  directory, we have to do this.
     */
    if(!is_curdir) {
        ftp_cmd("CWD %s", dir);
        if(ftp->code != ctComplete)
            goto failed;
    }

    if(ftp->has_mlsd_command) {
        is_mlsd = true;
#if 0
        /* PureFTPd (1.0.11) doesn't recognize directory arguments
         * with spaces, not even quoted, it just chops the argument
         * string after the first space, duh... so we have to CWD to
         * the directory...
         */
        char *asdf;
        asprintf(&asdf, "%s/", dir);
        /* Hack to get around issue in PureFTPd (up to version 0.98.2):
         * doing a 'MLSD link-to-dir' on PureFTPd closes the control
         * connection, however, 'MLSD link-to-dir/' works fine.
         */
        _failed = (ftp_list("MLSD", asdf, fp) != 0);
        free(asdf);
#else
        _failed = (ftp_list("MLSD", 0, fp) != 0);
#endif
        if(_failed && ftp->code == ctError)
            ftp->has_mlsd_command = false;
    }
    if(!ftp->has_mlsd_command) {
        _failed = (ftp_list("LIST", 0, fp) != 0);
        is_mlsd = false;
    }

    if(!is_curdir)
        ftp_cmd("CWD %s", ftp->curdir);

    if(_failed)
        goto failed;

    rewind(fp);

    rdir = rdir_create();
    if(rdir_parse(rdir, fp, dir, is_mlsd) != 0) {
        rdir_destroy(rdir);
        goto failed;
    }

    fclose(fp);
    ftp_trace("added directory '%s' to cache\n", dir);
    list_additem(ftp->cache, rdir);
    free(dir);
    return rdir;

  failed: /* forgive me father, for I have goto'ed */
    if (fp)
	    fclose(fp);
    free(dir);
    return 0;
}
コード例 #18
0
ファイル: completion.c プロジェクト: rneatherway/yafc
static char *remote_completion_function(const char *text, int state)
{
    static int len;            /* length of unquoted */
    static char *dir = NULL;   /* any initial directory in text */
    static char *unquoted = NULL; /* the unquoted filename (or beginning of it) */
    static listitem *lip = NULL;
    static rdirectory *rdir = NULL; /* the cached remote directory */
    static char merge_fmt[] = "%s/%s";

    if (!ftp_loggedin())
        return 0;

    /* this is not really true, this is for local filename completion,
     * but it works here too (sort of), and it looks nicer, since
     * the whole path is not printed by readline, ie
     * only foo is printed and not /bar/fu/foo (if cwd == /bar/fu)
     * readline appends a class character (ie /,@,*) in _local_ filenames
     */
    rl_filename_completion_desired = 1;
#ifndef HAVE_LIBEDIT
    rl_filename_quoting_desired = 1;
#endif

    if (!state) {
        dir = base_dir_xptr(text);
        if (dir) {
            stripslash(dir);
            char* e = strchr(dir, 0);
            if (e[-1]=='\"')
                e[-1] = '\0';
            unquote(dir);
            if (strcmp(dir, "/") == 0)
                strlcpy(merge_fmt, "%s%s", sizeof(merge_fmt));
            else
                strlcpy(merge_fmt, "%s/%s", sizeof(merge_fmt));
        }
#ifndef HAVE_LIBEDIT
        if(gvWaitingDots) {
            rl_insert_text("..."); /* show dots while waiting, like ncftp */
            rl_redisplay();
        }
#endif

        char* ap = ftp_path_absolute(dir);
        rdir = ftp_cache_get_directory(ap);
        const bool dir_is_cached = (rdir != 0);
        if (!rdir)
            rdir = ftp_read_directory(ap);
        free(ap);

#ifndef HAVE_LIBEDIT
        if (gvWaitingDots)
            rl_do_undo(); /* remove the dots */
#endif

        if (!dir_is_cached && ftp_get_verbosity() >= vbCommand)
            rl_forced_update_display();

        if (!rdir) {
            free(dir);
            return 0;
        }
        unquoted = dequote_filename(base_name_ptr(text), 0);
        if (!unquoted)
            unquoted = (char *)xmalloc(1);
        len = strlen(unquoted);
        lip = rdir->files->first;
    }

    while (lip) {
        rfile* fp = (rfile *)lip->data;
        lip = lip->next;

        /* 0 = not dir, 1 = dir, 2 = link (maybe dir) */
        const int isdir = ftp_maybe_isdir(fp);
        if (remote_dir_only && isdir == 0)
            continue;

        const char* name = base_name_ptr(fp->path);
        /* skip dotdirs in completion */
        if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
            continue;

        if (strncmp(name, unquoted, len) == 0) {
            char *ret;
            if (dir)
            {
                if (asprintf(&ret, merge_fmt, dir, name) == -1)
                {
                    fprintf(stderr, _("Failed to allocate memory.\n"));
                    free(unquoted);
                    free(dir);
                    return NULL;
                }
            }
            else
                ret = xstrdup(name);
            if (isdir == 1) {
                rl_completion_append_character = '/';
            } else {
                rl_completion_append_character = ' ';
            }
            return ret;
        }
    }
    free(unquoted);
    free(dir);
    return NULL;
}
コード例 #19
0
ファイル: get.c プロジェクト: sebastinas/yafc
void cmd_get(int argc, char **argv)
{
    list *gl;
    int opt=GET_VERBOSE, c;
    char *logfile = 0;
    pid_t pid;
    struct group *grp;
    char *get_output = 0;
    int stat_thresh = gvStatsThreshold;
#ifdef HAVE_REGEX
    int ret;
    char get_rx_errbuf[129];
#endif
    struct option longopts[] = {
        {"append", no_argument, 0, 'a'},
        {"chmod", required_argument, 0, 'c'},
        {"chgrp", required_argument, 0, '2'},
        {"no-dereference", no_argument, 0, 'd'},
        {"delete-after", no_argument, 0, 'D'},
        {"dir-mask", required_argument, 0, '3'},
#ifdef HAVE_REGEX
        {"dir-rx-mask", required_argument, 0, '4'},
#endif
        {"interactive", no_argument, 0, 'i'},
        {"skip-empty", no_argument, 0, 'e'},
        {"force", no_argument, 0, 'f'},
        {"force-newer", no_argument, 0, 'F'},
        {"logfile", required_argument, 0, 'L'},
        {"mask", required_argument, 0, 'm'},
#ifdef HAVE_REGEX
        {"rx-mask", required_argument, 0, 'M'},
#endif
        {"newer", no_argument, 0, 'n'},
        {"nohup", no_argument, 0, 'H'},
        {"verbose", no_argument, 0, 'v'},
        {"preserve", no_argument, 0, 'p'},
        {"parents", no_argument, 0, 'P'},
        {"quiet", no_argument, 0, 'q'},
        {"recursive", no_argument, 0, 'r'},
        {"resume", no_argument, 0, 'R'},
        {"skip-existing", no_argument, 0, 's'},
        {"stats", optional_argument, 0, 'S'},
        {"tagged", no_argument, 0, 't'},
        {"type", required_argument, 0, '1'},
        {"unique", no_argument, 0, 'u'},
        {"output", required_argument, 0, 'o'},
        {"help", no_argument, 0, 'h'},
        {0, 0, 0, 0},
    };

    if(cmod) {
        mode_free(cmod);
        cmod = 0;
    }

    if(get_glob_mask) {
        free(get_glob_mask);
        get_glob_mask = 0;
    }
    if(get_dir_glob_mask) {
        free(get_dir_glob_mask);
        get_dir_glob_mask = 0;
    }
#ifdef HAVE_REGEX
    if(get_rx_mask_set) {
        regfree(&get_rx_mask);
        get_rx_mask_set = 0;
    }
    if(get_dir_rx_mask_set) {
        regfree(&get_dir_rx_mask);
        get_dir_rx_mask_set = 0;
    }
#endif

    get_skip_empty = false;

    optind = 0; /* force getopt() to re-initialize */
    while((c=getopt_long(argc, argv, "abHc:dDeio:fFL:tnpPvqrRsuT:m:M:",
                         longopts, 0)) != EOF)
    {
        switch(c) {
          case 'a':
            opt |= GET_APPEND;
            break;
          case 'c':
            cmod = mode_compile(optarg, MODE_MASK_ALL);
            if(cmod == NULL) {
                fprintf(stderr, _("Invalid mode for --chmod: %s\n"), optarg);
                return;
            }
            opt |= GET_CHMOD;
            break;
        case '2': /* --chgrp */
            grp = getgrnam(optarg);
            if(grp == 0) {
                fprintf(stderr, _("%s is not a valid group name\n"), optarg);
                return;
            }
            {
                int i;
                for(i=0; grp->gr_mem && grp->gr_mem[i]; i++) {
                    if(strcmp(gvUsername, grp->gr_mem[i]) == 0)
                        break;
                }
                if(!grp->gr_mem[i]) {
                    fprintf(stderr,
                            _("you are not a member of group %s\n"), optarg);
                    return;
                }
            }
            group_change = grp->gr_gid;
            opt |= GET_CHGRP;
            break;
          case 'D':
            opt |= GET_DELETE_AFTER;
            break;
          case 'd':
            opt |= GET_NO_DEREFERENCE;
            break;
           case 'e':
              opt |= GET_SKIP_EMPTY;
              get_skip_empty = true;
              break;
        case '3': /* --dir-mask=GLOB */
            free(get_dir_glob_mask);
            get_dir_glob_mask = xstrdup(optarg);
            unquote(get_dir_glob_mask);
            break;
#ifdef HAVE_REGEX
        case '4': /* --dir-rx-mask=REGEXP */
            if(get_dir_rx_mask_set) {
                regfree(&get_dir_rx_mask);
                get_dir_rx_mask_set = false;
            }
            unquote(optarg);
            ret = regcomp(&get_dir_rx_mask, optarg, REG_EXTENDED);
            if(ret != 0) {
                regerror(ret, &get_dir_rx_mask, get_rx_errbuf, sizeof(get_rx_errbuf) - 1);
                ftp_err(_("Regexp '%s' failed: %s\n"), optarg, get_rx_errbuf);
                return;
            } else
                get_dir_rx_mask_set = true;
            break;
#endif
          case 'i':
            opt |= GET_INTERACTIVE;
            break;
          case 'f':
            opt |= GET_FORCE;
            break;
          case 'F':
            opt |= GET_FORCE_NEWER;
            break;
        case 'm': /* --mask */
            free(get_glob_mask);
            get_glob_mask = xstrdup(optarg);
            unquote(get_glob_mask);
            break;
#ifdef HAVE_REGEX
        case 'M': /* --rx-mask */
            if(get_rx_mask_set) {
                regfree(&get_rx_mask);
                get_rx_mask_set = false;
            }
            unquote(optarg);
            ret = regcomp(&get_rx_mask, optarg, REG_EXTENDED);
            if(ret != 0) {
                regerror(ret, &get_rx_mask, get_rx_errbuf, sizeof(get_rx_errbuf) - 1);
                ftp_err(_("Regexp '%s' failed: %s\n"), optarg, get_rx_errbuf);
                return;
            } else
                get_rx_mask_set = true;
            break;
#endif
          case 'o':
            get_output = tilde_expand_home(optarg, gvLocalHomeDir);
            /*stripslash(get_output);*/
            unquote(get_output);
            break;
          case 'v':
            opt |= GET_VERBOSE;
            break;
          case 'p':
            opt |= GET_PRESERVE;
            break;
          case 'P':
            opt |= GET_PARENTS;
            break;
          case 'H':
            opt |= GET_NOHUP;
            break;
          case 'q':
            opt &= ~GET_VERBOSE;
            break;
          case 'r':
            opt |= GET_RECURSIVE;
            break;
          case 's':
            opt |= GET_SKIP_EXISTING;
            break;
          case 'S':
            stat_thresh = optarg ? atoi(optarg) : 0;
            break;
          case 'R':
            opt |= GET_RESUME;
            break;
          case '1':
            if(strncmp(optarg, "ascii", strlen(optarg)) == 0)
                opt |= GET_ASCII;
            else if(strncmp(optarg, "binary", strlen(optarg)) == 0)
                opt |= GET_BINARY;
            else {
                printf(_("Invalid option argument --type=%s\n"), optarg);
                return;
            }
            break;
          case 'u':
            opt |= GET_UNIQUE;
            break;
          case 'L':
              free(logfile);
              logfile = xstrdup(optarg);
              unquote(logfile);
              break;
          case 't':
            opt |= GET_TAGGED;
            break;
          case 'n':
            opt |= GET_NEWER;
            break;
          case 'h':
            print_get_syntax();
            return;
          case '?':
            return;
        }
    }
    if(optind>=argc && !test(opt, GET_TAGGED)) {
        minargs(optind);
        return;
    }

    need_connected();
    need_loggedin();

    gl = rglob_create();
    while(optind < argc) {
        stripslash(argv[optind]);
        if(rglob_glob(gl, argv[optind], true, true, get_exclude_func) == -1)
            fprintf(stderr, _("%s: no matches found\n"), argv[optind]);
        optind++;
    }
    if(list_numitem(gl) == 0 && !test(opt, GET_TAGGED)) {
        rglob_destroy(gl);
        return;
    }
    if(test(opt, GET_TAGGED)
       && (!ftp->taglist || list_numitem(ftp->taglist)==0))
    {
        printf(_("no tagged files\n"));
        if(list_numitem(gl) == 0) {
            rglob_destroy(gl);
            return;
        }
    }

    get_quit = false;
    get_batch = get_owbatch = get_delbatch = test(opt, GET_FORCE);
    if(test(opt, GET_FORCE))
        opt &= ~GET_INTERACTIVE;

    if(get_output && !test(opt, GET_RECURSIVE) && list_numitem(gl) +
       (test(opt, GET_TAGGED) ? list_numitem(ftp->taglist) : 0) == 1)
        {
            /* if the argument to --output ends with a slash, we assume the
             * user wants the destination to be a directory
             */
            char *e = strrchr(get_output, 0);
            if(e && e[-1] != '/')
                opt |= GET_OUTPUT_FILE;
        }

    stats_reset(gvStatsTransfer);

    gvInTransfer = true;
    gvInterrupted = false;

    if(test(opt, GET_NOHUP)) {
        int r = 0;
        pid = fork();

        if(pid == 0) {
            r = transfer_init_nohup(logfile);
            if(r != 0)
                exit(0);
        }

        if(r != 0)
            return;

        if(pid == 0) { /* child process */
            transfer_begin_nohup(argc, argv);

            if(!test(opt, GET_FORCE) && !test(opt, GET_RESUME))
                opt |= GET_UNIQUE;
            opt |= GET_FORCE;

            if(list_numitem(gl))
                getfiles(gl, opt, get_output);
            rglob_destroy(gl);
            if(ftp->taglist && test(opt, GET_TAGGED))
                getfiles(ftp->taglist, opt, get_output);
            free(get_output);

            transfer_end_nohup();
        }
        if(pid == -1) {
            perror("fork()");
            return;
        }
        /* parent process */
        sleep(1);
        printf("%d\n", pid);
        input_save_history();
        gvars_destroy();
        reset_xterm_title();
        exit(0);
    }

    if(list_numitem(gl))
        getfiles(gl, opt, get_output);
    rglob_destroy(gl);
    if(ftp->taglist && test(opt, GET_TAGGED))
        getfiles(ftp->taglist, opt, get_output);
    free(get_output);
    mode_free(cmod);
    cmod = 0;
    gvInTransfer = false;

    stats_display(gvStatsTransfer, stat_thresh);
}
コード例 #20
0
ファイル: put.c プロジェクト: wmene/yafc-1.1.2
/* store a local file on remote server */
void cmd_put(int argc, char **argv)
{
	int c, opt=PUT_VERBOSE;
	list *gl;
	char *put_output = 0;
	char *logfile = 0;
	pid_t pid;
#ifdef HAVE_REGEX
	int ret;
	char put_rx_errbuf[129];
#endif
	struct option longopts[] = {
		{"append", no_argument, 0, 'a'},
		{"delete-after", no_argument, 0, 'D'},
		{"dir-mask", required_argument, 0, '3'},
#ifdef HAVE_REGEX
		{"dir-rx-mask", required_argument, 0, '4'},
#endif
		{"skip-empty", no_argument, 0, 'e'},
		{"force", no_argument, 0, 'f'},
		{"nohup", no_argument, 0, 'H'},
		{"interactive", no_argument, 0, 'i'},
		{"logfile", required_argument, 0, 'L'},
		{"mask", required_argument, 0, 'm'},
#ifdef HAVE_REGEX
		{"rx-mask", required_argument, 0, 'M'},
#endif
		{"newer", no_argument, 0, 'n'},
		{"output", required_argument, 0, 'o'},
		{"preserve", no_argument, 0, 'p'},
		{"parents", no_argument, 0, 'P'},
		{"quiet", no_argument, 0, 'q'},
		{"recursive", no_argument, 0, 'r'},
		{"resume", no_argument, 0, 'R'},
		{"skip-existing", no_argument, 0, 's'},
		{"tagged", no_argument, 0, 't'},
		{"type", required_argument, 0, '1'},
		{"verbose", no_argument, 0, 'v'},
		{"unique", no_argument, 0, 'u'},
		{"help", no_argument, 0, 'h'},
		{0, 0, 0, 0},
	};

	if(put_glob_mask) {
		free(put_glob_mask);
		put_glob_mask = 0;
	}
	if(put_dir_glob_mask) {
		free(put_dir_glob_mask);
		put_dir_glob_mask = 0;
	}
#ifdef HAVE_REGEX
	if(put_rx_mask_set) {
		regfree(&put_rx_mask);
		put_rx_mask_set = 0;
	}
	if(put_dir_rx_mask_set) {
		regfree(&put_dir_rx_mask);
		put_dir_rx_mask_set = 0;
	}
#endif

	put_skip_empty = false;

	optind = 0; /* force getopt() to re-initialize */
	while((c = getopt_long(argc, argv,
						   "aDefHiL:no:pPqrRstvum:M:", longopts, 0)) != EOF)
	{
		switch(c) {
		case 'i':
			opt |= PUT_INTERACTIVE;
			break;
		case 'f':
			opt |= PUT_FORCE;
			break;
		   case 'e':
			  opt |= PUT_SKIP_EMPTY;
			  put_skip_empty = true;
			  break;
		case '3': /* --dir-mask=GLOB */
			free(put_dir_glob_mask);
			put_dir_glob_mask = xstrdup(optarg);
			unquote(put_dir_glob_mask);
			break;
#ifdef HAVE_REGEX
		case '4': /* --dir-rx-mask=REGEXP */
			if(put_dir_rx_mask_set) {
				regfree(&put_dir_rx_mask);
				put_dir_rx_mask_set = false;
			}
			unquote(optarg);
			ret = regcomp(&put_dir_rx_mask, optarg, REG_EXTENDED);
			if(ret != 0) {
				regerror(ret, &put_dir_rx_mask, put_rx_errbuf, 128);
				ftp_err(_("Regexp '%s' failed: %s\n"), optarg, put_rx_errbuf);
				return;
			} else
				put_dir_rx_mask_set = true;
			break;
#endif
		case 'o':
			put_output = tilde_expand_home(optarg, ftp->homedir);
			path_collapse(put_output);
			stripslash(put_output);
			break;
		case 'H':
			opt |= PUT_NOHUP;
			break;
		case 'L':
			free(logfile);
			logfile = xstrdup(optarg);
			unquote(logfile);
			break;
		case 'm': /* --mask */
			free(put_glob_mask);
			put_glob_mask = xstrdup(optarg);
			break;
#ifdef HAVE_REGEX
		case 'M': /* --rx-mask */
			if(put_rx_mask_set) {
				regfree(&put_rx_mask);
				put_rx_mask_set = false;
			}

			ret = regcomp(&put_rx_mask, optarg, REG_EXTENDED);
			if(ret != 0) {
				regerror(ret, &put_rx_mask, put_rx_errbuf, 128);
				ftp_err(_("Regexp '%s' failed: %s\n"), optind, put_rx_errbuf);
				return;
			} else
				put_rx_mask_set = true;
			break;
#endif
		  case 'n':
			opt |= PUT_NEWER;
			break;
		  case 'v':
			opt |= PUT_VERBOSE;
			break;
		  case 'q':
			opt &= ~PUT_VERBOSE;
			break;
		  case 'a':
			opt |= PUT_APPEND;
			break;
		  case 'D':
			opt |= PUT_DELETE_AFTER;
			break;
		  case 'u':
			opt |= PUT_UNIQUE;
			if(!ftp->has_stou_command) {
				fprintf(stderr, _("Remote doesn't support the STOU"
								  " (store unique) command\n"));
				return;
			}
			break;
		  case 'r':
			opt |= PUT_RECURSIVE;
			break;
		  case 's':
			opt |= PUT_SKIP_EXISTING;
			break;
		  case 'R':
			opt |= PUT_RESUME;
			break;
		  case 't':
			opt |= PUT_TAGGED;
			break;
		  case '1':
			if(strncmp(optarg, "ascii", strlen(optarg)) == 0)
				opt |= PUT_ASCII;
			else if(strncmp(optarg, "binary", strlen(optarg)) == 0)
				opt |= PUT_BINARY;
			else {
				printf(_("Invalid option argument --type=%s\n"), optarg);
				return;
			}
			break;
		  case 'p':
			opt |= PUT_PRESERVE;
			break;
		  case 'P':
			opt |= PUT_PARENTS;
			break;
		  case 'h':
			print_put_syntax();;
			return;
		  case '?':
			return;
		}
	}
	if(optind>=argc && !test(opt, PUT_TAGGED)) {
/*		fprintf(stderr, _("missing argument, try 'put --help'"*/
/*						  " for more information\n"));*/
		minargs(optind);
		return;
	}

	if(test(opt, PUT_APPEND) && test(opt, PUT_SKIP_EXISTING)) {
		printf("Can't use --append and --skip-existing simultaneously\n");
		return;
	}

	need_connected();
	need_loggedin();

	gl = lglob_create();
	while(optind < argc) {
		char *f;

		f = tilde_expand_home(argv[optind], gvLocalHomeDir);
		stripslash(f);
		lglob_glob(gl, f, true, put_exclude_func);
		optind++;
	}

	if(list_numitem(gl) == 0) {
		if(!test(opt, PUT_TAGGED)) {
			list_free(gl);
			return;
		} else if(list_numitem(gvLocalTagList) == 0) {
			printf(_("no tagged files\n"));
			list_free(gl);
			return;
		}
	}

	free(ftp->last_mkpath);
	ftp->last_mkpath = 0;

	put_quit = false;
	put_batch = put_owbatch = put_delbatch = test(opt, PUT_FORCE);
	if(test(opt, PUT_FORCE))
		opt &= ~PUT_INTERACTIVE;

	if(put_output && !test(opt, PUT_RECURSIVE) && list_numitem(gl) +
	   (test(opt, PUT_TAGGED) ? list_numitem(gvLocalTagList) : 0) == 1)
		{
			opt |= PUT_OUTPUT_FILE;
		}

	gvInTransfer = true;
	gvInterrupted = false;

	if(test(opt, PUT_NOHUP)) {
		int r = 0;
		pid = fork();

		if(pid == 0) {
			r = transfer_init_nohup(logfile);
			if(r != 0)
				exit(0);
		}

		if(r != 0)
			return;

		if(pid == 0) { /* child process */
			transfer_begin_nohup(argc, argv);

			if(!test(opt, PUT_FORCE) && !test(opt, PUT_RESUME))
				opt |= PUT_UNIQUE;
			opt |= PUT_FORCE;

			putfiles(gl, opt, put_output);
			list_free(gl);
			if(test(opt, PUT_TAGGED)) {
				putfiles(gvLocalTagList, opt, put_output);
				list_clear(gvLocalTagList);
			}
			free(put_output);

			transfer_end_nohup();
		}
		if(pid == -1) {
			perror("fork()");
			return;
		}
		/* parent process */
		sleep(1);
		printf("%d\n", pid);
		input_save_history();
		gvars_destroy();
		reset_xterm_title();
		exit(0);
	}

	putfiles(gl, opt, put_output);
	list_free(gl);
	if(test(opt, PUT_TAGGED)) {
		putfiles(gvLocalTagList, opt, put_output);
		list_clear(gvLocalTagList);
	}
	free(put_output);
	gvInTransfer = false;
}
コード例 #21
0
ファイル: ssh_cmd.c プロジェクト: casualuser/yafc
rdirectory *ssh_read_directory(const char *path)
{
  char *p = ftp_path_absolute(path);
  stripslash(p);

  sftp_dir dir = sftp_opendir(ftp->sftp_session, p);
  if (!dir)
  {
    free(p);
    return 0;
  }

  ftp_trace("*** start parsing directory listing ***\n");
  rdirectory* rdir = rdir_create();
  sftp_attributes attrib = NULL;
  while ((attrib = sftp_readdir(ftp->sftp_session, dir)) != NULL)
  {
    ftp_trace("%s\n", attrib->longname);

    rfile* rf = rfile_create();
    rf->perm = perm2string(attrib->permissions);

    rf->nhl = 0; // atoi(e);
    if (attrib->owner)
      rf->owner = xstrdup(attrib->owner);
    if (attrib->group)
      rf->group = xstrdup(attrib->group);

    if (asprintf(&rf->path, "%s/%s", p, attrib->name) == -1)
    {
      ftp_err(_("Failed to allocate memory.\n"));
      sftp_closedir(dir);
      free(p);
      rdir_destroy(rdir);
      rfile_destroy(rf);
    }
    rf->mtime = attrib->mtime;
    rf->date = time_to_string(rf->mtime);
    rf->size = attrib->size;
    rfile_parse_colors(rf);

    rf->link = NULL;
    if (rislink(rf) && ftp->ssh_version > 2)
      rf->link = sftp_readlink(ftp->sftp_session, rf->path);

    list_additem(rdir->files, (void *)rf);
    sftp_attributes_free(attrib);
  }
  ftp_trace("*** end parsing directory listing ***\n");

  if (!sftp_dir_eof(dir))
  {
    ftp_err(_("Couldn't list directory: %s\n"), ssh_get_error(ftp->session));
    sftp_closedir(dir);
    free(p);
    rdir_destroy(rdir);
    return NULL;
  }

  sftp_closedir(dir);
  rdir->path = p;
  ftp_trace("added directory '%s' to cache\n", p);
  list_additem(ftp->cache, rdir);

  return rdir;
}
コード例 #22
0
ファイル: fxp.c プロジェクト: Celelibi/yafc
void cmd_fxp(int argc, char **argv)
{
	list *gl;
	listitem *fxp_tmp = 0;
	char *logfile = 0;
	char *fxp_output = 0;
#ifdef HAVE_REGEX
	int ret;
	char fxp_rx_errbuf[129];
#endif
	int c, opt = FXP_VERBOSE;
	struct option longopts[] = {
		{"append", no_argument, 0, 'a'},
		{"delete-after", no_argument, 0, 'D'},
		{"dir-mask", required_argument, 0, '3'},
#ifdef HAVE_REGEX
		{"dir-rx-mask", required_argument, 0, '4'},
#endif
		{"force", no_argument, 0, 'f'},
    {"force-newer", no_argument, 0, 'F'},
		{"nohup", no_argument, 0, 'H'},
		{"interactive", no_argument, 0, 'i'},
		{"logfile", required_argument, 0, 'L'},
		{"mask", required_argument, 0, 'm'},
#ifdef HAVE_REGEX
		{"rx-mask", required_argument, 0, 'M'},
#endif
		{"newer", no_argument, 0, 'n'},
		{"output", required_argument, 0, 'o'},
		{"preserve", no_argument, 0, 'p'},
		{"parents", no_argument, 0, 'P'},
		{"quiet", no_argument, 0, 'q'},
		{"recursive", no_argument, 0, 'r'},
		{"resume", no_argument, 0, 'R'},
		{"skip-existing", no_argument, 0, 's'},
		{"tagged", no_argument, 0, 't'},
		{"target", required_argument, 0, 'T'},
		{"type", required_argument, 0, '1'},
		{"unique", no_argument, 0, 'u'},
		{"verbose", no_argument, 0, 'v'},
		{"help", no_argument, 0, 'h'},
		{0, 0, 0, 0}
	};

	if(fxp_glob_mask) {
		free(fxp_glob_mask);
		fxp_glob_mask = 0;
	}
	if(fxp_dir_glob_mask) {
		free(fxp_dir_glob_mask);
		fxp_dir_glob_mask = 0;
	}
#ifdef HAVE_REGEX
	if(fxp_rx_mask_set) {
		fxp_rx_mask_set = 0;
	}
	if(fxp_dir_rx_mask_set) {
		regfree(&fxp_dir_rx_mask);
		fxp_dir_rx_mask_set = 0;
	}
#endif

	if(list_numitem(gvFtpList) == 2) {
		fxp_tmp = gvFtpList->first;
		if(fxp_tmp->data == ftp)
			fxp_target = fxp_tmp->next->data;
		else
			fxp_target = fxp_tmp->data;
	} else
		fxp_target = 0;

	fxp_skip_empty = false;

	optind = 0; /* force getopt() to re-initialize */
	while((c=getopt_long(argc, argv, "aDefHiL:M:no:pPqrRstT:uvh",
						 longopts, 0)) != EOF)
		{
			switch(c) {
			case 'a': /* --append */
				opt |= FXP_APPEND;
				break;
			case 'D': /* --delete-after */
				opt |= FXP_DELETE_AFTER;
				break;
			case 'f': /* --force */
				opt |= FXP_FORCE;
				break;
      case 'F':
        opt |= FXP_FORCE_NEWER;
        break;
			   case 'e': /* --skip-empty */
				  opt |= FXP_SKIP_EMPTY;
				  fxp_skip_empty = true;
				  break;
			case '3': /* --dir-mask=GLOB */
				free(fxp_dir_glob_mask);
				fxp_dir_glob_mask = xstrdup(optarg);
				unquote(fxp_dir_glob_mask);
				break;
#ifdef HAVE_REGEX
			case '4': /* --dir-rx-mask=REGEXP */
				if(fxp_dir_rx_mask_set) {
					regfree(&fxp_dir_rx_mask);
					fxp_dir_rx_mask_set = false;
				}
				unquote(optarg);
				ret = regcomp(&fxp_dir_rx_mask, optarg, REG_EXTENDED);
				if(ret != 0) {
					regerror(ret, &fxp_dir_rx_mask, fxp_rx_errbuf, 128);
					ftp_err(_("Regexp '%s' failed: %s\n"),
							optarg, fxp_rx_errbuf);
					return;
				} else
					fxp_dir_rx_mask_set = true;
				break;
#endif
			case 'H': /* --nohup */
				opt |= FXP_NOHUP;
				break;
			case 'i': /* --interactive */
				opt |= FXP_INTERACTIVE;
				break;
			case 'L': /* --logfile=FILE */
				free(logfile);
				logfile = xstrdup(optarg);
				unquote(logfile);
				break;
			case 'm': /* --mask=GLOB */
				free(fxp_glob_mask);
				fxp_glob_mask = xstrdup(optarg);
				unquote(fxp_glob_mask);
				break;
#ifdef HAVE_REGEX
			case 'M': /* --rx-mask=REGEXP */
				if(fxp_rx_mask_set) {
					regfree(&fxp_rx_mask);
					fxp_rx_mask_set = false;
				}

				unquote(optarg);
				ret = regcomp(&fxp_rx_mask, optarg, REG_EXTENDED);
				if(ret != 0) {
					regerror(ret, &fxp_rx_mask, fxp_rx_errbuf, 128);
					ftp_err(_("Regexp '%s' failed: %s\n"),
							optarg, fxp_rx_errbuf);
					return;
				} else
					fxp_rx_mask_set = true;
				break;
#endif
			case 'n': /* --newer */
				opt |= FXP_NEWER;
				break;
			case 'o': /* --output=DIRECTORY */
				if(fxp_target == 0) {
					printf(_("FxP target not set, use --target=NAME"
							 " (as first option)\n"));
					return;
				}
				fxp_output = tilde_expand_home(optarg, fxp_target->homedir);
				stripslash(fxp_output);
				unquote(fxp_output);
				break;
			case 'p': /* --preserve */
				opt |= FXP_PRESERVE;
				break;
			case 'P': /* --parents */
				opt |= FXP_PARENTS;
				break;
			case 'q': /* --quiet */
				opt &= ~FXP_VERBOSE;
				break;
			case 'r': /* --recursive */
				opt |= FXP_RECURSIVE;
				break;
			case 'R': /* --resume */
				opt |= FXP_RESUME;
				break;
			case 's':
				opt |= FXP_SKIP_EXISTING;
				break;
			case 't': /* --tagged */
				opt |= FXP_TAGGED;
				break;
			case '1': /* --type=[ascii|binary] */
				if(strncmp(optarg, "ascii", strlen(optarg)) == 0)
					opt |= FXP_ASCII;
				else if(strncmp(optarg, "binary", strlen(optarg)) == 0)
					opt |= FXP_BINARY;
				else {
					printf(_("Invalid option argument --type=%s\n"), optarg);
					return;
				}
				break;
			case 'T': /* --target=HOST */
				fxp_tmp = ftplist_search(optarg);
				if(!fxp_tmp)
					return;
				fxp_target = (Ftp *)fxp_tmp->data;
				break;
			case 'u': /* --unique */
				opt |= FXP_UNIQUE;
				break;
			case 'v': /* --verbose */
				opt |= FXP_VERBOSE;
				break;
			case 'h': /* --help */
				print_fxp_syntax();
				return;
			case '?':
			default:
				return;
			}
		}

	if(optind >= argc && !test(opt, FXP_TAGGED)) {
		minargs(optind);
		return;
	}

	need_connected();
	need_loggedin();

	if(fxp_target == 0) {
		ftp_err(_("No target specified, try '%s --help'"
				  " for more information\n"), argv[0]);
		return;
	}

#ifdef HAVE_LIBSSH
	if(ftp->session || fxp_target->session) {
		ftp_err("FxP for SSH connections no implemented\n");
		return;
	}
#endif

	gl = rglob_create();
	while(optind < argc) {
		stripslash(argv[optind]);
		if(rglob_glob(gl, argv[optind], true, true, fxp_exclude_func) == -1)
			fprintf(stderr, _("%s: no matches found\n"), argv[optind]);
		optind++;
	}
	if(list_numitem(gl) == 0 && !test(opt, FXP_TAGGED)) {
		rglob_destroy(gl);
		return;
	}
	if(test(opt, FXP_TAGGED)
	   && (!ftp->taglist || list_numitem(ftp->taglist) == 0))
	{
		printf(_("no tagged files\n"));
		if(list_numitem(gl) == 0) {
			rglob_destroy(gl);
			return;
		}
	}

	fxp_quit = false;
	fxp_batch = fxp_owbatch = fxp_delbatch = test(opt, FXP_FORCE);
	if(test(opt, FXP_FORCE))
		opt &= ~FXP_INTERACTIVE;

	if(fxp_output && !test(opt, FXP_RECURSIVE) && list_numitem(gl) +
	   (test(opt, FXP_TAGGED) ? list_numitem(ftp->taglist) : 0) == 1)
		{
			opt |= FXP_OUTPUT_FILE;
		}

	gvInTransfer = true;
	gvInterrupted = false;

	if(test(opt, FXP_NOHUP)) {
		int r = 0;
		pid_t pid = fork();

		if(pid == 0) {
			r = transfer_init_nohup(logfile);
			if(r != 0)
				exit(0);
		}

		if(r != 0)
			return;

		if(pid == 0) { /* child process */
			transfer_begin_nohup(argc, argv);

			if(!test(opt, FXP_FORCE) && !test(opt, FXP_RESUME))
				opt |= FXP_UNIQUE;
			opt |= FXP_FORCE;

			if(list_numitem(gl))
				fxpfiles(gl, opt, fxp_output);
			rglob_destroy(gl);

			if(ftp->taglist && test(opt, FXP_TAGGED))
				fxpfiles(ftp->taglist, opt, fxp_output);

			free(fxp_output);

			transfer_end_nohup();
		}
		if(pid == -1) {
			perror("fork()");
			return;
		}
		/* parent process */
		sleep(1);
		printf("%d\n", pid);
		input_save_history();
		gvars_destroy();
		reset_xterm_title();
		exit(0);
	}

	if(list_numitem(gl))
		fxpfiles(gl, opt, fxp_output);
	rglob_destroy(gl);

	if(ftp->taglist && test(opt, FXP_TAGGED))
		fxpfiles(ftp->taglist, opt, fxp_output);

	free(fxp_output);
	gvInTransfer = false;
}
コード例 #23
0
ファイル: get.c プロジェクト: sebastinas/yafc
static void getfiles(list *gl, unsigned int opt, const char *output)
{
    listitem *li;
    rfile *fp, *lnfp;
    const char *opath, *ofile;
    char *link = 0;

    list_sort(gl, get_sort_func, false);

    li = gl->first;
    while(li && !get_quit) {
        fp = (rfile *)li->data;

        if(!ftp_connected())
            return;

        if(gvSighupReceived) {
            if(!test(opt, GET_RESUME))
                opt |= GET_UNIQUE;
            opt |= GET_FORCE;
        }

        opath = fp->path;
        ofile = base_name_ptr(opath);

        if(strcmp(ofile, ".")==0 || strcmp(ofile, "..")==0) {
            transfer_nextfile(gl, &li, true);
            continue;
        }

        if(test(opt, GET_INTERACTIVE) && !get_batch && !gvSighupReceived) {
						char* sp = shortpath(opath, 42, ftp->homedir);
            int a = ask(ASKYES|ASKNO|ASKCANCEL|ASKALL, ASKYES,
                        _("Get '%s'?"), sp);
						free(sp);
            if(a == ASKNO) {
                transfer_nextfile(gl, &li, true);
                continue;
            }
            if(a == ASKCANCEL) {
                get_quit = true;
                break;
            }
            if(a == ASKALL)
                get_batch = true;
            /* else a==ASKYES */
        }


        if(rislink(fp)) {
            link_to_link__duh:
            if(test(opt, GET_NO_DEREFERENCE)) {
                /* link the file, don't copy */
                const int r = getfile(fp, opt, output, ofile);
                transfer_nextfile(gl, &li, r == 0);
                continue;
            }

            {
                char *xcurdir = base_dir_xptr(opath);
                link = path_absolute(fp->link, xcurdir, ftp->homedir);
                stripslash(link);
                free(xcurdir);
                ftp_trace("found link: '%s' -> '%s'\n", opath, link);
            }

            lnfp = ftp_get_file(link);
            if(lnfp == 0) {
                /* couldn't dereference the link, try to RETR it */
                ftp_trace("unable to dereference link\n");
                const int r = getfile(fp, opt, output, ofile);
                transfer_nextfile(gl, &li, r == 0);
                continue;
            }

            if(strncmp(opath, lnfp->path, strlen(lnfp->path)) == 0) {
                ftp_trace("opath == '%s', lnfp->path == '%s'\n", opath,
                          lnfp->path);
								char* sp = shortpath(lnfp->path, 42, ftp->homedir);
                fprintf(stderr, _("%s: circular link -- skipping\n"), sp);
								free(sp);
                transfer_nextfile(gl, &li, true);
                continue;
            }

            fp = lnfp;

            if(rislink(fp))
                /* found a link pointing to another link
                 */
                /* forgive me father, for I have goto'ed */
                goto link_to_link__duh;
        }

        if(risdir(fp)) {
            if(test(opt, GET_RECURSIVE)) {
                char *recurs_output;
                char *recurs_mask;
                list *rgl;


                if((get_dir_glob_mask && fnmatch(get_dir_glob_mask,
                                                 base_name_ptr(fp->path),
                                                 FNM_EXTMATCH) == FNM_NOMATCH)
#ifdef HAVE_REGEX
                   || (get_dir_rx_mask_set && regexec(&get_dir_rx_mask,
                                                      base_name_ptr(fp->path),
                                                      0, 0, 0) == REG_NOMATCH)
#endif
                    )
                    {
                    } else {
                        char *q_recurs_mask;

                        bool success = true;
                        if(!test(opt, GET_PARENTS))
                            success = asprintf(&recurs_output, "%s/%s",
                                     output ? output : ".", ofile) != -1;
                        else
                            success = asprintf(&recurs_output, "%s",
                                     output ? output : ".") != -1;
                        if (!success)
                        {
                          fprintf(stderr, _("Failed to allocate memory.\n"));
                          transfer_nextfile(gl, &li, true);
			                    continue;
                        }
                        if (asprintf(&recurs_mask, "%s/*", opath) == -1)
                        {
                          free(recurs_output);
                          fprintf(stderr, _("Failed to allocate memory.\n"));
                          transfer_nextfile(gl, &li, true);
                          continue;
                        }
                        rgl = rglob_create();
                        q_recurs_mask = backslash_quote(recurs_mask);
                        rglob_glob(rgl, q_recurs_mask, true, true, get_exclude_func);
                        free(q_recurs_mask);
                        if(list_numitem(rgl) > 0)
                            getfiles(rgl, opt, recurs_output);
                        if(test(opt, GET_PRESERVE))
                            get_preserve_attribs(fp, recurs_output);
                        rglob_destroy(rgl);
                        free(recurs_output);
                    }
            } else if(test(opt, GET_VERBOSE)) {
							char* sp = shortpath(opath, 42, ftp->homedir);
							fprintf(stderr, _("%s: omitting directory\n"), sp);
							free(sp);
            }
            transfer_nextfile(gl, &li, true);
            continue;
        }
        if(!risreg(fp)) {
            if(test(opt, GET_VERBOSE)) {
							char* sp = shortpath(opath, 42, ftp->homedir);
                fprintf(stderr, _("%s: not a regular file\n"), sp);
								free(sp);
						}
            transfer_nextfile(gl, &li, true);
            continue;
        }
        const int r = getfile(fp, opt, output, ofile);

        transfer_nextfile(gl, &li, r == 0);

        if(gvInterrupted) {
            gvInterrupted = false;
            if(li && !get_quit && ftp_connected() && !gvSighupReceived)
            {
                int a = ask(ASKYES|ASKNO, ASKYES,
                            _("Continue transfer?"));
                if(a == ASKNO) {
                    get_quit = true;
                    break;
                }
                /* else a == ASKYES */
                fprintf(stderr, _("Excellent!!!\n"));
            }
        }
    }
}
コード例 #24
0
ファイル: ssh_cmd.c プロジェクト: wmene/yafc-1.1.2
rdirectory *ssh_read_directory(const char *path)
{
	rdirectory *rdir;
	int i;
	SFTP_DIRENT **dir;
	char *p = ftp_path_absolute(path);
	stripslash(p);

	if(ssh_readdir(p, &dir) != 0) {
		free(p);
		return 0;
	}

	rdir = rdir_create();

	ftp_trace("*** start parsing directory listing ***\n");

	for(i = 0; dir[i]; i++) {
		rfile *rf;
		char *e, *cf = dir[i]->longname;

		ftp_trace("%s\n", dir[i]->longname);

		rf = rfile_create();

		rf->perm = perm2string(dir[i]->a.perm);

		e = strqsep(&cf, ' ');  /* skip permissions */
		e = strqsep(&cf, ' ');  /* nhl? */
/*		if(ftp->ssh_version > 2) {*/
			rf->nhl = atoi(e);
/*		} else*/
/*			rf->nhl = 0;*/
#if 1
		e = strqsep(&cf, ' ');
		rf->owner = xstrdup(e);
		e = strqsep(&cf, ' ');
		rf->group = xstrdup(e);
#else
		asprintf(&rf->owner, "%d", dir[i]->a.uid);
		asprintf(&rf->group, "%d", dir[i]->a.gid);
#endif

		asprintf(&rf->path, "%s/%s", p, dir[i]->filename);
		rf->mtime = dir[i]->a.mtime;
		if(rf->mtime == 0) {
			char *m, *d, *y;
			while(e && month_number(e) == -1)
				e = strqsep(&cf, ' ');
			if(e) {
				m = e;
				d = strqsep(&cf, ' ');
				y = strqsep(&cf, ' ');
				ftp_trace("parsing time: m:%s d:%s y:%s\n", m, d, y);
				rfile_parse_time(rf, m, d, y);
			}
		}
		rf->date = time_to_string(rf->mtime);
		rf->size = dir[i]->a.size;
		rfile_parse_colors(rf);

		rf->link = 0;
		if(rislink(rf) && ftp->ssh_version > 2)
			rf->link = ssh_readlink(rf->path);

		list_additem(rdir->files, (void *)rf);
	}
	ftp_trace("*** end parsing directory listing ***\n");

	ssh_free_dirents(dir);

	rdir->path = p;

	ftp_trace("added directory '%s' to cache\n", p);
	list_additem(ftp->cache, rdir);

	return rdir;
}