tests: add ncpfs quota smoke helpers
Some checks failed
Source release / source-package (push) Failing after 24s
Some checks failed
Source release / source-package (push) Failing after 24s
This commit is contained in:
@@ -58,11 +58,13 @@ static int act_umode_file=0;
|
||||
#include "nwattrib.h"
|
||||
#include "nwarchive.h"
|
||||
#include "trustee.h"
|
||||
#include "nwxattr.h"
|
||||
#include "nwfile.h"
|
||||
#include "nwconn.h"
|
||||
#include "namspace.h"
|
||||
#include "namedos.h"
|
||||
#include "connect.h"
|
||||
#include <nwfs/zXattr.h>
|
||||
|
||||
/* connect.h may already be include-guarded through another header before
|
||||
* NW_VOL is visible, so keep this local forward declaration before the
|
||||
@@ -1466,6 +1468,40 @@ static int set_ncp22_25_file_info(char *unixname,
|
||||
}
|
||||
|
||||
|
||||
static int set_ncp22_25_dir_quota_metadata(char *unixname, uint32 max_space)
|
||||
{
|
||||
zNW_metadata_s metadata;
|
||||
ssize_t len;
|
||||
size_t size;
|
||||
SQUAD quota;
|
||||
|
||||
if (unixname == NULL)
|
||||
return(-0x8c);
|
||||
|
||||
memset(&metadata, 0, sizeof(metadata));
|
||||
len = mars_nwe_getxattr(unixname, zNW_METADATA, &metadata, sizeof(metadata));
|
||||
if (len < 0) {
|
||||
nwfs_metadata_init(&metadata);
|
||||
} else if (nwfs_metadata_validate(&metadata, (size_t)len) != NWFS_OK) {
|
||||
XDPRINTF((2,0, "invalid netware.metadata while setting dir quota: %s", unixname));
|
||||
return(-0x8c);
|
||||
}
|
||||
|
||||
if (max_space == MAX_U32 || max_space == 0x40000000UL)
|
||||
quota = zDIR_NO_QUOTA;
|
||||
else
|
||||
quota = (SQUAD)max_space;
|
||||
|
||||
if (nwfs_metadata_set_quota_limit(&metadata, quota) != NWFS_OK)
|
||||
return(-0x8c);
|
||||
|
||||
size = nwfs_metadata_size_for_trustees(metadata.nwm_trustee_num);
|
||||
if (size == 0 || mars_nwe_setxattr(unixname, zNW_METADATA, &metadata, size, 0))
|
||||
return(-0x8c);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int set_ncp22_25_maximum_space(int volume, char *unixname,
|
||||
struct stat *stb,
|
||||
NW_SET_DIR_INFO *f,
|
||||
@@ -1473,16 +1509,15 @@ static int set_ncp22_25_maximum_space(int volume, char *unixname,
|
||||
int is_dir)
|
||||
{
|
||||
uint32 max_space;
|
||||
uint32 quota;
|
||||
int result;
|
||||
|
||||
if (!(change_mask & DM_MAXIMUM_SPACE))
|
||||
return(0);
|
||||
|
||||
/* NetWare exposes maximum space on directory entries. mars_nwe already
|
||||
* has a Linux user-quota backend for volume restrictions; use that as the
|
||||
* closest available mapping. Files have no max_space field in the DOS
|
||||
* layout, so ignore the bit if a client sends it for a file.
|
||||
/* NetWare/NSS exposes maximum space on directory entries. Keep it in the
|
||||
* OES-compatible netware.metadata nwm_quota_limit field; user/volume
|
||||
* restrictions are a separate netware.userquota data model and are handled
|
||||
* by the volume-restriction NCPs.
|
||||
*/
|
||||
if (!is_dir) {
|
||||
XDPRINTF((5,0,
|
||||
@@ -1495,26 +1530,10 @@ static int set_ncp22_25_maximum_space(int volume, char *unixname,
|
||||
return(-0x8c);
|
||||
|
||||
max_space = GET_BE32(f->u.d.max_space);
|
||||
|
||||
/* Treat the common unlimited sentinels as "remove restriction". */
|
||||
if (max_space == MAX_U32 || max_space == 0x40000000UL)
|
||||
quota = 0;
|
||||
else
|
||||
quota = max_space;
|
||||
|
||||
result = nw_set_vol_restrictions((uint8)volume, act_uid, quota);
|
||||
if (result) {
|
||||
/* If quota support is not compiled/enabled, do not break old clients. */
|
||||
XDPRINTF((5,0,
|
||||
"NCP22/25 maximum space quota ignored: vol=%d uid=%d max=0x%08lx rc=%d",
|
||||
volume, act_uid, (unsigned long)max_space, result));
|
||||
if (result == -0xfb)
|
||||
return(0);
|
||||
} else {
|
||||
XDPRINTF((5,0,
|
||||
"NCP22/25 maximum space quota set: vol=%d uid=%d max=0x%08lx quota=0x%08lx",
|
||||
volume, act_uid, (unsigned long)max_space, (unsigned long)quota));
|
||||
}
|
||||
result = set_ncp22_25_dir_quota_metadata(unixname, max_space);
|
||||
XDPRINTF((5,0,
|
||||
"NCP22/25 directory quota metadata set: vol=%d path=%s max=0x%08lx rc=%d",
|
||||
volume, unixname ? unixname : "", (unsigned long)max_space, result));
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,29 @@ target_link_libraries(nwfs_xattr_dump PRIVATE mars_nwe::nwfs ${XATTR_LIBRARIES})
|
||||
add_executable(nwfs_xattr_edit nwfs_xattr_edit.c)
|
||||
target_link_libraries(nwfs_xattr_edit PRIVATE mars_nwe::nwfs ${XATTR_LIBRARIES})
|
||||
|
||||
find_path(NCPFS_INCLUDE_DIR
|
||||
NAMES ncp/nwcalls.h
|
||||
)
|
||||
find_library(NCPFS_LIBRARY
|
||||
NAMES ncp
|
||||
)
|
||||
|
||||
set(NWFS_NCPFS_DIRQUOTA_HELPER "")
|
||||
set(NWFS_NCPFS_USERQUOTA_HELPER "")
|
||||
if(NCPFS_INCLUDE_DIR AND NCPFS_LIBRARY)
|
||||
add_executable(nwfs_ncpfs_dirquota nwfs_ncpfs_dirquota.c)
|
||||
target_include_directories(nwfs_ncpfs_dirquota PRIVATE ${NCPFS_INCLUDE_DIR})
|
||||
target_link_libraries(nwfs_ncpfs_dirquota PRIVATE ${NCPFS_LIBRARY})
|
||||
set(NWFS_NCPFS_DIRQUOTA_HELPER "${CMAKE_CURRENT_BINARY_DIR}/nwfs_ncpfs_dirquota")
|
||||
|
||||
add_executable(nwfs_ncpfs_userquota nwfs_ncpfs_userquota.c)
|
||||
target_include_directories(nwfs_ncpfs_userquota PRIVATE ${NCPFS_INCLUDE_DIR})
|
||||
target_link_libraries(nwfs_ncpfs_userquota PRIVATE ${NCPFS_LIBRARY})
|
||||
set(NWFS_NCPFS_USERQUOTA_HELPER "${CMAKE_CURRENT_BINARY_DIR}/nwfs_ncpfs_userquota")
|
||||
else()
|
||||
message(STATUS "ncpfs/libncp not found; manual nwfs NCPFS quota smoke helpers disabled")
|
||||
endif()
|
||||
|
||||
configure_file(nwfs_metadata_xattr_file_test.sh.in nwfs_metadata_xattr_file_test.sh @ONLY)
|
||||
add_test(NAME nwfs_metadata_xattr_file_test COMMAND sh ${CMAKE_CURRENT_BINARY_DIR}/nwfs_metadata_xattr_file_test.sh)
|
||||
|
||||
|
||||
125
tests/nwfs/nwfs_ncpfs_dirquota.c
Normal file
125
tests/nwfs/nwfs_ncpfs_dirquota.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Manual NCPFS smoke helper for NetWare directory space limits.
|
||||
*
|
||||
* This is intentionally small and is based on the ncpfs contrib/testing
|
||||
* dirlimit.c example by Petr Vandrovec. It mutates a directory through
|
||||
* libncp/NCPFS so the host-side test can verify the mars-nwe
|
||||
* netware.metadata directory-quota xattr afterwards.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <ncp/nwcalls.h>
|
||||
#include <ncp/nwnet.h>
|
||||
|
||||
static void usage(const char *prog)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: %s [-l LIMIT_4K] [-p VOLUME:PATH] NCPFS_MOUNTED_PATH\n"
|
||||
"\n"
|
||||
"Sets the NetWare DOS-info MaximumSpace field through libncp.\n"
|
||||
"LIMIT_4K is in 4 KiB NetWare blocks, matching ncpfs dirlimit.c.\n",
|
||||
prog);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
NWDSCCODE err;
|
||||
NWCONN_HANDLE conn = NULL;
|
||||
char volume[1000];
|
||||
char volpath[1000];
|
||||
char remote[2000];
|
||||
unsigned char nwpath[1000];
|
||||
const char *override_path = NULL;
|
||||
const char *mounted_path;
|
||||
unsigned long limit = 0;
|
||||
int set_limit = 0;
|
||||
int opt;
|
||||
int len;
|
||||
|
||||
if (NWCallsInit(NULL, NULL)) {
|
||||
fprintf(stderr, "NWCallsInit failed\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "h?p:l:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'l':
|
||||
errno = 0;
|
||||
limit = strtoul(optarg, NULL, 0);
|
||||
if (errno || limit > 0xffffffffUL) {
|
||||
fprintf(stderr, "invalid limit: %s\n", optarg);
|
||||
return 2;
|
||||
}
|
||||
set_limit = 1;
|
||||
break;
|
||||
case 'p':
|
||||
override_path = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
usage(argv[0]);
|
||||
return opt == 'h' ? 0 : 2;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (!set_limit || optind + 1 != argc) {
|
||||
usage(argv[0]);
|
||||
return 2;
|
||||
}
|
||||
mounted_path = argv[optind];
|
||||
|
||||
err = NWParsePath(mounted_path, NULL, &conn, volume, volpath);
|
||||
if (err) {
|
||||
fprintf(stderr, "NWParsePath failed for %s: %s\n", mounted_path, strnwerror(err));
|
||||
return 1;
|
||||
}
|
||||
if (!conn) {
|
||||
fprintf(stderr, "path is not on an NCPFS mount: %s\n", mounted_path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (override_path) {
|
||||
len = ncp_path_to_NW_format(override_path, nwpath, sizeof(nwpath));
|
||||
} else {
|
||||
if ((size_t)snprintf(remote, sizeof(remote), "%s:%s", volume, volpath) >= sizeof(remote)) {
|
||||
fprintf(stderr, "remote path too long\n");
|
||||
ncp_close(conn);
|
||||
return 2;
|
||||
}
|
||||
len = ncp_path_to_NW_format(remote, nwpath, sizeof(nwpath));
|
||||
}
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "cannot convert remote path: %s\n", strerror(-len));
|
||||
ncp_close(conn);
|
||||
return 1;
|
||||
}
|
||||
|
||||
{
|
||||
struct ncp_dos_info info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.MaximumSpace = limit;
|
||||
err = ncp_ns_modify_entry_dos_info(conn, NW_NS_DOS, SA_ALL,
|
||||
NCP_DIRSTYLE_NOHANDLE,
|
||||
0, 0, nwpath, len,
|
||||
DM_MAXIMUM_SPACE, &info);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
fprintf(stderr, "cannot set directory quota on %s: %s\n", mounted_path, strnwerror(err));
|
||||
ncp_close(conn);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("directory quota set path=%s limit4k=%lu\n", mounted_path, limit);
|
||||
ncp_close(conn);
|
||||
return 0;
|
||||
}
|
||||
@@ -9,6 +9,8 @@ if [ "$#" -lt 4 ]; then
|
||||
echo "example: $0 localhost supervisor secret /var/local/mars_nwe/SYS /mnt/nw-sys SYSTEM/NWFSTEST SYS" >&2
|
||||
echo "TESTDIR defaults to NWFSTEST. If the volume root is not creatable through NCP, pass an existing writable directory below SYS." >&2
|
||||
echo "Set NWFS_NCPFS_TRUSTEE_OBJECT and NWFS_NCPFS_TRUSTEE_TYPE to override the default GUEST user trustee mutation." >&2
|
||||
echo "Set NWFS_NCPFS_DIR_QUOTA_4K to override the default directory quota limit; set it empty to skip." >&2
|
||||
echo "Set NWFS_NCPFS_USER_QUOTA_4K to enable the user-volume restriction smoke. The server must run with NWFS_QUOTA_BACKEND=METADATAONLY for netware.userquota." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
@@ -23,6 +25,12 @@ TRUSTEE_OBJECT=${NWFS_NCPFS_TRUSTEE_OBJECT:-GUEST}
|
||||
TRUSTEE_TYPE=${NWFS_NCPFS_TRUSTEE_TYPE:-1}
|
||||
TRUSTEE_RIGHTS=${NWFS_NCPFS_TRUSTEE_RIGHTS:-RF}
|
||||
DUMP="@CMAKE_CURRENT_BINARY_DIR@/nwfs_xattr_dump"
|
||||
DIRQUOTA_HELPER="@NWFS_NCPFS_DIRQUOTA_HELPER@"
|
||||
USERQUOTA_HELPER="@NWFS_NCPFS_USERQUOTA_HELPER@"
|
||||
DIR_QUOTA_4K=${NWFS_NCPFS_DIR_QUOTA_4K-321}
|
||||
USER_QUOTA_4K=${NWFS_NCPFS_USER_QUOTA_4K-}
|
||||
USER_QUOTA_OBJECT=${NWFS_NCPFS_USER_QUOTA_OBJECT:-$TRUSTEE_OBJECT}
|
||||
USER_QUOTA_TYPE=${NWFS_NCPFS_USER_QUOTA_TYPE:-$TRUSTEE_TYPE}
|
||||
MKDIR_ERR=$(mktemp "${TMPDIR:-/tmp}/nwfs_ncpfs_mkdir.XXXXXX")
|
||||
WRITE_ERR=$(mktemp "${TMPDIR:-/tmp}/nwfs_ncpfs_write.XXXXXX")
|
||||
GRANT_ERR=$(mktemp "${TMPDIR:-/tmp}/nwfs_ncpfs_grant.XXXXXX")
|
||||
@@ -129,3 +137,41 @@ if command -v nwrevoke >/dev/null 2>&1; then
|
||||
else
|
||||
echo "nwrevoke not found; skipping trustee-remove mutation" >&2
|
||||
fi
|
||||
|
||||
if [ -n "$DIR_QUOTA_4K" ]; then
|
||||
if [ -n "$DIRQUOTA_HELPER" ] && [ -x "$DIRQUOTA_HELPER" ]; then
|
||||
echo "setting directory quota ${DIR_QUOTA_4K}x4K on $NCP_TEST_PATH" >&2
|
||||
"$DIRQUOTA_HELPER" -l "$DIR_QUOTA_4K" "$NCP_TEST_PATH"
|
||||
sync
|
||||
printf '\n# after directory quota set\n'
|
||||
"$DUMP" "$HOST_TEST_PATH"
|
||||
else
|
||||
echo "nwfs_ncpfs_dirquota helper not built; skipping directory quota mutation" >&2
|
||||
fi
|
||||
else
|
||||
echo "NWFS_NCPFS_DIR_QUOTA_4K is empty; skipping directory quota mutation" >&2
|
||||
fi
|
||||
|
||||
if [ -n "$USER_QUOTA_4K" ]; then
|
||||
if [ -n "$USERQUOTA_HELPER" ] && [ -x "$USERQUOTA_HELPER" ]; then
|
||||
echo "setting user quota ${USER_QUOTA_4K}x4K for $USER_QUOTA_OBJECT type $USER_QUOTA_TYPE on $VOLUME" >&2
|
||||
"$USERQUOTA_HELPER" -S "$SERVER" -U "$USER" -P "$PASSWORD" \
|
||||
--volume "$VOLUME" --object "$USER_QUOTA_OBJECT" --type "$USER_QUOTA_TYPE" \
|
||||
--limit-4k "$USER_QUOTA_4K"
|
||||
sync
|
||||
printf '\n# after user quota set\n'
|
||||
"$DUMP" "$SYSROOT"
|
||||
|
||||
echo "removing user quota for $USER_QUOTA_OBJECT type $USER_QUOTA_TYPE on $VOLUME" >&2
|
||||
"$USERQUOTA_HELPER" -S "$SERVER" -U "$USER" -P "$PASSWORD" \
|
||||
--volume "$VOLUME" --object "$USER_QUOTA_OBJECT" --type "$USER_QUOTA_TYPE" \
|
||||
--remove
|
||||
sync
|
||||
printf '\n# after user quota remove\n'
|
||||
"$DUMP" "$SYSROOT"
|
||||
else
|
||||
echo "nwfs_ncpfs_userquota helper not built; skipping user quota mutation" >&2
|
||||
fi
|
||||
else
|
||||
echo "NWFS_NCPFS_USER_QUOTA_4K not set; skipping user quota mutation" >&2
|
||||
fi
|
||||
|
||||
164
tests/nwfs/nwfs_ncpfs_userquota.c
Normal file
164
tests/nwfs/nwfs_ncpfs_userquota.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Manual NCP/libncp smoke helper for NetWare volume/user restrictions.
|
||||
*
|
||||
* It uses the same public ncpfs/NWCalls APIs as ncpfs contrib/testing/pp/volres.c
|
||||
* so tests mutate the server through NCP and verify netware.userquota on the
|
||||
* host SYS root afterwards.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ncp/nwcalls.h>
|
||||
#include <ncp/nwnet.h>
|
||||
#include <ncp/ncplib.h>
|
||||
|
||||
static void usage(const char *prog)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: %s [ncpfs options] --volume VOL --object NAME --type TYPE (--limit-4k LIMIT | --remove)\n"
|
||||
"\n"
|
||||
"ncpfs options are parsed by ncp_initialize(), for example:\n"
|
||||
" -S MARS -U SUPERVISOR -P secret\n",
|
||||
prog);
|
||||
}
|
||||
|
||||
static int parse_u32(const char *text, uint32_t *value)
|
||||
{
|
||||
char *end = NULL;
|
||||
unsigned long v;
|
||||
|
||||
errno = 0;
|
||||
v = strtoul(text, &end, 0);
|
||||
if (errno || !end || *end || v > 0xffffffffUL)
|
||||
return -1;
|
||||
*value = (uint32_t)v;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
NWCONN_HANDLE conn;
|
||||
long init_err = 0;
|
||||
const char *volume = NULL;
|
||||
const char *object = NULL;
|
||||
uint32_t object_type = 1;
|
||||
uint32_t limit = 0;
|
||||
int have_limit = 0;
|
||||
int remove_limit = 0;
|
||||
int i;
|
||||
NWCCODE err;
|
||||
NWVOL_NUM volnum;
|
||||
nuint32 object_id;
|
||||
nuint32 restriction = 0;
|
||||
nuint32 in_use = 0;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) {
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (NWCallsInit(NULL, NULL)) {
|
||||
fprintf(stderr, "NWCallsInit failed\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
conn = ncp_initialize(&argc, argv, 1, &init_err);
|
||||
if (!conn) {
|
||||
fprintf(stderr, "ncp_initialize/login failed: %ld\n", init_err);
|
||||
usage(argv[0]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (!strcmp(argv[i], "--volume")) {
|
||||
if (++i >= argc) {
|
||||
usage(argv[0]);
|
||||
ncp_close(conn);
|
||||
return 2;
|
||||
}
|
||||
volume = argv[i];
|
||||
} else if (!strcmp(argv[i], "--object")) {
|
||||
if (++i >= argc) {
|
||||
usage(argv[0]);
|
||||
ncp_close(conn);
|
||||
return 2;
|
||||
}
|
||||
object = argv[i];
|
||||
} else if (!strcmp(argv[i], "--type")) {
|
||||
if (++i >= argc || parse_u32(argv[i], &object_type)) {
|
||||
fprintf(stderr, "invalid --type value\n");
|
||||
ncp_close(conn);
|
||||
return 2;
|
||||
}
|
||||
} else if (!strcmp(argv[i], "--limit-4k")) {
|
||||
if (++i >= argc || parse_u32(argv[i], &limit)) {
|
||||
fprintf(stderr, "invalid --limit-4k value\n");
|
||||
ncp_close(conn);
|
||||
return 2;
|
||||
}
|
||||
have_limit = 1;
|
||||
} else if (!strcmp(argv[i], "--remove")) {
|
||||
remove_limit = 1;
|
||||
} else {
|
||||
fprintf(stderr, "unknown argument: %s\n", argv[i]);
|
||||
usage(argv[0]);
|
||||
ncp_close(conn);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (!volume || !object || (have_limit == remove_limit)) {
|
||||
usage(argv[0]);
|
||||
ncp_close(conn);
|
||||
return 2;
|
||||
}
|
||||
|
||||
err = NWGetVolumeNumber(conn, volume, &volnum);
|
||||
if (err) {
|
||||
fprintf(stderr, "NWGetVolumeNumber(%s) failed: %s\n", volume, strnwerror(err));
|
||||
ncp_close(conn);
|
||||
return 1;
|
||||
}
|
||||
|
||||
err = NWGetObjectID(conn, object, (NWObjectType)object_type, &object_id);
|
||||
if (err) {
|
||||
fprintf(stderr, "NWGetObjectID(%s,type=%u) failed: %s\n",
|
||||
object, (unsigned)object_type, strnwerror(err));
|
||||
ncp_close(conn);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (remove_limit)
|
||||
err = NWRemoveObjectDiskRestrictions(conn, volnum, object_id);
|
||||
else
|
||||
err = NWSetObjectVolSpaceLimit(conn, volnum, object_id, limit);
|
||||
|
||||
if (err) {
|
||||
fprintf(stderr, "%s object volume restriction failed: %s\n",
|
||||
remove_limit ? "remove" : "set", strnwerror(err));
|
||||
ncp_close(conn);
|
||||
return 1;
|
||||
}
|
||||
|
||||
err = NWGetObjDiskRestrictions(conn, volnum, object_id, &restriction, &in_use);
|
||||
if (err) {
|
||||
fprintf(stderr, "NWGetObjDiskRestrictions failed after mutation: %s\n", strnwerror(err));
|
||||
ncp_close(conn);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("userquota %s object=%s type=%u id=0x%08x volume=%s volnum=%u restriction4k=%u inuse4k=%u\n",
|
||||
remove_limit ? "removed" : "set",
|
||||
object, (unsigned)object_type, (unsigned)object_id,
|
||||
volume, (unsigned)volnum, (unsigned)restriction, (unsigned)in_use);
|
||||
|
||||
ncp_close(conn);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user