Add initial libnwfs metadata xattr library
All checks were successful
Source release / source-package (push) Successful in 1m3s

This commit is contained in:
OpenAI
2026-06-10 14:18:02 +00:00
committed by Mario Fetka
parent bf21295121
commit 23fa433b80
8 changed files with 823 additions and 0 deletions

View File

@@ -82,6 +82,7 @@ option(ENABLE_XATTR "Should we build Mars Nwe with extended attribute support?"
option(MARS_NWE_INSTALL_DOSUTILS "Install DOS client utilities" ON)
option(MARS_NWE_INSTALL_NEW_DOSUTILS "Install the new/experimental DOS client utilities instead of legacy netold.exe" OFF)
option(MARS_NWE_BUILD_TESTS "Build optional mars_nwe integration tests" OFF)
option(MARS_NWE_BUILD_NWFS_TESTS "Build libnwfs unit tests" OFF)
option(ENABLE_DIRECTORY "Build the optional nwdirectory/TinyLDAP subsystem" OFF)
option(MARS_NWE_BUILD_MATRIXSSL_PROGRAMS "Build MatrixSSL example apps, tests and helper tools" OFF)
@@ -260,6 +261,7 @@ add_subdirectory(third_party/matrixssl)
# MatrixSSL, which stays a native TLS/crypto provider.
add_subdirectory(src/core)
add_subdirectory(src/ssl)
add_subdirectory(src/nwfs)
if(ENABLE_DIRECTORY)
# Bundled FLAIM storage stack. Keep the imported sources unchanged; the CMake
@@ -334,6 +336,10 @@ add_subdirectory(src)
add_subdirectory(opt)
add_subdirectory(sys)
if(MARS_NWE_BUILD_NWFS_TESTS)
add_subdirectory(tests/nwfs)
endif()
if(MARS_NWE_BUILD_TESTS)
add_subdirectory(tests)
endif()

260
include/nwfs/zXattr.h Normal file
View File

@@ -0,0 +1,260 @@
/****************************************************************************
|
| (C) Copyright 2005 Novell, Inc.
| All Rights Reserved.
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of version 2 of the GNU General Public
| License as published by the Free Software Foundation.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; if not, contact Novell, Inc.
|
| To contact Novell about this file by physical or electronic mail,
| you may find current contact information at www.novell.com
|
|***************************************************************************
|
| Novell Storage Services (NSS) support module
|
|---------------------------------------------------------------------------
|
| $Author: vandana $
| $Date: 2006-11-14 05:57:30 +0530 (Tue, 14 Nov 2006) $
|
| $RCSfile$
| $Revision: 1632 $
|
|---------------------------------------------------------------------------
| This module is used to:
| Defines the <name, value> pairs for the netware extended attributes.
+-------------------------------------------------------------------------*/
#ifndef _ZXATTR_H_
#define _ZXATTR_H_ 1
#ifndef _ZOMNI_H_
#include <zOmni.h>
#endif
#ifndef _ZPARAMS_H_
#include <zParams.h>
#endif
#define zNW_PREFIX "netware."
#define zNW_NCPSTAT zNW_PREFIX "ncpstat"
#define zNW_QUOTA zNW_PREFIX "quota"
#define zNW_METADATA zNW_PREFIX "metadata"
#define zNW_USERQUOTA zNW_PREFIX "userquota"
//#define zNW_TRUSTEE zNW_PREFIX "trustee"
#define zNW_BYTEORDER 0xfeff
#define zNW_NCPSTAT_VERSION 1
#define zNW_QUOTA_VERSION 2
#define zNW_METADATA_VERSION 1
#define zNW_USERQUOTA_VERSION 1
//#define zNW_TRUSTEE_VERSION 1
#define zNW_ALLOWED_MODIFY_FLAGS (zMOD_FILE_ATTRIBUTES \
| zMOD_CREATED_TIME \
| zMOD_MODIFIED_TIME \
| zMOD_ACCESSED_TIME)
typedef struct zNW_ncpstat_s {
WORD nws_byteorder;
WORD nws_version;
LONG nws_reserved_1;
QUAD nws_info_mask; /* Modify information indicated by mask
* (see zParams.h zMOD_*) */
QUAD nws_file_attributes;/* All the NSS file attributes
* (see zParams.h) */
QUAD nws_file_attr_mask; /* All the NSS file attributes */
QUAD nws_zid; /* File ID, for hard links, this will be
* the secondary zid */
QUAD nws_zid_primary; /* Primary ZID */
QUAD nws_zid_parent; /* File id of parent */
GUID_t nws_volume_id; /* 128 bit volume id */
QUAD nws_size_logical; /* Logical size of the file in bytes */
QUAD nws_size_physical; /* Physical size of the file in bytes */
QUAD nws_created; /* UTC time created */
// QUAD nws_archived;
QUAD nws_modified; /* UTC time modified */
QUAD nws_accessed; /* UTC time last accessed */
// QUAD nws_metaDataModified;
} zNW_ncpstat_s;
typedef struct zNW_quota_V1_s {
WORD nwq_byteorder;
WORD nwq_version;
LONG nwq_reserved_1;
QUAD nwq_user_used; /* Quota used by user */
QUAD nwq_user_limit; /* Quota limit assigned to user */
QUAD nwq_dir_left; /* Quota min left in directory ancestors */
} zNW_quota_V1_s;
typedef struct zNW_quota_s {
WORD nwq_byteorder;
WORD nwq_version;
LONG nwq_reserved_1;
QUAD nwq_user_used; /* Quota used by user */
QUAD nwq_user_limit; /* Quota limit assigned to user */
QUAD nwq_dir_left; /* Quota min left in directory ancestors */
QUAD nwq_dir_quota; /* Quota set on the directory */
} zNW_quota_s;
/*
* We have picked a value for zMAX_TRUSTEES that will let the
* structure fit in 64K.
*/
#define zMAX_TRUSTEES 2043
typedef struct zNW_trustee_s {
GUID_t nwt_id;
QUAD nwt_rights;
QUAD nwt_reserved_2;
} zNW_trustee_s;
typedef struct zNW_metadata_s {
WORD nwm_byteorder;
WORD nwm_version;
LONG nwm_reserved_1;
QUAD nwm_modify_mask;
QUAD nwm_file_attributes;
QUAD nwm_file_attributes_mask;
QUAD nwm_time_created;
QUAD nwm_time_archived;
QUAD nwm_time_modified;
QUAD nwm_time_accessed;
QUAD nwm_time_meta_data_modified;
QUAD nwm_reserved_2;
GUID_t nwm_id_owner;
GUID_t nwm_id_archiver;
GUID_t nwm_id_modifier;
GUID_t nwm_id_metadata_modifier;
SQUAD nwm_quota_limit;
LONG nwm_inherited_rights_mask;
LONG nwm_trustee_num;
zNW_trustee_s nwm_trustee[zMAX_TRUSTEES];
} zNW_metadata_s;
/*
* We have picked a value for zMAX_USERS that will let the
* structure fit in 64K.
*/
#define zMAX_XATTR_USERS 2047
typedef struct zNW_user_restriction_s {
GUID_t nwur_user;
SQUAD nwur_restriction;
QUAD nwur_reserved_2;
} zNW_user_restriction_s;
typedef struct zNW_user_quota_s {
WORD nwuq_byteorder;
WORD nwuq_version;
LONG nwuq_num_users;
LONG nwuq_index;
LONG nwuq_reserved_1;
zNW_user_restriction_s nwuq_user[zMAX_XATTR_USERS];
} zNW_user_quota_s;
#if 0
#define zMAX_FDN_NAME 256
#define zMAX_XATTR_USERS 124
typedef struct zNW_user_restriction_s {
QUAD nwur_restriction;
QUAD nwur_reserved_2;
unicode_t nwur_dnsname[zMAX_FDN_NAME];
} zNW_user_restriction_s;
typedef struct zNW_user_quota_s {
WORD nwuq_byteorder;
WORD nwuq_version;
LONG nwuq_num_users;
LONG nwuq_index;
LONG nwuq_reserved_1;
zNW_user_restriction_s nwuq_user[zMAX_XATTR_USERS];
} zNW_user_quota_s;
typedef struct zNW_user_trustee_s{
QUAD nwut_rights;
QUAD nwut_reserved_2;
unicode_t nwut_dnsname[zMAX_FDN_NAME];
} zNW_user_trustee_s;
typedef struct zNW_trustee_name_s {
WORD nwtn_byteorder;
WORD nwtn_version;
LONG nwtn_num_trustees;
LONG nwtn_index;
LONG nwtn_reserved_1;
zNW_user_trustee_s nwtn_user[zMAX_XATTR_USERS];
} zNW_trustee_name_s;
#endif
/*
* mars-nwe userspace adaptation boundary.
*
* The media structures above keep the imported OES/NSS names and layout.
* The helpers below are intentionally small: they initialise and validate the
* OES-compatible netware.* payloads without pulling in the NSS kernel, VFS,
* Semantic Agent or MPK runtime.
*/
#include <stddef.h>
#define NWFS_METADATA_FIXED_SIZE offsetof(zNW_metadata_s, nwm_trustee)
#define NWFS_USERQUOTA_FIXED_SIZE offsetof(zNW_user_quota_s, nwuq_user)
#define NWFS_QUOTA_BACKEND_ENV "NWFS_QUOTA_BACKEND"
#define NWFS_QUOTA_BACKEND_LINUXQUOTA "LINUXQUOTA"
#define NWFS_QUOTA_BACKEND_METADATAONLY "METADATAONLY"
#define NWFS_QUOTA_BACKEND_NSS "NSS"
typedef enum nwfs_status_e {
NWFS_OK = 0,
NWFS_ERR_INVAL = -1,
NWFS_ERR_RANGE = -2,
NWFS_ERR_VERSION = -3,
NWFS_ERR_BYTEORDER = -4
} nwfs_status_e;
void nwfs_ncpstat_init(zNW_ncpstat_s *ncpstat);
int nwfs_ncpstat_validate(const zNW_ncpstat_s *ncpstat, size_t size);
void nwfs_metadata_init(zNW_metadata_s *metadata);
int nwfs_metadata_validate(const zNW_metadata_s *metadata, size_t size);
size_t nwfs_metadata_size_for_trustees(LONG trustee_num);
LONG nwfs_metadata_max_trustees_for_size(size_t size);
void nwfs_quota_init(zNW_quota_s *quota);
int nwfs_quota_validate(const zNW_quota_s *quota, size_t size);
void nwfs_userquota_init(zNW_user_quota_s *userquota);
int nwfs_userquota_validate(const zNW_user_quota_s *userquota, size_t size);
size_t nwfs_userquota_size_for_users(LONG user_num);
LONG nwfs_userquota_max_users_for_size(size_t size);
int nwfs_metadata_set_file_attributes(zNW_metadata_s *metadata, QUAD attributes);
int nwfs_metadata_get_file_attributes(const zNW_metadata_s *metadata, QUAD *attributes);
int nwfs_metadata_set_inherited_rights_mask(zNW_metadata_s *metadata, LONG inherited_rights_mask);
int nwfs_metadata_get_inherited_rights_mask(const zNW_metadata_s *metadata, LONG *inherited_rights_mask);
int nwfs_metadata_set_trustees(zNW_metadata_s *metadata, const zNW_trustee_s *trustees, LONG trustee_num);
int nwfs_metadata_get_trustees(const zNW_metadata_s *metadata, zNW_trustee_s *trustees, LONG trustee_capacity, LONG *trustee_num);
#endif

32
src/nwfs/CMakeLists.txt Normal file
View File

@@ -0,0 +1,32 @@
add_library(nwfs SHARED
lsaComn.c
lsaXattr.c)
add_library(mars_nwe::nwfs ALIAS nwfs)
set_target_properties(nwfs PROPERTIES
OUTPUT_NAME nwfs
VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}"
SOVERSION "${VERSION_MAJOR}")
target_compile_features(nwfs PRIVATE c_std_99)
target_include_directories(nwfs
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>"
"$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include/nwfs/nss/sdk/public>"
"$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include/nwfs/nss/sdk/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}")
install(TARGETS nwfs
EXPORT mars-nwe-nwfs-targets
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(FILES "${CMAKE_SOURCE_DIR}/include/nwfs/zXattr.h"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/nwfs")
install(EXPORT mars-nwe-nwfs-targets
NAMESPACE mars_nwe::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/mars-nwe")

232
src/nwfs/lsaComn.c Normal file
View File

@@ -0,0 +1,232 @@
/****************************************************************************
|
| (C) Copyright 1995 - 2000 Novell, Inc.
| All Rights Reserved.
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of version 2 of the GNU General Public
| License as published by the Free Software Foundation.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; if not, contact Novell, Inc.
|
| To contact Novell about this file by physical or electronic mail,
| you may find current contact information at www.novell.com
|
|***************************************************************************
|
| Novell Storage Services (NSS) support module
|
|---------------------------------------------------------------------------
| mars-nwe userspace adaptation of the LSA common metadata helpers. This file
| keeps the imported OES/NSS netware.* media structures as the compatibility
| boundary and strips the original NSS kernel/VFS/runtime plumbing.
+-------------------------------------------------------------------------*/
#include <string.h>
#include <nwfs/zXattr.h>
#include "lsaPrivate.h"
int nwfs_validate_header(WORD byteorder, WORD version, WORD expected_version)
{
if (byteorder != zNW_BYTEORDER) {
return NWFS_ERR_BYTEORDER;
}
if (version != expected_version) {
return NWFS_ERR_VERSION;
}
return NWFS_OK;
}
int nwfs_validate_count(LONG count, LONG max_count)
{
if (count > max_count) {
return NWFS_ERR_RANGE;
}
return NWFS_OK;
}
void nwfs_ncpstat_init(zNW_ncpstat_s *ncpstat)
{
if (ncpstat == NULL) {
return;
}
memset(ncpstat, 0, sizeof(*ncpstat));
ncpstat->nws_byteorder = zNW_BYTEORDER;
ncpstat->nws_version = zNW_NCPSTAT_VERSION;
}
int nwfs_ncpstat_validate(const zNW_ncpstat_s *ncpstat, size_t size)
{
if (ncpstat == NULL) {
return NWFS_ERR_INVAL;
}
if (size < sizeof(*ncpstat)) {
return NWFS_ERR_RANGE;
}
return nwfs_validate_header(ncpstat->nws_byteorder,
ncpstat->nws_version,
zNW_NCPSTAT_VERSION);
}
void nwfs_metadata_init(zNW_metadata_s *metadata)
{
if (metadata == NULL) {
return;
}
memset(metadata, 0, sizeof(*metadata));
metadata->nwm_byteorder = zNW_BYTEORDER;
metadata->nwm_version = zNW_METADATA_VERSION;
metadata->nwm_file_attributes_mask = ~(QUAD)0;
metadata->nwm_inherited_rights_mask = (LONG)~0U;
}
size_t nwfs_metadata_size_for_trustees(LONG trustee_num)
{
if (trustee_num < 0 || trustee_num > zMAX_TRUSTEES) {
return 0;
}
return NWFS_METADATA_FIXED_SIZE + ((size_t)trustee_num * sizeof(zNW_trustee_s));
}
LONG nwfs_metadata_max_trustees_for_size(size_t size)
{
size_t count;
if (size < NWFS_METADATA_FIXED_SIZE) {
return -1;
}
count = (size - NWFS_METADATA_FIXED_SIZE) / sizeof(zNW_trustee_s);
if (count > zMAX_TRUSTEES) {
count = zMAX_TRUSTEES;
}
return (LONG)count;
}
int nwfs_metadata_validate(const zNW_metadata_s *metadata, size_t size)
{
int rc;
size_t needed;
if (metadata == NULL) {
return NWFS_ERR_INVAL;
}
if (size < NWFS_METADATA_FIXED_SIZE) {
return NWFS_ERR_RANGE;
}
rc = nwfs_validate_header(metadata->nwm_byteorder,
metadata->nwm_version,
zNW_METADATA_VERSION);
if (rc != NWFS_OK) {
return rc;
}
rc = nwfs_validate_count(metadata->nwm_trustee_num, zMAX_TRUSTEES);
if (rc != NWFS_OK) {
return rc;
}
needed = nwfs_metadata_size_for_trustees(metadata->nwm_trustee_num);
if (needed == 0 || size < needed) {
return NWFS_ERR_RANGE;
}
return NWFS_OK;
}
void nwfs_quota_init(zNW_quota_s *quota)
{
if (quota == NULL) {
return;
}
memset(quota, 0, sizeof(*quota));
quota->nwq_byteorder = zNW_BYTEORDER;
quota->nwq_version = zNW_QUOTA_VERSION;
}
int nwfs_quota_validate(const zNW_quota_s *quota, size_t size)
{
if (quota == NULL) {
return NWFS_ERR_INVAL;
}
if (size < sizeof(*quota)) {
return NWFS_ERR_RANGE;
}
return nwfs_validate_header(quota->nwq_byteorder,
quota->nwq_version,
zNW_QUOTA_VERSION);
}
void nwfs_userquota_init(zNW_user_quota_s *userquota)
{
if (userquota == NULL) {
return;
}
memset(userquota, 0, sizeof(*userquota));
userquota->nwuq_byteorder = zNW_BYTEORDER;
userquota->nwuq_version = zNW_USERQUOTA_VERSION;
}
size_t nwfs_userquota_size_for_users(LONG user_num)
{
if (user_num < 0 || user_num > zMAX_XATTR_USERS) {
return 0;
}
return NWFS_USERQUOTA_FIXED_SIZE + ((size_t)user_num * sizeof(zNW_user_restriction_s));
}
LONG nwfs_userquota_max_users_for_size(size_t size)
{
size_t count;
if (size < NWFS_USERQUOTA_FIXED_SIZE) {
return -1;
}
count = (size - NWFS_USERQUOTA_FIXED_SIZE) / sizeof(zNW_user_restriction_s);
if (count > zMAX_XATTR_USERS) {
count = zMAX_XATTR_USERS;
}
return (LONG)count;
}
int nwfs_userquota_validate(const zNW_user_quota_s *userquota, size_t size)
{
int rc;
size_t needed;
if (userquota == NULL) {
return NWFS_ERR_INVAL;
}
if (size < NWFS_USERQUOTA_FIXED_SIZE) {
return NWFS_ERR_RANGE;
}
rc = nwfs_validate_header(userquota->nwuq_byteorder,
userquota->nwuq_version,
zNW_USERQUOTA_VERSION);
if (rc != NWFS_OK) {
return rc;
}
rc = nwfs_validate_count(userquota->nwuq_num_users, zMAX_XATTR_USERS);
if (rc != NWFS_OK) {
return rc;
}
needed = nwfs_userquota_size_for_users(userquota->nwuq_num_users);
if (needed == 0 || size < needed) {
return NWFS_ERR_RANGE;
}
return NWFS_OK;
}

40
src/nwfs/lsaPrivate.h Normal file
View File

@@ -0,0 +1,40 @@
/****************************************************************************
|
| (C) Copyright 1995 - 2000 Novell, Inc.
| All Rights Reserved.
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of version 2 of the GNU General Public
| License as published by the Free Software Foundation.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; if not, contact Novell, Inc.
|
| To contact Novell about this file by physical or electronic mail,
| you may find current contact information at www.novell.com
|
|***************************************************************************
|
| Novell Storage Services (NSS) support module
|
|---------------------------------------------------------------------------
| mars-nwe userspace adaptation: private declarations shared by the initial
| libnwfs.so implementation. The original kernel/VFS/MPK hooks are
| intentionally not exposed here.
+-------------------------------------------------------------------------*/
#ifndef _LSAPRIVATE_H_
#define _LSAPRIVATE_H_ 1
#include <stddef.h>
#include <nwfs/zXattr.h>
int nwfs_validate_header(WORD byteorder, WORD version, WORD expected_version);
int nwfs_validate_count(LONG count, LONG max_count);
#endif

152
src/nwfs/lsaXattr.c Normal file
View File

@@ -0,0 +1,152 @@
/****************************************************************************
|
| (C) Copyright 1995 - 2000 Novell, Inc.
| All Rights Reserved.
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of version 2 of the GNU General Public
| License as published by the Free Software Foundation.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; if not, contact Novell, Inc.
|
| To contact Novell about this file by physical or electronic mail,
| you may find current contact information at www.novell.com
|
|***************************************************************************
|
| Novell Storage Services (NSS) support module
|
|---------------------------------------------------------------------------
| mars-nwe userspace adaptation of the LSA netware.* xattr helpers. This is
| not a wrapper around NSS: it operates directly on the adapted OES/NSS GPL-2.0
| media structures that mars-nwe will store in netware.metadata, netware.quota
| and netware.userquota xattrs.
+-------------------------------------------------------------------------*/
#include <string.h>
#include <nwfs/zXattr.h>
#include "lsaPrivate.h"
int nwfs_metadata_set_file_attributes(zNW_metadata_s *metadata, QUAD attributes)
{
int rc = nwfs_metadata_validate(metadata, sizeof(*metadata));
if (rc != NWFS_OK) {
return rc;
}
metadata->nwm_modify_mask |= zMOD_FILE_ATTRIBUTES;
metadata->nwm_file_attributes = attributes;
metadata->nwm_file_attributes_mask = ~(QUAD)0;
return NWFS_OK;
}
int nwfs_metadata_get_file_attributes(const zNW_metadata_s *metadata, QUAD *attributes)
{
int rc = nwfs_metadata_validate(metadata,
nwfs_metadata_size_for_trustees(metadata ? metadata->nwm_trustee_num : 0));
if (rc != NWFS_OK) {
return rc;
}
if (attributes == NULL) {
return NWFS_ERR_INVAL;
}
*attributes = metadata->nwm_file_attributes;
return NWFS_OK;
}
int nwfs_metadata_set_inherited_rights_mask(zNW_metadata_s *metadata, LONG inherited_rights_mask)
{
int rc = nwfs_metadata_validate(metadata, sizeof(*metadata));
if (rc != NWFS_OK) {
return rc;
}
metadata->nwm_inherited_rights_mask = inherited_rights_mask;
return NWFS_OK;
}
int nwfs_metadata_get_inherited_rights_mask(const zNW_metadata_s *metadata, LONG *inherited_rights_mask)
{
int rc = nwfs_metadata_validate(metadata,
nwfs_metadata_size_for_trustees(metadata ? metadata->nwm_trustee_num : 0));
if (rc != NWFS_OK) {
return rc;
}
if (inherited_rights_mask == NULL) {
return NWFS_ERR_INVAL;
}
*inherited_rights_mask = metadata->nwm_inherited_rights_mask;
return NWFS_OK;
}
int nwfs_metadata_set_trustees(zNW_metadata_s *metadata, const zNW_trustee_s *trustees, LONG trustee_num)
{
int rc;
if (metadata == NULL) {
return NWFS_ERR_INVAL;
}
if (trustee_num < 0 || trustee_num > zMAX_TRUSTEES) {
return NWFS_ERR_RANGE;
}
if (trustee_num != 0 && trustees == NULL) {
return NWFS_ERR_INVAL;
}
rc = nwfs_metadata_validate(metadata, sizeof(*metadata));
if (rc != NWFS_OK) {
return rc;
}
if (trustee_num != 0) {
memcpy(metadata->nwm_trustee, trustees,
(size_t)trustee_num * sizeof(metadata->nwm_trustee[0]));
}
metadata->nwm_trustee_num = trustee_num;
return NWFS_OK;
}
int nwfs_metadata_get_trustees(const zNW_metadata_s *metadata,
zNW_trustee_s *trustees,
LONG trustee_capacity,
LONG *trustee_num)
{
int rc;
if (metadata == NULL || trustee_num == NULL) {
return NWFS_ERR_INVAL;
}
rc = nwfs_metadata_validate(metadata,
nwfs_metadata_size_for_trustees(metadata->nwm_trustee_num));
if (rc != NWFS_OK) {
return rc;
}
*trustee_num = metadata->nwm_trustee_num;
if (metadata->nwm_trustee_num == 0) {
return NWFS_OK;
}
if (trustees == NULL) {
return NWFS_OK;
}
if (trustee_capacity < metadata->nwm_trustee_num) {
return NWFS_ERR_RANGE;
}
memcpy(trustees, metadata->nwm_trustee,
(size_t)metadata->nwm_trustee_num * sizeof(metadata->nwm_trustee[0]));
return NWFS_OK;
}

View File

@@ -0,0 +1,3 @@
add_executable(nwfs_xattr_roundtrip_test nwfs_xattr_roundtrip_test.c)
target_link_libraries(nwfs_xattr_roundtrip_test PRIVATE mars_nwe::nwfs)
add_test(NAME nwfs_xattr_roundtrip_test COMMAND nwfs_xattr_roundtrip_test)

View File

@@ -0,0 +1,98 @@
#include <stdio.h>
#include <string.h>
#include <nwfs/zXattr.h>
#define CHECK(expr) do { \
if (!(expr)) { \
fprintf(stderr, "CHECK failed at %s:%d: %s\n", __FILE__, __LINE__, #expr); \
return 1; \
} \
} while (0)
static void fill_guid(GUID_t *guid, unsigned seed)
{
guid->timeLow = 0x10000000u + seed;
guid->timeMid = (WORD)(0x2000u + seed);
guid->timeHighAndVersion = (WORD)(0x3000u + seed);
guid->clockSeqHighAndReserved = (BYTE)(0x40u + seed);
guid->clockSeqLow = (BYTE)(0x50u + seed);
for (size_t i = 0; i < sizeof(guid->node); ++i) {
guid->node[i] = (BYTE)(seed + i);
}
}
int main(void)
{
zNW_ncpstat_s ncpstat;
zNW_metadata_s metadata;
zNW_quota_s quota;
zNW_user_quota_s userquota;
zNW_trustee_s trustees[2];
zNW_trustee_s copy[2];
QUAD attributes = 0;
LONG irm = 0;
LONG trustee_num = 0;
nwfs_ncpstat_init(&ncpstat);
CHECK(nwfs_ncpstat_validate(&ncpstat, sizeof(ncpstat)) == NWFS_OK);
CHECK(ncpstat.nws_byteorder == zNW_BYTEORDER);
CHECK(ncpstat.nws_version == zNW_NCPSTAT_VERSION);
ncpstat.nws_version = zNW_NCPSTAT_VERSION + 1;
CHECK(nwfs_ncpstat_validate(&ncpstat, sizeof(ncpstat)) == NWFS_ERR_VERSION);
nwfs_metadata_init(&metadata);
CHECK(nwfs_metadata_validate(&metadata, NWFS_METADATA_FIXED_SIZE) == NWFS_OK);
CHECK(metadata.nwm_byteorder == zNW_BYTEORDER);
CHECK(metadata.nwm_version == zNW_METADATA_VERSION);
CHECK(nwfs_metadata_set_file_attributes(&metadata, 0x00000000000000a5ULL) == NWFS_OK);
CHECK(nwfs_metadata_get_file_attributes(&metadata, &attributes) == NWFS_OK);
CHECK(attributes == 0x00000000000000a5ULL);
CHECK((metadata.nwm_modify_mask & zMOD_FILE_ATTRIBUTES) != 0);
CHECK(nwfs_metadata_set_inherited_rights_mask(&metadata, 0x000001ffU) == NWFS_OK);
CHECK(nwfs_metadata_get_inherited_rights_mask(&metadata, &irm) == NWFS_OK);
CHECK(irm == 0x000001ffU);
memset(trustees, 0, sizeof(trustees));
fill_guid(&trustees[0].nwt_id, 1);
trustees[0].nwt_rights = 0x000001ffU;
fill_guid(&trustees[1].nwt_id, 2);
trustees[1].nwt_rights = 0x00000083U;
CHECK(nwfs_metadata_set_trustees(&metadata, trustees, 2) == NWFS_OK);
CHECK(nwfs_metadata_validate(&metadata, nwfs_metadata_size_for_trustees(2)) == NWFS_OK);
memset(copy, 0, sizeof(copy));
CHECK(nwfs_metadata_get_trustees(&metadata, copy, 2, &trustee_num) == NWFS_OK);
CHECK(trustee_num == 2);
CHECK(memcmp(copy, trustees, sizeof(trustees)) == 0);
nwfs_quota_init(&quota);
quota.nwq_user_used = 1234;
quota.nwq_user_limit = 5678;
quota.nwq_dir_left = 9012;
quota.nwq_dir_quota = 3456;
CHECK(nwfs_quota_validate(&quota, sizeof(quota)) == NWFS_OK);
CHECK(quota.nwq_byteorder == zNW_BYTEORDER);
CHECK(quota.nwq_version == zNW_QUOTA_VERSION);
CHECK(quota.nwq_user_used == 1234);
CHECK(quota.nwq_user_limit == 5678);
CHECK(quota.nwq_dir_left == 9012);
CHECK(quota.nwq_dir_quota == 3456);
nwfs_userquota_init(&userquota);
userquota.nwuq_num_users = 1;
userquota.nwuq_index = 7;
fill_guid(&userquota.nwuq_user[0].nwur_user, 3);
userquota.nwuq_user[0].nwur_restriction = 0x12345678LL;
CHECK(nwfs_userquota_validate(&userquota, nwfs_userquota_size_for_users(1)) == NWFS_OK);
CHECK(userquota.nwuq_byteorder == zNW_BYTEORDER);
CHECK(userquota.nwuq_version == zNW_USERQUOTA_VERSION);
CHECK(userquota.nwuq_num_users == 1);
CHECK(userquota.nwuq_index == 7);
CHECK(userquota.nwuq_user[0].nwur_restriction == 0x12345678LL);
metadata.nwm_byteorder = 0;
CHECK(nwfs_metadata_validate(&metadata, sizeof(metadata)) == NWFS_ERR_BYTEORDER);
return 0;
}