salvage: add initial config helper

This commit is contained in:
Mario Fetka
2026-05-31 09:25:42 +00:00
parent a539df7d3c
commit bedec0d2c0
5 changed files with 226 additions and 1 deletions

28
include/nwsalvage.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef _NWSALVAGE_H_
#define _NWSALVAGE_H_
#include <stddef.h>
#define NWSALVAGE_ENABLE_INI_SECTION 48
#define NWSALVAGE_REPOSITORY_INI_SECTION 49
#define NWSALVAGE_DEFAULT_ENABLED 1
#define NWSALVAGE_DEFAULT_RECYCLE_NAME ".recycle"
#define NWSALVAGE_DEFAULT_METADATA_NAME ".salvage"
#define NWSALVAGE_REPOSITORY_NAME_MAX 64
struct nwsalvage_config {
int enabled;
char recycle_repository[NWSALVAGE_REPOSITORY_NAME_MAX];
char metadata_repository[NWSALVAGE_REPOSITORY_NAME_MAX];
};
int nwsalvage_config_defaults(struct nwsalvage_config *config);
int nwsalvage_config_set_repositories(struct nwsalvage_config *config,
const char *recycle_repository,
const char *metadata_repository);
int nwsalvage_config_parse_repositories(struct nwsalvage_config *config,
const char *line);
int nwsalvage_repository_name_valid(const char *name);
#endif

View File

@@ -60,7 +60,7 @@ ELSE(ENABLE_INTERNAL_RIP_SAP)
ENDIF(ENABLE_INTERNAL_RIP_SAP)
add_executable(nwserv nwserv.c net1.c tools.c ${EMUTLI} ${EMUTLI1} ${NWROUTE_0} )
add_executable(nwconn nwconn.c net1.c tools.c connect.c namspace.c nwvolume.c nwfile.c unxfile.c nwqconn.c nameos2.c namedos.c nwfname.c nwshare.c extpipe.c nwattrib.c trustee.c nwarchive.c nwatalk.c nwxattr.c ${EMUTLI} )
add_executable(nwconn nwconn.c net1.c tools.c connect.c namspace.c nwvolume.c nwfile.c unxfile.c nwqconn.c nameos2.c namedos.c nwfname.c nwshare.c extpipe.c nwattrib.c trustee.c nwarchive.c nwatalk.c nwxattr.c nwsalvage.c ${EMUTLI} )
add_executable(ncpserv ncpserv.c net1.c tools.c ${EMUTLI} )
add_executable(nwclient nwclient.c net1.c tools.c ${EMUTLI} )
add_executable(nwbind nwbind.c net1.c tools.c nwdbm.c nwcrypt.c unxlog.c sema.c nwqueue.c unxfile.c ${EMUTLI} )

120
src/nwsalvage.c Normal file
View File

@@ -0,0 +1,120 @@
/* nwsalvage.c - NetWare salvage/recycle backend helpers */
#include "nwsalvage.h"
#include <ctype.h>
#include <errno.h>
#include <string.h>
int nwsalvage_repository_name_valid(const char *name)
{
size_t len;
if (!name || !*name) {
errno = EINVAL;
return(0);
}
len = strlen(name);
if (len >= NWSALVAGE_REPOSITORY_NAME_MAX) {
errno = ENAMETOOLONG;
return(0);
}
if (!strcmp(name, ".") || !strcmp(name, "..")) {
errno = EINVAL;
return(0);
}
if (strchr(name, '/') || strchr(name, '\\') || strchr(name, ':')) {
errno = EINVAL;
return(0);
}
return(1);
}
int nwsalvage_config_set_repositories(struct nwsalvage_config *config,
const char *recycle_repository,
const char *metadata_repository)
{
if (!config ||
!nwsalvage_repository_name_valid(recycle_repository) ||
!nwsalvage_repository_name_valid(metadata_repository)) {
if (!errno) errno = EINVAL;
return(-1);
}
strncpy(config->recycle_repository, recycle_repository,
sizeof(config->recycle_repository));
config->recycle_repository[sizeof(config->recycle_repository) - 1] = '\0';
strncpy(config->metadata_repository, metadata_repository,
sizeof(config->metadata_repository));
config->metadata_repository[sizeof(config->metadata_repository) - 1] = '\0';
return(0);
}
int nwsalvage_config_defaults(struct nwsalvage_config *config)
{
if (!config) {
errno = EINVAL;
return(-1);
}
memset(config, 0, sizeof(*config));
config->enabled = NWSALVAGE_DEFAULT_ENABLED;
return(nwsalvage_config_set_repositories(config,
NWSALVAGE_DEFAULT_RECYCLE_NAME,
NWSALVAGE_DEFAULT_METADATA_NAME));
}
static int parse_token(const char **cursor, char *out, size_t out_len)
{
const char *p = *cursor;
size_t len = 0;
while (*p && isspace((unsigned char)*p)) p++;
if (!*p) {
errno = EINVAL;
return(-1);
}
while (p[len] && !isspace((unsigned char)p[len])) len++;
if (len >= out_len) {
errno = ENAMETOOLONG;
return(-1);
}
memcpy(out, p, len);
out[len] = '\0';
*cursor = p + len;
return(0);
}
int nwsalvage_config_parse_repositories(struct nwsalvage_config *config,
const char *line)
{
const char *p = line;
char recycle_repository[NWSALVAGE_REPOSITORY_NAME_MAX];
char metadata_repository[NWSALVAGE_REPOSITORY_NAME_MAX];
if (!config || !line) {
errno = EINVAL;
return(-1);
}
if (parse_token(&p, recycle_repository, sizeof(recycle_repository)) < 0 ||
parse_token(&p, metadata_repository, sizeof(metadata_repository)) < 0)
return(-1);
while (*p && isspace((unsigned char)*p)) p++;
if (*p) {
errno = EINVAL;
return(-1);
}
return(nwsalvage_config_set_repositories(config,
recycle_repository,
metadata_repository));
}

View File

@@ -26,3 +26,19 @@ add_custom_target(salvage_layout_smoke ALL
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES
${SALVAGE_LAYOUT_SMOKE_SCRIPT}
)
add_executable(salvage_config_smoke
salvage_config_smoke.c
${CMAKE_SOURCE_DIR}/src/nwsalvage.c
)
target_include_directories(salvage_config_smoke PRIVATE
${CMAKE_SOURCE_DIR}/include
)
add_custom_target(run_salvage_config_smoke ALL
COMMAND $<TARGET_FILE:salvage_config_smoke>
DEPENDS salvage_config_smoke
COMMENT "Running salvage config smoke helper"
VERBATIM
)

View File

@@ -0,0 +1,61 @@
/* Smoke test for the initial nwsalvage configuration helpers. */
#include "nwsalvage.h"
#include <stdio.h>
#include <string.h>
static int expect_true(int condition, const char *message)
{
if (!condition) {
fprintf(stderr, "FAIL: %s\n", message);
return(1);
}
return(0);
}
int main(void)
{
struct nwsalvage_config config;
int failures = 0;
failures += expect_true(nwsalvage_config_defaults(&config) == 0,
"defaults are accepted");
failures += expect_true(config.enabled == 1,
"salvage defaults to enabled");
failures += expect_true(!strcmp(config.recycle_repository, ".recycle"),
"default recycle repository name");
failures += expect_true(!strcmp(config.metadata_repository, ".salvage"),
"default metadata repository name");
failures += expect_true(nwsalvage_config_parse_repositories(
&config, " .recycle .salvage ") == 0,
"section 49 default line parses");
failures += expect_true(!strcmp(config.recycle_repository, ".recycle"),
"parsed recycle repository name");
failures += expect_true(!strcmp(config.metadata_repository, ".salvage"),
"parsed metadata repository name");
failures += expect_true(nwsalvage_config_parse_repositories(
&config, "recycle salvage") == 0,
"custom repository names parse");
failures += expect_true(!strcmp(config.recycle_repository, "recycle"),
"custom recycle repository name");
failures += expect_true(!strcmp(config.metadata_repository, "salvage"),
"custom metadata repository name");
failures += expect_true(nwsalvage_config_parse_repositories(
&config, "bad/name .salvage") < 0,
"repository names reject slash components");
failures += expect_true(nwsalvage_config_parse_repositories(
&config, ".recycle") < 0,
"repository line requires two names");
failures += expect_true(nwsalvage_config_parse_repositories(
&config, ".recycle .salvage extra") < 0,
"repository line rejects extra tokens");
if (failures)
return(1);
puts("salvage config smoke passed");
return(0);
}