Esempio n. 1
0
File: fxp.c Progetto: Celelibi/yafc
static void fxp_preserve_attribs(const rfile *fi, char *dest)
{
	mode_t m = rfile_getmode(fi);
	if(m != (mode_t)-1) {
		if(ftp->has_site_chmod_command)
			ftp_chmod(dest, get_mode_string(m));
	}
}
Esempio n. 2
0
static void get_preserve_attribs(const rfile *fi, char *dest)
{
    time_t t;
    mode_t m = rfile_getmode(fi);
    if(m != (mode_t)-1) {
        if(access(dest, F_OK) == 0 && chmod(dest, m) != 0)
            perror(dest);
    }
    if(!risdir(fi)) {
        t = ftp_filetime(fi->path, true);
        if(t != (time_t)-1) {
            struct utimbuf u;
            u.actime = t;
            u.modtime = t;
            if(utime(dest, &u) != 0)
                perror(dest);
        }
    }
}
Esempio n. 3
0
/* returns:
 * 0   ok, remove file from list
 * -1  failure
 */
static int getfile(const rfile *fi, unsigned int opt,
             const char *output, const char *destname)
{
    struct stat sb;
    char* dest = NULL;
    getmode_t how = getNormal;
    bool mkunique = false;
    int r, ret = -1;

    if((get_glob_mask && fnmatch(get_glob_mask, base_name_ptr(fi->path),
                                 FNM_EXTMATCH) == FNM_NOMATCH)
#ifdef HAVE_REGEX
       || (get_rx_mask_set && regexec(&get_rx_mask, base_name_ptr(fi->path),
                                      0, 0, 0) == REG_NOMATCH)
#endif
        )
    {
        return 0;
    }

    if(!output)
        output = ".";

    if(test(opt, GET_PARENTS)) {
        char *apath = base_dir_xptr(fi->path);
        if (asprintf(&dest, "%s%s/%s", output, apath, destname) == -1)
        {
          free(apath);
          fprintf(stderr, _("Failed to allocate memory.\n"));
          return -1;
        }
        free(apath);
    } else {
        /* check if -o option is given, if GET_OUTPUT_FILE is set, we only
         * transfer one file and output is set to the filename. However, if
         * the destination already exists and is a directory, we assume
         * that the user meant a directory */

        int dest_is_file = test(opt, GET_OUTPUT_FILE);

        if(stat(output, &sb) == 0) {
            if(S_ISDIR(sb.st_mode)) {
                dest_is_file = false;
            }
        }

        if(dest_is_file)
            dest = xstrdup(output);
        else
            if (asprintf(&dest, "%s/%s", output, destname) == -1)
            {
              fprintf(stderr, _("Failed to allocate memory.\n"));
              return -1;
            }
    }

    /* make sure destination directory exists */
    {
        char *destdir = base_dir_xptr(dest);
        if(destdir) {
            bool r = make_path(destdir);
            if(!r) {
                if (errno == EEXIST)
                  ftp_err("`%s' exists but is not a directory\n", destdir);
                else
                  ftp_err("%s: %s\n", destdir, strerror(errno));
                transfer_mail_msg(_("Couldn't create directory: %s\n"),
                                  destdir);
                free(destdir);
                return -1;
            }
            /* change permission and group, if requested */
            if(test(opt, GET_CHMOD)) {
                if(stat(destdir, &sb) == 0) {
                    mode_t m = sb.st_mode;
                    m = mode_adjust(m, cmod);
                    if(chmod(destdir, m) != 0)
                        perror(destdir);
                }           }
            if(test(opt, GET_CHGRP)) {
                if(chown(destdir, -1, group_change) != 0)
                    perror(dest);
            }
            free(destdir);
        }
    }

    /* check if destination file exists */
    if(stat(dest, &sb) == 0) {
        if(test(opt, GET_SKIP_EXISTING)) {
            if(test(opt, GET_VERBOSE)) {
							char* sp = shortpath(dest, 42, gvLocalHomeDir);
              fprintf(stderr, _("Local file '%s' exists, skipping...\n"),
                      sp);
							stats_file(STATS_SKIP, 0);
							free(sp);
						}
            return 0;
        }
        if(test(opt, GET_UNIQUE))
            mkunique = true;
        else if(test(opt, GET_APPEND))
            how = getAppend;
        else if(test(opt, GET_NEWER)) {
            struct tm *fan = gmtime(&sb.st_mtime);
            time_t ft = ftp_filetime(fi->path, test(opt, GET_FORCE_NEWER));
            sb.st_mtime = gmt_mktime(fan);

            ftp_trace("get -n: remote file: %s", ctime(&ft));
            ftp_trace("get -n: local file: %s\n", ctime(&sb.st_mtime));

            if(sb.st_mtime >= ft && ft != (time_t)-1) {
                if(test(opt, GET_VERBOSE)) {
									char* sp = shortpath(dest, 30, gvLocalHomeDir);
                    ftp_err(_(
                        "Local file '%s' is newer than remote, skipping...\n"),
                            sp);
									stats_file(STATS_SKIP, 0);
									free(sp);
								}
                return 0;
            }
        } else if(!test(opt, GET_RESUME)) {
            if(!get_owbatch && !gvSighupReceived) {
                struct tm *fan = gmtime(&sb.st_mtime);
                time_t ft = ftp_filetime(fi->path, test(opt, GET_FORCE_NEWER));
                int a;
                char *e;

                sb.st_mtime = gmt_mktime(fan);
                e = xstrdup(ctime(&sb.st_mtime));
								char* sp = shortpath(dest, 42, gvLocalHomeDir);
                a = ask(ASKYES|ASKNO|ASKUNIQUE|ASKCANCEL|ASKALL|ASKRESUME,
                        ASKRESUME,
                        _("Local file '%s' exists\nLocal: %lld bytes, %sRemote: %lld bytes, %sOverwrite?"),
                        sp,
                        (unsigned long long) sb.st_size, e ? e : "unknown date\n",
                        ftp_filesize(fi->path), ctime(&ft));
								free(sp);
                free(e);
                if(a == ASKCANCEL) {
                    get_quit = true;
                    return 0;
                }
                else if(a == ASKNO)
                    return 0;
                else if(a == ASKUNIQUE)
                    mkunique = true;
                else if(a == ASKALL) {
                    get_owbatch = true;
                }
                else if(a == ASKRESUME)
                    opt |= GET_RESUME; /* for this file only */
                /* else a == ASKYES */
            }
        }
        if(test(opt, GET_RESUME))
            how = getResume;
    }

    if(mkunique) {
        char* newdest = make_unique_filename(dest);
        free(dest);
        dest = newdest;
    }

    /* the file doesn't exist or we choosed to overwrite it, or changed dest */

    if(rislink(fi) && test(opt, GET_NO_DEREFERENCE)) {
        /* remove any existing destination */
        unlink(dest);
        ftp_err(_("symlinking '%s' to '%s'\n"), dest, fi->link);
        if(symlink(fi->link, dest) != 0)
            perror(dest);
        ret = 0;
    }
    else {
        r = do_the_get(fi->path, dest, how, opt);

        if(r == 0) {
			stats_file(STATS_SUCCESS, ftp->ti.total_size);
            ret = 0;
            if(test(opt, GET_PRESERVE))
                get_preserve_attribs(fi, dest);
            if(test(opt, GET_CHMOD)) {
                mode_t m = rfile_getmode(fi);
                m = mode_adjust(m, cmod);
                if(chmod(dest, m) != 0)
                    perror(dest);
            }
            if(test(opt, GET_CHGRP)) {
                if(chown(dest, -1, group_change) != 0)
                    perror(dest);
            }
            if(test(opt, GET_DELETE_AFTER)) {
                bool dodel = false;
								char* sp = shortpath(fi->path, 42, ftp->homedir);
                if(!test(opt, GET_FORCE)
                   && !get_delbatch && !gvSighupReceived)
                {
                    int a = ask(ASKYES|ASKNO|ASKCANCEL|ASKALL, ASKYES,
                                _("Delete remote file '%s'?"), sp);
                    if(a == ASKALL) {
                        get_delbatch = true;
                        dodel = true;
                    }
                    else if(a == ASKCANCEL)
                        get_quit = true;
                    else if(a != ASKNO)
                        dodel = true;
                } else
                    dodel = true;

                if(dodel) {
                    ftp_unlink(fi->path);
                    if(ftp->code == ctComplete)
                        fprintf(stderr, _("%s: deleted\n"), sp);
                    else
                        fprintf(stderr, _("error deleting '%s': %s\n"),
															  sp, ftp_getreply(false));
                }
								free(sp);
            }
        } else {
			stats_file(STATS_FAIL, 0);
			ret = -1;
		}
    }

    free(dest);
    return ret;
}