Exemple #1
0
static int getforkparams(const AFPObj *obj, struct ofork *ofork, uint16_t bitmap, char *buf, size_t *buflen)
{
    struct path         path;
    struct stat     *st;

    struct adouble  *adp;
    struct dir      *dir;
    struct vol      *vol;


    /* can only get the length of the opened fork */
    if ( ( (bitmap & ((1<<FILPBIT_DFLEN) | (1<<FILPBIT_EXTDFLEN)))
           && (ofork->of_flags & AFPFORK_RSRC))
         ||
         ( (bitmap & ((1<<FILPBIT_RFLEN) | (1<<FILPBIT_EXTRFLEN)))
           && (ofork->of_flags & AFPFORK_DATA))) {
        return( AFPERR_BITMAP );
    }

    if (! AD_META_OPEN(ofork->of_ad)) {
        adp = NULL;
    } else {
        adp = ofork->of_ad;
    }

    vol = ofork->of_vol;
    dir = dirlookup(vol, ofork->of_did);

    if (NULL == (path.m_name = utompath(vol, of_name(ofork), dir->d_did, utf8_encoding(obj)))) {
        return( AFPERR_MISC );
    }
    path.u_name = of_name(ofork);
    path.id = 0;
    st = &path.st;
    if ( bitmap & ( (1<<FILPBIT_DFLEN) | (1<<FILPBIT_EXTDFLEN) |
                    (1<<FILPBIT_FNUM) | (1 << FILPBIT_CDATE) |
                    (1 << FILPBIT_MDATE) | (1 << FILPBIT_BDATE))) {
        if ( ad_data_fileno( ofork->of_ad ) <= 0 ) {
            /* 0 is for symlink */
            if (movecwd(vol, dir) < 0)
                return( AFPERR_NOOBJ );
            if ( lstat( path.u_name, st ) < 0 )
                return( AFPERR_NOOBJ );
        } else {
            if ( fstat( ad_data_fileno( ofork->of_ad ), st ) < 0 ) {
                return( AFPERR_BITMAP );
            }
        }
    }
    return getmetadata(obj, vol, bitmap, &path, dir, buf, buflen, adp );
}
Exemple #2
0
/*
 * build mac. path (backwards) by traversing the directory tree
 *
 * The old way: dir and path refer to an app, path is a mac format
 * pathname.  makemacpath() builds something that looks like a cname,
 * but uses upaths instead of mac format paths.
 *
 * The new way: dir and path refer to an app, path is a mac format
 * pathname.  makemacpath() builds a cname. (zero is a path separator
 * and it's not \0 terminated).
 *
 * See afp_getappl() for the backward compatiblity code.
 */
static char *
makemacpath(const struct vol *vol, char *mpath, int mpathlen, struct dir *dir, char *path)
{
    char	*p;

    p = mpath + mpathlen;
    p -= strlen( path );
    memcpy( p, path, strlen( path )); 

    while ( dir->d_did != DIRDID_ROOT ) {
        p -= blength(dir->d_m_name) + 1;
        if (p < mpath) {
            /* FIXME: pathname too long */
            return NULL;
        }
        memcpy(p, cfrombstr(dir->d_m_name), blength(dir->d_m_name) + 1);
        if ((dir = dirlookup(vol, dir->d_pdid)) == NULL)
            return NULL;
    }
    return( p );


#if 0
    char buffer[12 + MAXPATHLEN + 1];
    int buflen = 12 + MAXPATHLEN + 1;
    char *ret = mpath;
    char *path = name;
    char *uname = NULL;
    struct bstrList *pathlist = NULL;
    cnid_t cnid = dir->d_pdid;

    /* Create list for path elements, request 16 list elements for now*/
    if ((pathlist = bstListCreateMin(16)) == NULL) {
        LOG(log_error, logtype_afpd, "makemacpath: OOM: %s", strerror(errno));
        return NULL;
    }

    while ( cnid != DIRDID_ROOT ) {

        /* construct path, copy already found uname to path element list*/
        if ((bstrListPush(pathlist, bfromcstr(path))) != BSTR_OK) {
            afp_errno = AFPERR_MISC;
            ret = NULL;
            goto exit;
        }

        /* next part */
        if ((uname = cnid_resolve(vol->v_cdb, &cnid, buffer, buflen)) == NULL ) {
            afp_errno = AFPERR_NOOBJ;
            ret = NULL;
            goto exit;
        }

        if ((path = utompath(vol, uname, cnid, utf8_encoding())) == NULL) {
            afp_errno = AFPERR_MISC;
            ret = NULL;
            goto exit;
        }
    }



exit:
    if (pathlist)
        bstrListDestroy(pathlist);

    return(ret);
#endif
}
Exemple #3
0
/*!
 * This function performs a CNID db search
 *
 * Uses globals c1, c2, the search criteria
 *
 * @param vol       (r)  volume we are searching on ...
 * @param dir       (rw) directory we are starting from ...
 * @param uname     (r)  UNIX name of object to search
 * @param rmatches  (r)  maximum number of matches we can return
 * @param pos       (r)  position we've stopped recently
 * @param rbuf      (w)  output buffer
 * @param nrecs     (w)  number of matches
 * @param rsize     (w)  length of data written to output buffer
 * @param ext       (r)  extended search flag
 */
static int catsearch_db(struct vol *vol,
                        struct dir *dir,  
                        const char *uname,
                        int rmatches,
                        uint32_t *pos,
                        char *rbuf,
                        uint32_t *nrecs,
                        int *rsize,
                        int ext)
{
    static char resbuf[DBD_MAX_SRCH_RSLTS * sizeof(cnid_t)];
    static uint32_t cur_pos;
    static int num_matches;
    int ccr ,r;
	int result = AFP_OK;
    struct path path;
	char *rrbuf = rbuf;
    char buffer[MAXPATHLEN +2];
    uint16_t flags = CONV_TOLOWER;

    LOG(log_debug, logtype_afpd, "catsearch_db(req pos: %u): {pos: %u, name: %s}",
        *pos, cur_pos, uname);
        
	if (*pos != 0 && *pos != cur_pos) {
		result = AFPERR_CATCHNG;
		goto catsearch_end;
	}

    if (cur_pos == 0 || *pos == 0) {
        if (convert_charset(vol->v_volcharset,
                            vol->v_volcharset,
                            vol->v_maccharset,
                            uname,
                            strlen(uname),
                            buffer,
                            MAXPATHLEN,
                            &flags) == (size_t)-1) {
            LOG(log_error, logtype_afpd, "catsearch_db: conversion error");
            result = AFPERR_MISC;
            goto catsearch_end;
        }

        LOG(log_debug, logtype_afpd, "catsearch_db: %s", buffer);

        if ((num_matches = cnid_find(vol->v_cdb,
                                     buffer,
                                     strlen(uname),
                                     resbuf,
                                     sizeof(resbuf))) == -1) {
            result = AFPERR_MISC;
            goto catsearch_end;
        }
    }
	
	while (cur_pos < num_matches) {
        char *name;
        cnid_t cnid, did;
        char resolvebuf[12 + MAXPATHLEN + 1];
        struct dir *dir;

        /* Next CNID to process from buffer */
        memcpy(&cnid, resbuf + cur_pos * sizeof(cnid_t), sizeof(cnid_t));
        did = cnid;

        if ((name = cnid_resolve(vol->v_cdb, &did, resolvebuf, 12 + MAXPATHLEN + 1)) == NULL)
            goto next;
        LOG(log_debug, logtype_afpd, "catsearch_db: {pos: %u, name:%s, cnid: %u}",
            cur_pos, name, ntohl(cnid));
        if ((dir = dirlookup(vol, did)) == NULL)
            goto next;
        if (movecwd(vol, dir) < 0 )
            goto next;

        memset(&path, 0, sizeof(path));
        path.u_name = name;
        path.m_name = utompath(vol, name, cnid, utf8_encoding());

        if (of_stat(vol, &path) != 0) {
            switch (errno) {
            case EACCES:
            case ELOOP:
                goto next;
            case ENOENT:
                
            default:
                result = AFPERR_MISC;
                goto catsearch_end;
            } 
        }
        /* For files path.d_dir is the parent dir, for dirs its the dir itself */
        if (S_ISDIR(path.st.st_mode))
            if ((dir = dirlookup(vol, cnid)) == NULL)
                goto next;
        path.d_dir = dir;

        LOG(log_maxdebug, logtype_afpd,"catsearch_db: dir: %s, cwd: %s, name: %s", 
            cfrombstr(dir->d_fullpath), getcwdpath(), path.u_name);

        /* At last we can check the search criteria */
        ccr = crit_check(vol, &path);
        if ((ccr & 1)) {
            LOG(log_debug, logtype_afpd,"catsearch_db: match: %s/%s",
                getcwdpath(), path.u_name);
            /* bit 1 means that criteria has been met */
            r = rslt_add(vol, &path, &rrbuf, ext);
            if (r == 0) {
                result = AFPERR_MISC;
                goto catsearch_end;
            } 
            *nrecs += r;
            /* Number of matches limit */
            if (--rmatches == 0) 
                goto catsearch_pause;
            /* Block size limit */
            if (rrbuf - rbuf >= 448)
                goto catsearch_pause;
        }
    next:
        cur_pos++;
    } /* while */

	/* finished */
	result = AFPERR_EOF;
    cur_pos = 0;
	goto catsearch_end;

catsearch_pause:
    *pos = cur_pos;

catsearch_end: /* Exiting catsearch: error condition */
	*rsize = rrbuf - rbuf;
    LOG(log_debug, logtype_afpd, "catsearch_db(req pos: %u): {pos: %u}", *pos, cur_pos);
	return result;
}
Exemple #4
0
/* uname - UNIX name 
 * fname - our fname (translated to UNIX)
 * cidx - index in directory stack
 */
static int crit_check(struct vol *vol, struct path *path) {
	int result = 0;
	u_int16_t attr, flags = CONV_PRECOMPOSE;
	struct finderinfo *finfo = NULL, finderinfo;
	struct adouble *adp = NULL;
	time_t c_date, b_date;
	u_int32_t ac_date, ab_date;
	static char convbuf[514]; /* for convert_charset dest_len parameter +2 */
	size_t len;
    int islnk;
    islnk=S_ISLNK(path->st.st_mode);

	if (S_ISDIR(path->st.st_mode)) {
		if (!c1.dbitmap)
			return 0;
	}
	else {
		if (!c1.fbitmap)
			return 0;

		/* compute the Mac name 
		 * first try without id (it's slow to find it)
		 * An other option would be to call get_id in utompath but 
		 * we need to pass parent dir
		*/
        if (!(path->m_name = utompath(vol, path->u_name, 0 , utf8_encoding()) )) {
        	/*retry with the right id */
       
        	cnid_t id;
        	
        	adp = adl_lkup(vol, path, adp);
        	id = get_id(vol, adp, &path->st, path->d_dir->d_did, path->u_name, strlen(path->u_name));
        	if (!id) {
        		/* FIXME */
        		return 0;
        	}
        	/* save the id for getfilparm */
        	path->id = id;
        	if (!(path->m_name = utompath(vol, path->u_name, id , utf8_encoding()))) {
        		return 0;
        	}
        }
	}
		
	/* Kind of optimization: 
	 * -- first check things we've already have - filename
	 * -- last check things we get from ad_open()
	 * FIXME strmcp strstr (icase)
	 */

	/* Check for filename */
	if ((c1.rbitmap & (1<<DIRPBIT_LNAME))) { 
		if ( (size_t)(-1) == (len = convert_string(vol->v_maccharset, CH_UCS2, path->m_name, -1, convbuf, 512)) )
			goto crit_check_ret;

		if ((c1.rbitmap & (1<<CATPBIT_PARTIAL))) {
			if (strcasestr_w( (ucs2_t*) convbuf, (ucs2_t*) c1.lname) == NULL)
				goto crit_check_ret;
		} else
			if (strcasecmp_w((ucs2_t*) convbuf, (ucs2_t*) c1.lname) != 0)
				goto crit_check_ret;
	} 
	
	if ((c1.rbitmap & (1<<FILPBIT_PDINFO))) { 
		if ( (size_t)(-1) == (len = convert_charset( CH_UTF8_MAC, CH_UCS2, CH_UTF8, path->m_name, strlen(path->m_name), convbuf, 512, &flags))) {
			goto crit_check_ret;
		}

		if (c1.rbitmap & (1<<CATPBIT_PARTIAL)) {
			if (strcasestr_w((ucs2_t *) convbuf, (ucs2_t*)c1.utf8name) == NULL)
				goto crit_check_ret;
		} else
			if (strcasecmp_w((ucs2_t *)convbuf, (ucs2_t*)c1.utf8name) != 0)
				goto crit_check_ret;
	} 


	/* FIXME */
	if ((unsigned)c2.mdate > 0x7fffffff)
		c2.mdate = 0x7fffffff;
	if ((unsigned)c2.cdate > 0x7fffffff)
		c2.cdate = 0x7fffffff;
	if ((unsigned)c2.bdate > 0x7fffffff)
		c2.bdate = 0x7fffffff;

	/* Check for modification date */
	if ((c1.rbitmap & (1<<DIRPBIT_MDATE))) {
		if (path->st.st_mtime < c1.mdate || path->st.st_mtime > c2.mdate)
			goto crit_check_ret;
	}
	
	/* Check for creation date... */
	if ((c1.rbitmap & (1<<DIRPBIT_CDATE))) {
		c_date = path->st.st_mtime;
		adp = adl_lkup(vol, path, adp);
		if (adp && ad_getdate(adp, AD_DATE_CREATE, &ac_date) >= 0)
		    c_date = AD_DATE_TO_UNIX(ac_date);

		if (c_date < c1.cdate || c_date > c2.cdate)
			goto crit_check_ret;
	}

	/* Check for backup date... */
	if ((c1.rbitmap & (1<<DIRPBIT_BDATE))) {
		b_date = path->st.st_mtime;
		adp = adl_lkup(vol, path, adp);
		if (adp && ad_getdate(adp, AD_DATE_BACKUP, &ab_date) >= 0)
			b_date = AD_DATE_TO_UNIX(ab_date);

		if (b_date < c1.bdate || b_date > c2.bdate)
			goto crit_check_ret;
	}
				
	/* Check attributes */
	if ((c1.rbitmap & (1<<DIRPBIT_ATTR)) && c2.attr != 0) {
		if ((adp = adl_lkup(vol, path, adp))) {
			ad_getattr(adp, &attr);
			if ((attr & c2.attr) != c1.attr)
				goto crit_check_ret;
		} else 
			goto crit_check_ret;
	}		

        /* Check file type ID */
	if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.f_type != 0) {
	    finfo = unpack_finderinfo(vol, path, &adp, &finderinfo,islnk);
		if (finfo->f_type != c1.finfo.f_type)
			goto crit_check_ret;
	}
	
	/* Check creator ID */
	if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.creator != 0) {
		if (!finfo) {
			finfo = unpack_finderinfo(vol, path, &adp, &finderinfo,islnk);
		}
		if (finfo->creator != c1.finfo.creator)
			goto crit_check_ret;
	}
		
	/* Check finder info attributes */
	if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.attrs != 0) {
		if (!finfo) {
			finfo = unpack_finderinfo(vol, path, &adp, &finderinfo,islnk);
		}

		if ((finfo->attrs & c2.finfo.attrs) != c1.finfo.attrs)
			goto crit_check_ret;
	}
	
	/* Check label */
	if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.label != 0) {
		if (!finfo) {
			finfo = unpack_finderinfo(vol, path, &adp, &finderinfo,islnk);
		}
		if ((finfo->label & c2.finfo.label) != c1.finfo.label)
			goto crit_check_ret;
	}	
	/* FIXME: Attributes check ! */
	
	/* All criteria are met. */
	result |= 1;
crit_check_ret:
	if (adp != NULL)
		ad_close_metadata(adp);
	return result;
}  
Exemple #5
0
static int copy(const char *path,
                const struct stat *statp,
                int tflag,
                struct FTW *ftw)
{
    static int base = 0;

    struct stat to_stat;
    int dne;
    size_t nlen;
    const char *p;
    char *target_mid;

    if (alarmed)
        return -1;

    /* This currently doesn't work with "." */
    if (strcmp(path, ".") == 0) {
        ERROR("\".\" not supported");
    }
    const char *dir = strrchr(path, '/');
    if (dir == NULL)
        dir = path;
    else
        dir++;
    if (check_netatalk_dirs(dir) != NULL)
        return FTW_SKIP_SUBTREE;

    /*
     * If we are in case (2) above, we need to append the
     * source name to the target name.
     */
    if (type != FILE_TO_FILE) {
        /*
         * Need to remember the roots of traversals to create
         * correct pathnames.  If there's a directory being
         * copied to a non-existent directory, e.g.
         *     cp -R a/dir noexist
         * the resulting path name should be noexist/foo, not
         * noexist/dir/foo (where foo is a file in dir), which
         * is the case where the target exists.
         *
         * Also, check for "..".  This is for correct path
         * concatenation for paths ending in "..", e.g.
         *     cp -R .. /tmp
         * Paths ending in ".." are changed to ".".  This is
         * tricky, but seems the easiest way to fix the problem.
         *
         * XXX
         * Since the first level MUST be FTS_ROOTLEVEL, base
         * is always initialized.
         */
        if (ftw->level == 0) {
            if (type != DIR_TO_DNE) {
                base = ftw->base;

                if (strcmp(&path[base], "..") == 0)
                    base += 1;
            } else
                base = strlen(path);
        }

        p = &path[base];
        nlen = strlen(path) - base;
        target_mid = to.target_end;
        if (*p != '/' && target_mid[-1] != '/')
            *target_mid++ = '/';
        *target_mid = 0;
        if (target_mid - to.p_path + nlen >= PATH_MAX) {
            SLOG("%s%s: name too long (not copied)", to.p_path, p);
            badcp = rval = 1;
            return 0;
        }
        (void)strncat(target_mid, p, nlen);
        to.p_end = target_mid + nlen;
        *to.p_end = 0;
        STRIP_TRAILING_SLASH(to);
    }

    /* Not an error but need to remember it happened */
    if (stat(to.p_path, &to_stat) == -1)
        dne = 1;
    else {
        if (to_stat.st_dev == statp->st_dev &&
            to_stat.st_ino == statp->st_ino) {
            SLOG("%s and %s are identical (not copied).", to.p_path, path);
            badcp = rval = 1;
            if (S_ISDIR(statp->st_mode))
                /* without using glibc extension FTW_ACTIONRETVAL cant handle this */
                return FTW_SKIP_SUBTREE;
            return 0;
        }
        if (!S_ISDIR(statp->st_mode) &&
            S_ISDIR(to_stat.st_mode)) {
            SLOG("cannot overwrite directory %s with "
                 "non-directory %s",
                 to.p_path, path);
            badcp = rval = 1;
            return 0;
        }
        dne = 0;
    }

    /* Convert basename to appropiate volume encoding */
    if (dvolume.volinfo.v_path) {
        if ((convert_dots_encoding(&svolume, &dvolume, to.p_path, MAXPATHLEN)) == -1) {
            SLOG("Error converting name for %s", to.p_path);
            badcp = rval = 1;
            return -1;
        }
    }

    switch (statp->st_mode & S_IFMT) {
    case S_IFLNK:
        if (ftw_copy_link(ftw, path, statp, !dne))
            badcp = rval = 1;
        break;
    case S_IFDIR:
        if (!Rflag) {
            SLOG("%s is a directory", path);
            badcp = rval = 1;
            return -1;
        }
        /*
         * If the directory doesn't exist, create the new
         * one with the from file mode plus owner RWX bits,
         * modified by the umask.  Trade-off between being
         * able to write the directory (if from directory is
         * 555) and not causing a permissions race.  If the
         * umask blocks owner writes, we fail..
         */
        if (dne) {
            if (mkdir(to.p_path, statp->st_mode | S_IRWXU) < 0)
                ERROR("mkdir: %s: %s", to.p_path, strerror(errno));
        } else if (!S_ISDIR(to_stat.st_mode)) {
            errno = ENOTDIR;
            ERROR("%s", to.p_path);
        }

        /* Create ad dir and copy ".Parent" */
        if (dvolume.volinfo.v_path && dvolume.volinfo.v_adouble == AD_VERSION2) {

            /* Create ".AppleDouble" dir */
            mode_t omask = umask(0);
            bstring addir = bfromcstr(to.p_path);
            bcatcstr(addir, "/.AppleDouble");
            mkdir(cfrombstr(addir), 02777);
            bdestroy(addir);

            if (svolume.volinfo.v_path && svolume.volinfo.v_adouble == AD_VERSION2) {
                /* copy ".Parent" file */
                if (dvolume.volume.vfs->vfs_copyfile(&dvolume.volume, -1, path, to.p_path)) {
                    SLOG("Error copying adouble for %s -> %s", path, to.p_path);
                    badcp = rval = 1;
                    break;
                }
            }

            /* Get CNID of Parent and add new childir to CNID database */
            ppdid = pdid;
            if ((did = cnid_for_path(&dvolume, to.p_path, &pdid)) == CNID_INVALID) {
                SLOG("Error resolving CNID for %s", to.p_path);
                badcp = rval = 1;
                return -1;
            }

            struct adouble ad;
            struct stat st;
            if (lstat(to.p_path, &st) != 0) {
                badcp = rval = 1;
                break;
            }
            ad_init(&ad, dvolume.volinfo.v_adouble, dvolume.volinfo.v_ad_options);
            if (ad_open_metadata(to.p_path, ADFLAGS_DIR, O_RDWR | O_CREAT, &ad) != 0) {
                ERROR("Error opening adouble for: %s", to.p_path);
            }
            ad_setid( &ad, st.st_dev, st.st_ino, did, pdid, dvolume.db_stamp);
            ad_setname(&ad, utompath(&dvolume.volinfo, basename(to.p_path)));
            ad_setdate(&ad, AD_DATE_CREATE | AD_DATE_UNIX, st.st_mtime);
            ad_setdate(&ad, AD_DATE_MODIFY | AD_DATE_UNIX, st.st_mtime);
            ad_setdate(&ad, AD_DATE_ACCESS | AD_DATE_UNIX, st.st_mtime);
            ad_setdate(&ad, AD_DATE_BACKUP, AD_DATE_START);
            ad_flush(&ad);
            ad_close_metadata(&ad);

            umask(omask);
        }

        if (pflag) {
            if (setfile(statp, -1))
                rval = 1;
#if 0
            if (preserve_dir_acls(statp, curr->fts_accpath, to.p_path) != 0)
                rval = 1;
#endif
        }
        break;

    case S_IFBLK:
    case S_IFCHR:
        SLOG("%s is a device file (not copied).", path);
        break;
    case S_IFSOCK:
        SLOG("%s is a socket (not copied).", path);
        break;
    case S_IFIFO:
        SLOG("%s is a FIFO (not copied).", path);
        break;
    default:
        if (ftw_copy_file(ftw, path, statp, dne))
            badcp = rval = 1;

        if (dvolume.volinfo.v_path && dvolume.volinfo.v_adouble == AD_VERSION2) {

            mode_t omask = umask(0);
            if (svolume.volinfo.v_path && svolume.volinfo.v_adouble == AD_VERSION2) {
                /* copy ad-file */
                if (dvolume.volume.vfs->vfs_copyfile(&dvolume.volume, -1, path, to.p_path)) {
                    SLOG("Error copying adouble for %s -> %s", path, to.p_path);
                    badcp = rval = 1;
                    break;
                }
            }

            /* Get CNID of Parent and add new childir to CNID database */
            pdid = did;
            cnid_t cnid;
            if ((cnid = cnid_for_path(&dvolume, to.p_path, &did)) == CNID_INVALID) {
                SLOG("Error resolving CNID for %s", to.p_path);
                badcp = rval = 1;
                return -1;
            }

            struct adouble ad;
            struct stat st;
            if (lstat(to.p_path, &st) != 0) {
                badcp = rval = 1;
                break;
            }
            ad_init(&ad, dvolume.volinfo.v_adouble, dvolume.volinfo.v_ad_options);
            if (ad_open_metadata(to.p_path, 0, O_RDWR | O_CREAT, &ad) != 0) {
                ERROR("Error opening adouble for: %s", to.p_path);
            }
            ad_setid( &ad, st.st_dev, st.st_ino, cnid, did, dvolume.db_stamp);
            ad_setname(&ad, utompath(&dvolume.volinfo, basename(to.p_path)));
            ad_setdate(&ad, AD_DATE_CREATE | AD_DATE_UNIX, st.st_mtime);
            ad_setdate(&ad, AD_DATE_MODIFY | AD_DATE_UNIX, st.st_mtime);
            ad_setdate(&ad, AD_DATE_ACCESS | AD_DATE_UNIX, st.st_mtime);
            ad_setdate(&ad, AD_DATE_BACKUP, AD_DATE_START);
            ad_flush(&ad);
            ad_close_metadata(&ad);
            umask(omask);
        }
        break;
    }
    if (vflag && !badcp)
        (void)printf("%s -> %s\n", path, to.p_path);

    return 0;
}
Exemple #6
0
/* -------------------------------------------------------
*/
static char *
private_demangle(const struct vol *vol, char *mfilename, cnid_t did, cnid_t *osx) 
{
    char *t;
    char *u_name;
    uint32_t id, file_id;
    static char buffer[12 + MAXPATHLEN + 1];
    int len = 12 + MAXPATHLEN + 1;
    struct dir	*dir;
    size_t prefix;

    id = file_id = 0;

    t = strchr(mfilename, MANGLE_CHAR);
    if (t == NULL) {
        return mfilename;
    }
    prefix = t - mfilename;
    /* FIXME 
     * is prefix == 0 a valid mangled filename ?
    */
    /* may be a mangled filename */
    t++;
    if (*t == '0') { /* can't start with a 0 */
        return mfilename;
    }
    while(isuxdigit(*t)) {
        id = (id *16) + hextoint(*t);
        t++;
    }
    if ((*t != 0 && *t != '.') || strlen(t) > MAX_EXT_LENGTH || id < 17) {
        return mfilename;
    }

    file_id = id = htonl(id);
    if (osx) {
        *osx = id;
    }

    /* is it a dir?, there's a conflict with pre OSX 'trash #2'  */
    if ((dir = dirlookup(vol, id))) {
        if (dir->d_pdid != did) {
            /* not in the same folder, there's a race with outdate cache
             * but we have to live with it, hopefully client will recover
            */
            return mfilename;
        }
        if (!osx) {
            /* it's not from cname so mfilename and dir must be the same */
            if (strcmp(cfrombstr(dir->d_m_name), mfilename) == 0) {
                return cfrombstr(dir->d_u_name);
            }
        } else {
            return demangle_checks(vol, cfrombstr(dir->d_u_name), mfilename, prefix, t);
        }
    }
    else if (NULL != (u_name = cnid_resolve(vol->v_cdb, &id, buffer, len)) ) {
        if (id != did) {
            return mfilename;
        }
        if (!osx) {
            /* convert back to mac name and check it's the same */
            t = utompath(vol, u_name, file_id, utf8_encoding(vol->v_obj));
            if (!strcmp(t, mfilename)) {
                return u_name;
            }
        }
        else {
            return demangle_checks (vol, u_name, mfilename, prefix, t);
        }
    }

    return mfilename;
}