Esempio n. 1
0
/*
 * Function: sys_get_eacontent
 *
 * Purpose: copy native EA into rbuf
 *
 * Arguments:
 *
 *    vol          (r) current volume
 *    rbuf         (w) DSI reply buffer
 *    rbuflen      (rw) current length of data in reply buffer
 *    uname        (r) filename
 *    oflag        (r) link and create flag
 *    attruname    (r) name of attribute
 *    maxreply     (r) maximum EA size as of current specs/real-life
 *    fd           (r) file descriptor
 * Returns: AFP code: AFP_OK on success or appropiate AFP error code
 *
 * Effects:
 *
 * Copies EA into rbuf. Increments *rbuflen accordingly.
 */
int sys_get_eacontent(VFS_FUNC_ARGS_EA_GETCONTENT)
{
    ssize_t   ret;
    uint32_t  attrsize;

    /* Start building reply packet */

    maxreply -= MAX_REPLY_EXTRA_BYTES;

    if (maxreply > MAX_EA_SIZE)
        maxreply = MAX_EA_SIZE;

    LOG(log_debug7, logtype_afpd, "sys_getextattr_content(%s): attribute: \"%s\", size: %u", uname, attruname, maxreply);
    if (vol->v_flags & AFPVOL_EA_SAMBA) {
        maxreply++;
    }

    /* PBaranski fix */
    if (fd != -1) {
	LOG(log_debug, logtype_afpd, "sys_get_eacontent(%s): file is already opened", uname);
	ret = sys_fgetxattr(fd, attruname, rbuf +4, maxreply);
    } else {
	if ((oflag & O_NOFOLLOW) ) {
    	    ret = sys_lgetxattr(uname, attruname, rbuf +4, maxreply);
	}
	else {
    	    ret = sys_getxattr(uname, attruname,  rbuf +4, maxreply);
	}
    }
    /* PBaranski fix */

    if (ret == -1) {
        memset(rbuf, 0, 4);
        *rbuflen += 4;
        switch(errno) {
        case OPEN_NOFOLLOW_ERRNO:
            /* its a symlink and client requested O_NOFOLLOW  */
            LOG(log_debug, logtype_afpd, "sys_getextattr_content(%s): symlink with kXAttrNoFollow", uname);
            return AFPERR_MISC;

        case ENOATTR:
            if (vol->v_obj->afp_version >= 34)
                return AFPERR_NOITEM;
            return AFPERR_MISC;

        default:
            LOG(log_debug, logtype_afpd, "sys_getextattr_content(%s): error: %s", attruname, strerror(errno));
            return AFPERR_MISC;
        }
    }

    if (vol->v_flags & AFPVOL_EA_SAMBA) {
        /* What can we do about xattrs that are 1 byte large? */
        if (ret < 2) {
            memset(rbuf, 0, 4);
            *rbuflen += 4;

            if (vol->v_obj->afp_version >= 34) {
                return AFPERR_NOITEM;
            }
            return AFPERR_MISC;
        }
        ret--;
    }

    /* remember where we must store length of attribute data in rbuf */
    *rbuflen += 4 +ret;

    attrsize = htonl((uint32_t)ret);
    memcpy(rbuf, &attrsize, 4);

    return AFP_OK;
}
Esempio n. 2
0
/*
 * Function: sys_get_easize
 *
 * Purpose: get size of a native EA
 *
 * Arguments:
 *
 *    vol          (r) current volume
 *    rbuf         (w) DSI reply buffer
 *    rbuflen      (rw) current length of data in reply buffer
 *    uname        (r) filename
 *    oflag        (r) link and create flag
 *    attruname    (r) name of attribute
 *
 * Returns: AFP code: AFP_OK on success or appropiate AFP error code
 *
 * Effects:
 *
 * Copies EA size into rbuf in network order. Increments *rbuflen +4.
 */
int sys_get_easize(VFS_FUNC_ARGS_EA_GETSIZE)
{
    ssize_t   ret;
    uint32_t  attrsize;

    LOG(log_debug7, logtype_afpd, "sys_getextattr_size(%s): attribute: \"%s\"", uname, attruname);

    /* PBaranski fix */
    if (fd != -1) {
	LOG(log_debug, logtype_afpd, "sys_get_easize(%s): file is already opened", uname);
	ret = sys_fgetxattr(fd, attruname, rbuf +4, 0);
    } else {
	if ((oflag & O_NOFOLLOW) ) {
    	    ret = sys_lgetxattr(uname, attruname, rbuf +4, 0);
	}
	else {
    	    ret = sys_getxattr(uname, attruname,  rbuf +4, 0);
	}
    }
    /* PBaranski fix */

    
    if (ret == -1) {
        memset(rbuf, 0, 4);
        *rbuflen += 4;
        switch(errno) {
        case OPEN_NOFOLLOW_ERRNO:
            /* its a symlink and client requested O_NOFOLLOW  */
            LOG(log_debug, logtype_afpd, "sys_getextattr_size(%s): symlink with kXAttrNoFollow", uname);
            return AFPERR_MISC;

        case ENOATTR:
        case ENOENT:
            if (vol->v_obj->afp_version >= 34)
                return AFPERR_NOITEM;
            return AFPERR_MISC;

        default:
            LOG(log_debug, logtype_afpd, "sys_getextattr_size: error: %s", strerror(errno));
            return AFPERR_MISC;
        }
    }

    if (ret > MAX_EA_SIZE) 
      ret = MAX_EA_SIZE;

    if (vol->v_flags & AFPVOL_EA_SAMBA) {
        /* What can we do about xattrs that are 1 byte large? */
        if (ret < 2) {
            memset(rbuf, 0, 4);
            *rbuflen += 4;

            if (vol->v_obj->afp_version >= 34) {
                return AFPERR_NOITEM;
            }
            return AFPERR_MISC;
        }
        ret--;
    }

    /* Start building reply packet */
    LOG(log_debug7, logtype_afpd, "sys_getextattr_size(%s): attribute: \"%s\", size: %u", uname, attruname, ret);

    /* length of attribute data */
    attrsize = htonl((uint32_t)ret);
    memcpy(rbuf, &attrsize, 4);
    *rbuflen += 4;

    ret = AFP_OK;
    return ret;
}
Esempio n. 3
0
ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size)
{
	return sys_fgetxattr(fd, name, value, size);
}