Exemple #1
0
/*
 * Function: sys_list_eas
 *
 * Purpose: copy names of native EAs into attrnamebuf
 *
 * Arguments:
 *
 *    vol          (r) current volume
 *    attrnamebuf  (w) store names a consecutive C strings here
 *    buflen       (rw) length of names in attrnamebuf
 *    uname        (r) filename
 *    oflag        (r) link and create flag
 *
 * Returns: AFP code: AFP_OK on success or appropiate AFP error code
 *
 * Effects:
 *
 * Copies names of all EAs of uname as consecutive C strings into rbuf.
 * Increments *rbuflen accordingly.
 * We hide the adouble:ea extended attributes here, but we currently
 * allow reading, writing and deleteting them.
 */
int sys_list_eas(VFS_FUNC_ARGS_EA_LIST)
{
    ssize_t attrbuflen = *buflen;
    int     ret, len, nlen;
    char    *buf;
    char    *ptr;
    struct adouble ad, *adp;

    buf = malloc(ATTRNAMEBUFSIZ);
    if (!buf)
        return AFPERR_MISC;

    /* PBaranski fix */
    if ( fd != -1) {
	LOG(log_debug, logtype_afpd, "sys_list_eas(%s): file is already opened", uname);
	ret = sys_flistxattr(fd, uname, buf, ATTRNAMEBUFSIZ);
    } else {
	if ((oflag & O_NOFOLLOW)) {
    	    ret = sys_llistxattr(uname, buf, ATTRNAMEBUFSIZ);
	}
	else {
    	    ret = sys_listxattr(uname, buf, ATTRNAMEBUFSIZ);
	}
    }
    /* PBaranski fix */

    if (ret == -1) switch(errno) {
        case OPEN_NOFOLLOW_ERRNO:
            /* its a symlink and client requested O_NOFOLLOW, we pretend 0 EAs */
            LOG(log_debug, logtype_afpd, "sys_list_extattr(%s): symlink with kXAttrNoFollow", uname);
            ret = AFP_OK;
            goto exit;
        default:
            LOG(log_debug, logtype_afpd, "sys_list_extattr(%s): error opening atttribute dir: %s", uname, strerror(errno));
            ret = AFPERR_MISC;
            goto exit;
    }
    
    ptr = buf;
    while (ret > 0)  {
        len = strlen(ptr);
        if (NOT_NETATALK_EA(ptr)) {
            /* Convert name to CH_UTF8_MAC and directly store in in the reply buffer */
            if ( 0 >= ( nlen = convert_string(vol->v_volcharset, CH_UTF8_MAC, ptr, len, attrnamebuf + attrbuflen, 256)) ) {
                ret = AFPERR_MISC;
                goto exit;
            }

            LOG(log_debug7, logtype_afpd, "sys_list_extattr(%s): attribute: %s", uname, ptr);

            attrbuflen += nlen + 1;
            if (attrbuflen > (ATTRNAMEBUFSIZ - 256)) {
                /* Next EA name could overflow, so bail out with error.
                   FIXME: evantually malloc/memcpy/realloc whatever.
                   Is it worth it ? */
                LOG(log_warning, logtype_afpd, "sys_list_extattr(%s): running out of buffer for EA names", uname);
                ret = AFPERR_MISC;
                goto exit;
            }
        }
        ret -= len + 1;
        ptr += len + 1;
    }

    ret = AFP_OK;

exit:
    free(buf);
    *buflen = attrbuflen;
    return ret;
}
Exemple #2
0
ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size)
{
	return sys_flistxattr(fd, list, size);
}