All checks were successful
Source release / source-package (push) Successful in 48s
Move the mars_nwe NetWare-core archive/fileinfo xattr names from the flat org.mars-nwe namespace into an explicit org.mars-nwe.netware subnamespace. The earlier xattr namespace cleanup intentionally removed the unreleased user.mars_nwe names and introduced Netatalk-style org.mars-nwe source-level keys. Keeping archive and fileinfo at org.mars-nwe.archive and org.mars-nwe.fileinfo would make those NetWare server metadata records peers of AFP metadata instead of identifying their ownership. The archive date/time/archiver and file create/creator/modifier records are NetWare-core file metadata, so place them under org.mars-nwe.netware.* while leaving AFP metadata under org.mars-nwe.afp.*. No legacy fallback is added because the old names only existed in local test systems and have not been released. The existing nwxattr wrapper still maps source-level org.mars-nwe.<domain>.* names to user.org.mars-nwe.<domain>.* on Linux, mirroring Netatalk's org.netatalk.* EA abstraction. Tests: git diff --check TODO: keep future nwbind/nwserv/AFP metadata in explicit org.mars-nwe.<domain>.* subnamespaces instead of adding new flat org.mars-nwe.* keys.
358 lines
9.6 KiB
C
358 lines
9.6 KiB
C
/* nwarchive.c - mars_nwe private archive metadata helpers */
|
|
#include "net.h"
|
|
#include "nwarchive.h"
|
|
#include "nwxattr.h"
|
|
|
|
#if XATTR_SUPPORT
|
|
#include <errno.h>
|
|
#endif
|
|
|
|
#define MARS_NWE_ARCHIVE_XATTR "org.mars-nwe.netware.archive"
|
|
#define MARS_NWE_ARCHIVE_VERSION 1
|
|
|
|
typedef struct {
|
|
uint8 version;
|
|
uint8 flags;
|
|
uint8 archive_date[2];
|
|
uint8 archive_time[2];
|
|
uint8 archiver_id[4];
|
|
} MARS_NWE_ARCHIVE_XATTR_DATA;
|
|
|
|
static void init_archive_data(MARS_NWE_ARCHIVE_XATTR_DATA *d)
|
|
{
|
|
memset(d, 0, sizeof(*d));
|
|
d->version = MARS_NWE_ARCHIVE_VERSION;
|
|
}
|
|
|
|
static void read_archive_data(MARS_NWE_ARCHIVE_XATTR_DATA *d,
|
|
uint16 *archive_date,
|
|
uint16 *archive_time,
|
|
uint32 *archiver_id,
|
|
uint8 *flags)
|
|
{
|
|
if (flags)
|
|
*flags = d->flags;
|
|
if (archive_date)
|
|
*archive_date = (d->flags & MARS_NWE_ARCHIVE_HAS_DATE)
|
|
? (uint16)GET_16(d->archive_date) : 0;
|
|
if (archive_time)
|
|
*archive_time = (d->flags & MARS_NWE_ARCHIVE_HAS_TIME)
|
|
? (uint16)GET_16(d->archive_time) : 0;
|
|
if (archiver_id)
|
|
*archiver_id = (d->flags & MARS_NWE_ARCHIVE_HAS_ARCHIVER)
|
|
? GET_BE32(d->archiver_id) : 0;
|
|
}
|
|
|
|
#if XATTR_SUPPORT
|
|
static int get_archive_data(char *unixname, MARS_NWE_ARCHIVE_XATTR_DATA *d)
|
|
{
|
|
ssize_t len;
|
|
|
|
init_archive_data(d);
|
|
if (!unixname || !*unixname)
|
|
return(-1);
|
|
|
|
len = mars_nwe_getxattr(unixname, MARS_NWE_ARCHIVE_XATTR, d, sizeof(*d));
|
|
if (len != sizeof(*d) || d->version != MARS_NWE_ARCHIVE_VERSION) {
|
|
init_archive_data(d);
|
|
return(-1);
|
|
}
|
|
return(0);
|
|
}
|
|
#endif
|
|
|
|
void mars_nwe_get_archive_info(char *unixname,
|
|
uint16 *archive_date,
|
|
uint16 *archive_time,
|
|
uint32 *archiver_id,
|
|
uint8 *flags)
|
|
{
|
|
MARS_NWE_ARCHIVE_XATTR_DATA d;
|
|
|
|
#if XATTR_SUPPORT
|
|
(void)get_archive_data(unixname, &d);
|
|
#else
|
|
(void)unixname;
|
|
init_archive_data(&d);
|
|
#endif
|
|
read_archive_data(&d, archive_date, archive_time, archiver_id, flags);
|
|
}
|
|
|
|
int mars_nwe_set_archive_info(char *unixname,
|
|
int set_date, uint16 archive_date,
|
|
int set_time, uint16 archive_time,
|
|
int set_archiver, uint32 archiver_id)
|
|
{
|
|
#if XATTR_SUPPORT
|
|
MARS_NWE_ARCHIVE_XATTR_DATA d;
|
|
|
|
(void)get_archive_data(unixname, &d);
|
|
|
|
if (set_date) {
|
|
U16_TO_16(archive_date, d.archive_date);
|
|
if (archive_date)
|
|
d.flags |= MARS_NWE_ARCHIVE_HAS_DATE;
|
|
else
|
|
d.flags &= (uint8)~MARS_NWE_ARCHIVE_HAS_DATE;
|
|
}
|
|
if (set_time) {
|
|
U16_TO_16(archive_time, d.archive_time);
|
|
if (archive_time)
|
|
d.flags |= MARS_NWE_ARCHIVE_HAS_TIME;
|
|
else
|
|
d.flags &= (uint8)~MARS_NWE_ARCHIVE_HAS_TIME;
|
|
}
|
|
if (set_archiver) {
|
|
U32_TO_BE32(archiver_id, d.archiver_id);
|
|
if (archiver_id)
|
|
d.flags |= MARS_NWE_ARCHIVE_HAS_ARCHIVER;
|
|
else
|
|
d.flags &= (uint8)~MARS_NWE_ARCHIVE_HAS_ARCHIVER;
|
|
}
|
|
|
|
if (!unixname || !*unixname)
|
|
return(0);
|
|
|
|
if (!d.flags) {
|
|
if (mars_nwe_removexattr(unixname, MARS_NWE_ARCHIVE_XATTR)) {
|
|
int err = errno;
|
|
if (err != ENODATA
|
|
#ifdef ENOATTR
|
|
&& err != ENOATTR
|
|
#endif
|
|
)
|
|
XDPRINTF((5,0,"mars_nwe archive xattr remove ignored for %s errno=%d", unixname, err));
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
if (mars_nwe_setxattr(unixname, MARS_NWE_ARCHIVE_XATTR, &d, sizeof(d), 0)) {
|
|
int err = errno;
|
|
/* Compatibility rule: NetWare archive metadata has no POSIX field.
|
|
* If Linux xattrs are unavailable or rejected, keep the NCP call
|
|
* successful and only log that the extra metadata was not stored.
|
|
*/
|
|
XDPRINTF((5,0,"mars_nwe archive xattr ignored for %s errno=%d", unixname, err));
|
|
}
|
|
#else
|
|
(void)unixname;
|
|
(void)set_date;
|
|
(void)archive_date;
|
|
(void)set_time;
|
|
(void)archive_time;
|
|
(void)set_archiver;
|
|
(void)archiver_id;
|
|
#endif
|
|
return(0);
|
|
}
|
|
|
|
|
|
#define MARS_NWE_FILEINFO_XATTR "org.mars-nwe.netware.fileinfo"
|
|
#define MARS_NWE_FILEINFO_VERSION 1
|
|
|
|
typedef struct {
|
|
uint8 version;
|
|
uint8 flags;
|
|
uint8 create_date[2];
|
|
uint8 create_time[2];
|
|
uint8 creator_id[4];
|
|
uint8 modifier_id[4];
|
|
} MARS_NWE_FILEINFO_XATTR_DATA;
|
|
|
|
#define MARS_NWE_FILEINFO_XATTR_V1_SIZE 10
|
|
|
|
static void init_file_info_data(MARS_NWE_FILEINFO_XATTR_DATA *d)
|
|
{
|
|
memset(d, 0, sizeof(*d));
|
|
d->version = MARS_NWE_FILEINFO_VERSION;
|
|
}
|
|
|
|
static void read_file_info_data(MARS_NWE_FILEINFO_XATTR_DATA *d,
|
|
uint16 *create_date,
|
|
uint16 *create_time,
|
|
uint32 *creator_id,
|
|
uint32 *modifier_id,
|
|
uint8 *flags)
|
|
{
|
|
if (flags)
|
|
*flags = d->flags;
|
|
if (create_date)
|
|
*create_date = (d->flags & MARS_NWE_FILEINFO_HAS_CREATE_DATE)
|
|
? (uint16)GET_16(d->create_date) : 0;
|
|
if (create_time)
|
|
*create_time = (d->flags & MARS_NWE_FILEINFO_HAS_CREATE_TIME)
|
|
? (uint16)GET_16(d->create_time) : 0;
|
|
if (creator_id)
|
|
*creator_id = (d->flags & MARS_NWE_FILEINFO_HAS_CREATOR)
|
|
? GET_BE32(d->creator_id) : 0;
|
|
if (modifier_id)
|
|
*modifier_id = (d->flags & MARS_NWE_FILEINFO_HAS_MODIFIER)
|
|
? GET_BE32(d->modifier_id) : 0;
|
|
}
|
|
|
|
#if XATTR_SUPPORT
|
|
static int get_file_info_data(char *unixname, MARS_NWE_FILEINFO_XATTR_DATA *d)
|
|
{
|
|
ssize_t len;
|
|
|
|
init_file_info_data(d);
|
|
if (!unixname || !*unixname)
|
|
return(-1);
|
|
|
|
len = mars_nwe_getxattr(unixname, MARS_NWE_FILEINFO_XATTR, d, sizeof(*d));
|
|
if ((len != sizeof(*d) && len != MARS_NWE_FILEINFO_XATTR_V1_SIZE) ||
|
|
d->version != MARS_NWE_FILEINFO_VERSION) {
|
|
init_file_info_data(d);
|
|
return(-1);
|
|
}
|
|
return(0);
|
|
}
|
|
#endif
|
|
|
|
void mars_nwe_get_file_info(char *unixname,
|
|
uint16 *create_date,
|
|
uint16 *create_time,
|
|
uint32 *creator_id,
|
|
uint8 *flags)
|
|
{
|
|
MARS_NWE_FILEINFO_XATTR_DATA d;
|
|
|
|
#if XATTR_SUPPORT
|
|
(void)get_file_info_data(unixname, &d);
|
|
#else
|
|
(void)unixname;
|
|
init_file_info_data(&d);
|
|
#endif
|
|
read_file_info_data(&d, create_date, create_time, creator_id, NULL, flags);
|
|
}
|
|
|
|
void mars_nwe_get_file_modifier_info(char *unixname,
|
|
uint32 *modifier_id,
|
|
uint8 *flags)
|
|
{
|
|
MARS_NWE_FILEINFO_XATTR_DATA d;
|
|
|
|
#if XATTR_SUPPORT
|
|
(void)get_file_info_data(unixname, &d);
|
|
#else
|
|
(void)unixname;
|
|
init_file_info_data(&d);
|
|
#endif
|
|
read_file_info_data(&d, NULL, NULL, NULL, modifier_id, flags);
|
|
}
|
|
|
|
int mars_nwe_set_file_info(char *unixname,
|
|
int set_create_date, uint16 create_date,
|
|
int set_create_time, uint16 create_time,
|
|
int set_creator, uint32 creator_id)
|
|
{
|
|
#if XATTR_SUPPORT
|
|
MARS_NWE_FILEINFO_XATTR_DATA d;
|
|
|
|
(void)get_file_info_data(unixname, &d);
|
|
|
|
if (set_create_date) {
|
|
U16_TO_16(create_date, d.create_date);
|
|
if (create_date)
|
|
d.flags |= MARS_NWE_FILEINFO_HAS_CREATE_DATE;
|
|
else
|
|
d.flags &= (uint8)~MARS_NWE_FILEINFO_HAS_CREATE_DATE;
|
|
}
|
|
if (set_create_time) {
|
|
U16_TO_16(create_time, d.create_time);
|
|
if (create_time)
|
|
d.flags |= MARS_NWE_FILEINFO_HAS_CREATE_TIME;
|
|
else
|
|
d.flags &= (uint8)~MARS_NWE_FILEINFO_HAS_CREATE_TIME;
|
|
}
|
|
if (set_creator) {
|
|
U32_TO_BE32(creator_id, d.creator_id);
|
|
if (creator_id)
|
|
d.flags |= MARS_NWE_FILEINFO_HAS_CREATOR;
|
|
else
|
|
d.flags &= (uint8)~MARS_NWE_FILEINFO_HAS_CREATOR;
|
|
}
|
|
|
|
if (!unixname || !*unixname)
|
|
return(0);
|
|
|
|
if (!d.flags) {
|
|
if (mars_nwe_removexattr(unixname, MARS_NWE_FILEINFO_XATTR)) {
|
|
int err = errno;
|
|
#if defined(ENOATTR)
|
|
if (err != ENODATA && err != ENOATTR)
|
|
#else
|
|
if (err != ENODATA)
|
|
#endif
|
|
XDPRINTF((5,0,"mars_nwe fileinfo xattr remove ignored for %s errno=%d", unixname, err));
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
if (mars_nwe_setxattr(unixname, MARS_NWE_FILEINFO_XATTR, &d, sizeof(d), 0)) {
|
|
int err = errno;
|
|
/* Compatibility rule: creator metadata has no portable POSIX field.
|
|
* Keep the NCP call successful and only log the missing persistence.
|
|
*/
|
|
XDPRINTF((5,0,"mars_nwe fileinfo xattr ignored for %s errno=%d", unixname, err));
|
|
}
|
|
#else
|
|
(void)unixname;
|
|
(void)set_create_date;
|
|
(void)create_date;
|
|
(void)set_create_time;
|
|
(void)create_time;
|
|
(void)set_creator;
|
|
(void)creator_id;
|
|
#endif
|
|
return(0);
|
|
}
|
|
|
|
|
|
int mars_nwe_set_file_modifier_info(char *unixname,
|
|
int set_modifier, uint32 modifier_id)
|
|
{
|
|
#if XATTR_SUPPORT
|
|
MARS_NWE_FILEINFO_XATTR_DATA d;
|
|
|
|
(void)get_file_info_data(unixname, &d);
|
|
|
|
if (set_modifier) {
|
|
U32_TO_BE32(modifier_id, d.modifier_id);
|
|
if (modifier_id)
|
|
d.flags |= MARS_NWE_FILEINFO_HAS_MODIFIER;
|
|
else
|
|
d.flags &= (uint8)~MARS_NWE_FILEINFO_HAS_MODIFIER;
|
|
}
|
|
|
|
if (!unixname || !*unixname)
|
|
return(0);
|
|
|
|
if (!d.flags) {
|
|
if (mars_nwe_removexattr(unixname, MARS_NWE_FILEINFO_XATTR)) {
|
|
int err = errno;
|
|
#if defined(ENOATTR)
|
|
if (err != ENODATA && err != ENOATTR)
|
|
#else
|
|
if (err != ENODATA)
|
|
#endif
|
|
XDPRINTF((5,0,"mars_nwe fileinfo xattr remove ignored for %s errno=%d", unixname, err));
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
if (mars_nwe_setxattr(unixname, MARS_NWE_FILEINFO_XATTR, &d, sizeof(d), 0)) {
|
|
int err = errno;
|
|
/* Compatibility rule: modifier metadata has no portable POSIX field.
|
|
* Keep the NCP call successful and only log the missing persistence.
|
|
*/
|
|
XDPRINTF((5,0,"mars_nwe fileinfo xattr ignored for %s errno=%d", unixname, err));
|
|
}
|
|
#else
|
|
(void)unixname;
|
|
(void)set_modifier;
|
|
(void)modifier_id;
|
|
#endif
|
|
return(0);
|
|
}
|