summaryrefslogtreecommitdiffstats
path: root/tools/nlmtest/nlmtest.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/nlmtest/nlmtest.c')
-rw-r--r--tools/nlmtest/nlmtest.c264
1 files changed, 264 insertions, 0 deletions
diff --git a/tools/nlmtest/nlmtest.c b/tools/nlmtest/nlmtest.c
new file mode 100644
index 0000000..d0acc47
--- /dev/null
+++ b/tools/nlmtest/nlmtest.c
@@ -0,0 +1,264 @@
+/*
+ * nlmtest
+ *
+ * Simple tool for NLM testing. You will have to adjust the values in
+ * host.h to your test system.
+ *
+ * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#include "config.h"
+
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <nfs/nfs.h>
+#include <getopt.h>
+#include "nlm_prot.h"
+#include "host.h"
+
+static char myhostname[256];
+static int hostnamelen;
+
+static void makelock(struct nlm_lock *, u_int32_t, off_t, off_t);
+static void makeowner(struct netobj *, u_int32_t);
+static void makefileh(struct netobj *);
+static char * nlm_stat_name(int status);
+static char * holderstr(struct netobj *oh);
+
+int
+main(int argc, char **argv)
+{
+ CLIENT *client;
+ nlm_testargs testargs;
+ nlm_lockargs lockargs;
+ nlm_unlockargs unlockargs;
+ nlm_lock alock;
+ nlm_testres *testres;
+ nlm_res *lockres;
+ char *filename = NLMTEST_FILE;
+ char *svchost = NLMTEST_HOST;
+ unsigned long offset = 0, length = 0;
+ int exclusive = 0;
+ int blocking = 0;
+ int unlock = 0;
+ u_int32_t cookie = 4321;
+ u_int32_t mypid = 1234;
+ int c;
+
+ while ((c = getopt(argc, argv, "bf:h:l:o:p:ux")) != EOF) {
+ switch(c) {
+ case 'b':
+ blocking = 1;
+ break;
+ case 'f':
+ filename = optarg;
+ break;
+ case 'h':
+ svchost = optarg;
+ break;
+ case 'l':
+ length = atoi(optarg);
+ break;
+ case 'o':
+ offset = atoi(optarg);
+ break;
+ case 'p':
+ mypid = atoi(optarg);
+ break;
+ case 'u':
+ unlock = 1;
+ break;
+ case 'x':
+ exclusive = 1;
+ break;
+ default:
+ fprintf(stderr, "nlmtest: bad option %c\n", c);
+ exit (2);
+ }
+ }
+
+ client = clnt_create(svchost, NLM_PROG, NLM_VERS, "udp");
+ if (client == NULL) {
+ clnt_pcreateerror("localhost");
+ exit(1);
+ }
+
+ /* Get local host name */
+ if (gethostname(myhostname, sizeof(myhostname)) < 0)
+ strcpy(myhostname, "unknown");
+ hostnamelen = strlen(myhostname);
+
+ makelock(&alock, mypid, offset, length);
+
+ testargs.cookie.n_bytes = (void*)&cookie;
+ testargs.cookie.n_len = 4;
+ testargs.exclusive = exclusive;
+ testargs.alock = alock;
+
+ if ((testres = nlm_test_1(&testargs, client)) == NULL) {
+ clnt_perror(client, "nlm_test call failed:");
+ exit (1);
+ }
+ printf ("nlm_test reply:\n"
+ "\tcookie: %d\n"
+ "\tstatus: %s\n",
+ *(int*)(testres->cookie.n_bytes),
+ nlm_stat_name(testres->stat.stat)
+ );
+
+ if (testres->stat.stat == nlm_denied) {
+ nlm_holder *holder = &(testres->stat.nlm_testrply_u.holder);
+ printf ("\tconflicting lock:\n"
+ "\t oh: %s\n"
+ "\t pid: %d\n"
+ "\t offset: %d\n"
+ "\t length: %d\n"
+ "\t exclusive: %d\n",
+ holderstr(&holder->oh),
+ holder->svid,
+ holder->l_offset,
+ holder->l_len,
+ holder->exclusive);
+ }
+
+ if (testres->stat.stat != nlm_granted && !unlock && !blocking)
+ return 1;
+
+ if (unlock) {
+ unlockargs.cookie.n_bytes = (void*)&cookie;
+ unlockargs.cookie.n_len = sizeof(cookie);
+ unlockargs.alock = alock;
+
+ if ((lockres = nlm_unlock_1(&unlockargs, client)) == NULL) {
+ clnt_perror(client, "nlm_unlock call failed:");
+ exit (1);
+ }
+ printf ("nlm_unlock reply:\n"
+ "\tcookie: %d\n"
+ "\tstatus: %s\n",
+ *(int*)(lockres->cookie.n_bytes),
+ nlm_stat_name(lockres->stat.stat)
+ );
+ } else {
+ lockargs.cookie.n_bytes = (void*)&cookie;
+ lockargs.cookie.n_len = sizeof(cookie);
+ lockargs.exclusive = exclusive;
+ lockargs.alock = alock;
+ lockargs.reclaim = 0;
+ lockargs.state = 0;
+
+ if ((lockres = nlm_lock_1(&lockargs, client)) == NULL) {
+ clnt_perror(client, "nlm_lock call failed:");
+ exit (1);
+ }
+ printf ("nlm_lock reply:\n"
+ "\tcookie: %d\n"
+ "\tstatus: %s\n",
+ *(int*)(lockres->cookie.n_bytes),
+ nlm_stat_name(lockres->stat.stat)
+ );
+ }
+
+ return 0;
+}
+
+static char *
+nlm_stat_name(int status)
+{
+ static char buf[12];
+
+ switch (status) {
+ case nlm_granted:
+ return "nlm_granted";
+ case nlm_denied:
+ return "nlm_denied";
+ case nlm_denied_nolocks:
+ return "nlm_denied_nolocks";
+ case nlm_blocked:
+ return "nlm_blocked";
+ case nlm_denied_grace_period:
+ return "nlm_denied_grace_period";
+ }
+ sprintf(buf, "%d", status);
+ return buf;
+}
+
+static char *
+holderstr(struct netobj *oh)
+{
+ static char buffer[4096];
+ unsigned char c, *sp;
+ int i;
+
+ for (i = 0, sp = buffer; i < oh->n_len; i++) {
+ c = (unsigned char) oh->n_bytes[i];
+ if (c < 0x20 || c > 0x7f)
+ sp += sprintf(sp, "\\%03o", c);
+ else
+ *sp++ = c;
+ }
+ *sp++ = '\0';
+
+ return buffer;
+}
+
+static void
+makelock(struct nlm_lock *alock, u_int32_t mypid, off_t offset, off_t length)
+{
+ makeowner(&alock->oh, mypid); /* Create owner handle */
+ makefileh(&alock->fh); /* Create file handle */
+
+ alock->caller_name = myhostname;
+ alock->svid = mypid;
+ alock->l_offset = offset;
+ alock->l_len = length;
+}
+
+static void
+makeowner(struct netobj *oh, u_int32_t mypid)
+{
+ static char ohdata[1024];
+
+ oh->n_bytes = ohdata;
+ oh->n_len = hostnamelen + 1 + 4;
+
+ strcpy(ohdata, myhostname);
+ memcpy(ohdata + hostnamelen + 1, &mypid, 4);
+}
+
+static void
+makefileh(struct netobj *fh)
+{
+ static struct knfs_fh f;
+ struct stat stb;
+#error this needs updating if it is still wanted
+ memset(&f, 0, sizeof(f));
+#if 0
+ if (stat(NLMTEST_DIR, &stb) < 0) {
+ perror("couldn't stat mount point " NLMTEST_DIR);
+ exit(1);
+ }
+ f.fh_xdev = stb.st_dev;
+ f.fh_xino = stb.st_ino;
+
+ if (stat(NLMTEST_DIR, &stb) < 0) {
+ perror("couldn't stat mount point " NLMTEST_DIR);
+ exit(1);
+ }
+ f.fh_dev = stb.st_dev;
+ f.fh_ino = stb.st_ino;
+
+ f.fh_version = NLMTEST_VERSION;
+#else
+ f.fh_xdev = 0x801;
+ f.fh_xino = 37596;
+ f.fh_dev = 0x801;
+ f.fh_ino = 37732;
+#endif
+
+ fh->n_len = 32;
+ fh->n_bytes = (void *) &f;
+}