Files
mars-nwe/tests/salvage/ncp_read_smoke.c

148 lines
4.0 KiB
C

/*
* Linux smoke helper for reading a NetWare file through ncpfs/ncplib.
*
* The helper is intentionally small and uses the public ncplib open/read/close
* calls. The salvage smoke script uses it instead of local Unix cat so the
* content check goes through the same NCP path that created/recovered the file.
*/
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ncp/nwcalls.h>
#include <ncp/ncplib.h>
#include <ncp/kernel/ncp.h>
static void usage(const char *prog)
{
fprintf(stderr,
"Usage: %s [--expect TEXT] [ncpfs options] PATH\n"
"\n"
"ncpfs options are parsed by ncp_initialize(), for example:\n"
" -S SERVER -U USER -P PASSWORD -n\n"
"\n"
"Example:\n"
" %s --expect hello -S MARS -U SUPERVISOR -P secret SYS:PUBLIC/SALVAGE.TXT\n",
prog, prog);
}
static int content_matches(const char *buf, size_t len, const char *expected)
{
size_t expected_len;
if (!expected)
return 1;
expected_len = strlen(expected);
if (len == expected_len && !memcmp(buf, expected, expected_len))
return 1;
if (len == expected_len + 1 && buf[expected_len] == '\n' &&
!memcmp(buf, expected, expected_len))
return 1;
return 0;
}
int main(int argc, char **argv)
{
NWCONN_HANDLE conn;
long init_err = 0;
const char *path = NULL;
const char *expected = NULL;
struct ncp_file_info file_info;
char *buf = NULL;
size_t alloc_len;
long err;
int i;
int rc = 1;
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], "--expect")) {
if (++i >= argc) {
fprintf(stderr, "missing --expect value\n");
ncp_close(conn);
return 2;
}
expected = argv[i];
} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
usage(argv[0]);
ncp_close(conn);
return 0;
} else if (!path) {
path = argv[i];
} else {
fprintf(stderr, "unexpected argument: %s\n", argv[i]);
usage(argv[0]);
ncp_close(conn);
return 2;
}
}
if (!path) {
usage(argv[0]);
ncp_close(conn);
return 2;
}
memset(&file_info, 0, sizeof(file_info));
err = ncp_open_file(conn, 0, path, 0, AR_READ_ONLY, &file_info);
if (err) {
fprintf(stderr, "NCP open for read failed: path=%s error=0x%04x\n",
path, (unsigned int)err);
ncp_close(conn);
return 1;
}
alloc_len = file_info.file_length ? (size_t)file_info.file_length : 1;
buf = malloc(alloc_len + 1);
if (!buf) {
fprintf(stderr, "out of memory reading path=%s size=%lu\n",
path, (unsigned long)alloc_len);
ncp_close_file(conn, file_info.file_id);
ncp_close(conn);
return 1;
}
err = ncp_read(conn, file_info.file_id, 0, alloc_len, buf);
if (err < 0) {
fprintf(stderr, "NCP read failed: path=%s error=%ld\n", path, err);
goto out;
}
buf[err] = '\0';
if (err > 0 && fwrite(buf, 1, (size_t)err, stdout) != (size_t)err) {
fprintf(stderr, "stdout write failed while reading path=%s\n", path);
goto out;
}
if (!content_matches(buf, (size_t)err, expected)) {
fprintf(stderr,
"NCP read content mismatch: path=%s bytes=%ld expected='%s'\n",
path, err, expected ? expected : "");
goto out;
}
fprintf(stderr, "NCP read path=%s bytes=%ld verified\n", path, err);
rc = 0;
out:
free(buf);
ncp_close_file(conn, file_info.file_id);
ncp_close(conn);
return rc;
}