From 1d9a537d046c4b6600a76d5be54c13515a827383 Mon Sep 17 00:00:00 2001
From: Steven Murray <steven.murray@cern.ch>
Date: Wed, 27 Nov 2013 16:22:09 +0100
Subject: [PATCH] The command-line tool castor-tape-mount now calls the
 skeleton C function rmc_mnt().

---
 mediachanger/castorrmc/h/rmc_api.h       |  4 +-
 mediachanger/castorrmc/rmc/rmc_mnt.c     | 59 +++++++---------
 mediachanger/castorrmc/rmc/rmc_mnt.man   | 18 ++---
 mediachanger/castorrmc/rmc/rmc_unmnt.c   | 89 +++++++++++++-----------
 mediachanger/castorrmc/rmc/rmc_unmnt.man | 31 ++++++---
 5 files changed, 104 insertions(+), 97 deletions(-)

diff --git a/mediachanger/castorrmc/h/rmc_api.h b/mediachanger/castorrmc/h/rmc_api.h
index b0784b4602..9d73444b09 100644
--- a/mediachanger/castorrmc/h/rmc_api.h
+++ b/mediachanger/castorrmc/h/rmc_api.h
@@ -28,7 +28,7 @@ EXTERN_C int rmc_mount(const char *const server, const char *const vid, const in
 EXTERN_C int rmc_read_elem_status(const char *const server, const int type, const int startaddr, const int nbelem, struct smc_element_info *const element_info);
 EXTERN_C void rmc_seterrbuf(const char *const buffer, const int buflen);
 EXTERN_C int send2rmc(const char *const host, const char *const reqp, const int reql, char *const user_repbuf, const int user_repbuf_len);
-EXTERN_C int rmc_mnt(const char *const server, const char *const vid, const char *const drive);
-EXTERN_C int rmc_unmnt(const char *const server, const char *const vid, const char *const drive);
+EXTERN_C int rmc_mnt(const char *const vid, const char *const drive);
+EXTERN_C int rmc_unmnt(const char *const vid, const char *const drive);
 
 #endif
diff --git a/mediachanger/castorrmc/rmc/rmc_mnt.c b/mediachanger/castorrmc/rmc/rmc_mnt.c
index e6a78013e5..4242405cb2 100644
--- a/mediachanger/castorrmc/rmc/rmc_mnt.c
+++ b/mediachanger/castorrmc/rmc/rmc_mnt.c
@@ -32,7 +32,6 @@
 #include "h/marshall.h"
 #include "h/rmc_api.h"
 #include "h/rmc_constants.h"
-#include "h/rmc_find_char.h"
 #include "h/rmc_get_acs_drive_id.h"
 #include "h/rmc_get_rmc_host_of_drive.h"
 #include "h/rmc_get_loader_type.h"
@@ -41,25 +40,31 @@
 #include <errno.h>
 #include <string.h>
 
-static int rmc_acs_mnt(const char *const server, const char *const vid,
-  const char *const drive);
-static int rmc_manual_mnt(const char *const server, const char *const vid,
-   const char *const drive);
-static int rmc_smc_mnt(const char *const server, const char *const vid,
-  const char *const drive);
-
-int rmc_mnt(
-	const char *const server,
-	const char *const vid,
-	const char *const drive)
-{
+static int rmc_acs_mnt(const char *const vid, const char *const drive);
+static int rmc_manual_mnt(const char *const vid, const char *const drive);
+static int rmc_smc_mnt(const char *const vid, const char *const drive);
+
+int rmc_mnt(const char *const vid, const char *const drive) {
+	/* If there is nothing to work on then return EINVAL */
+	if(NULL == vid || NULL == drive) {
+		errno = EINVAL;
+		serrno = errno;
+		return -1;
+	}
+
+	if(CA_MAXVIDLEN < strlen(vid)) {
+		errno = ERMCVIDTOOLONG; /* VID is too long */
+		serrno = errno;
+		return -1;
+	}
+
 	switch(rmc_get_loader_type(drive)) {
 	case RMC_LOADER_TYPE_ACS:
-		return rmc_acs_mnt(server, vid, drive);
+		return rmc_acs_mnt(vid, drive);
 	case RMC_LOADER_TYPE_MANUAL:
-		return rmc_manual_mnt(server, vid, drive);
+		return rmc_manual_mnt(vid, drive);
 	case RMC_LOADER_TYPE_SMC:
-		return rmc_smc_mnt(server, vid, drive);
+		return rmc_smc_mnt(vid, drive);
 	default:
 		errno = ERMCUKNLDRTYPE; /* Unknown loader type */
 		serrno = errno;
@@ -67,11 +72,7 @@ int rmc_mnt(
 	}
 }
 
-static int rmc_acs_mnt(
-	const char *const server,
-	const char *const vid,
-	const char *const drive) {
-
+static int rmc_acs_mnt(const char *const vid, const char *const drive) {
 	const gid_t gid = getgid();
 	const uid_t uid = getuid();
 
@@ -88,12 +89,6 @@ static int rmc_acs_mnt(
 	char rmc_host[CA_MAXHOSTNAMELEN+1];
 	struct rmc_acs_drive_id drive_id = {0, 0, 0, 0};
 
-	if(CA_MAXVIDLEN < strlen(vid)) {
-		errno = ERMCVIDTOOLONG; /* VID is too long */
-		serrno = errno;
-		return -1;
-	}
-
 	if(rmc_get_rmc_host_of_drive(drive, rmc_host, sizeof(rmc_host))) {
 		errno = ERMCPARSERMCHOST; /* Failed to parse RMC host */
 		serrno = errno;
@@ -140,18 +135,12 @@ static int rmc_acs_mnt(
         return send2rmc (rmc_host, sendbuf, msglen, repbuf, sizeof(repbuf));
 }
 
-static int rmc_manual_mnt(
-	const char *const server,
-	const char *const vid,
-	const char *const drive) {
+static int rmc_manual_mnt(const char *const vid, const char *const drive) {
 
 	return 0;
 }
 
-static int rmc_smc_mnt(
-	const char *const server,
-	const char *const vid,
-	const char *const drive) {
+static int rmc_smc_mnt(const char *const vid, const char *const drive) {
 
 	return 0;
 }
diff --git a/mediachanger/castorrmc/rmc/rmc_mnt.man b/mediachanger/castorrmc/rmc/rmc_mnt.man
index a44ffa7771..09a67a6f60 100644
--- a/mediachanger/castorrmc/rmc/rmc_mnt.man
+++ b/mediachanger/castorrmc/rmc/rmc_mnt.man
@@ -9,27 +9,20 @@ rmc_mnt \- send a request to the Remote Media Changer daemon to have a volume mo
 .br
 \fB#include "rmc_api.h"\fR
 .sp
-.BI "int rmc_mnt (char *" server ,
-.BI "char *" vid ,
-.BI "char *" drive );
+.BI "int \fBrmc_mnt\f[](const char *const \fIvid\f[], const char *const \fIdrive\f[]);
 .SH DESCRIPTION
 .B rmc_mnt
-asks the Remote Media Changer server running on
-.I server
-to mount the volume
+asks the remote media-changer daemon to mount the volume
 .I vid
 on the drive specified by
 .IR drive .
 .TP
-.I server
-specifies the Remote Media Changer to be contacted.
-.TP
 .I vid
 is the volume visual identifier.
 It must be at most six characters long.
 .TP
 .I drive
-specifies the drive in the robot in one of the following forms:
+specifies the drive in one of the following three forms corresponding to the three supported drive-loader types, namely acs, manual and smc:
 .RS
 .TP
 acs@rmc_host,ACS_NUMBER,LSM_NUMBER,PANEL_NUMBER,TRANSPORT_NUMBER
@@ -49,6 +42,9 @@ mount, or -1 if the operation failed. In the latter case,
 is set appropriately.
 .SH ERRORS
 .TP 1.8i
+.B EINVAL
+If either \fIvid\f[] or \fIdrive\f[] are passed a NULL pointer.
+.TP
 .B SECOMERR
 Communication error.
 .TP
@@ -63,7 +59,7 @@ Unit attention.
 Hardware error or Medium Removal Prevented.
 .TP
 .B ERMCUKNLDRTYPE
-Unknown loader type.
+Unknown drive-loader type.
 .TP
 .B ERMCVIDTOOLONG
 VID is too long.
diff --git a/mediachanger/castorrmc/rmc/rmc_unmnt.c b/mediachanger/castorrmc/rmc/rmc_unmnt.c
index fc36189fe3..678e9fbdfb 100644
--- a/mediachanger/castorrmc/rmc/rmc_unmnt.c
+++ b/mediachanger/castorrmc/rmc/rmc_unmnt.c
@@ -32,31 +32,39 @@
 #include "h/marshall.h"
 #include "h/rmc_api.h"
 #include "h/rmc_constants.h"
+#include "h/rmc_get_acs_drive_id.h"
+#include "h/rmc_get_rmc_host_of_drive.h"
 #include "h/rmc_get_loader_type.h"
 #include "h/serrno.h"
 
 #include <errno.h>
 #include <string.h>
 
-static int rmc_acs_unmnt(const char *const server, const char *const vid,
-  const char *const drive);
-static int rmc_manual_unmnt(const char *const server, const char *const vid,
-   const char *const drive);
-static int rmc_smc_unmnt(const char *const server, const char *const vid,
-  const char *const drive);
-
-int rmc_unmnt(
-	const char *const server,
-	const char *const vid,
-	const char *const drive)
-{
+static int rmc_acs_unmnt(const char *const vid, const char *const drive);
+static int rmc_manual_unmnt(const char *const vid, const char *const drive);
+static int rmc_smc_unmnt(const char *const vid, const char *const drive);
+
+int rmc_unmnt(const char *const vid, const char *const drive) {
+	/* If there is nothing to work on then return EINVAL */
+	if(NULL == vid || NULL == drive) {
+		errno = EINVAL;
+		serrno = errno;
+		return -1;
+	}
+
+	if(CA_MAXVIDLEN < strlen(vid)) {
+		errno = ERMCVIDTOOLONG; /* VID is too long */
+		serrno = errno;
+		return -1;
+	}
+
 	switch(rmc_get_loader_type(drive)) {
 	case RMC_LOADER_TYPE_ACS:
-		return rmc_acs_unmnt(server, vid, drive);
+		return rmc_acs_unmnt(vid, drive);
 	case RMC_LOADER_TYPE_MANUAL:
-		return rmc_manual_unmnt(server, vid, drive);
+		return rmc_manual_unmnt(vid, drive);
 	case RMC_LOADER_TYPE_SMC:
-		return rmc_smc_unmnt(server, vid, drive);
+		return rmc_smc_unmnt(vid, drive);
 	default:
 		errno = ERMCUNREC;
 		serrno = errno;
@@ -64,33 +72,39 @@ int rmc_unmnt(
 	}
 }
 
-int rmc_acs_unmnt(
-	const char *const server,
-	const char *const vid,
-	const char *const drive)
-{
+int rmc_acs_unmnt(const char *const vid, const char *const drive) {
 	const gid_t gid = getgid();
 	const uid_t uid = getuid();
 
 	/* The total length of the fixed size members of the request message */
-	/* is Magic (4 bytes) + request ID (4 bytes) + length (4 bytes) +    */
-	/* uid (4 bytes) + gid (4 bytes) = 20 bytes                          */
-	const int msglen = 20 + strlen(vid) + 1 + strlen(drive) + 1;
+	/* is Magic (4 bytes) + request ID (4 bytes) + msglen (4 bytes) +    */
+	/* uid (4 bytes) + gid (4 bytes) + ACS number (4 bytes) + LSM number */
+	/* (4 bytes) + panel number (4 bytes) + transport number (4 bytes) = */
+	/* 40 bytes                                                          */
+	const int msglen = 40 + strlen(vid);
 
 	char repbuf[1];
 	char *sbp = NULL;
 	char sendbuf[RMC_REQBUFSZ];
+	char rmc_host[CA_MAXHOSTNAMELEN+1];
+	struct rmc_acs_drive_id drive_id = {0, 0, 0, 0};
 
-	/* Consider the function arguments invalid if the total size of the */
-	/* request message would be greater than RMC_REQBUFSZ               */
-	if(msglen > RMC_REQBUFSZ) {
-		errno = ERMCUNREC;
+	if(rmc_get_rmc_host_of_drive(drive, rmc_host, sizeof(rmc_host))) {
+		errno = ERMCPARSERMCHOST; /* Failed to parse RMC host */
 		serrno = errno;
 		return -1;
 	}
 
-	if(CA_MAXVIDLEN < strlen(vid)) {
-		errno = ERMCUNREC;
+	if(rmc_get_acs_drive_id(drive, &drive_id)) {
+		errno = ERMCPARSEACSDRV; /* Failed to parse ACS drive id */
+		serrno = errno;
+		return -1;
+	}
+
+	/* It is an internal error if the total size of the request message */
+	/* would be greater than RMC_REQBUFSZ                               */
+	if(msglen > RMC_REQBUFSZ) {
+		errno = SEINTERNAL;
 		serrno = errno;
 		return -1;
 	}
@@ -104,8 +118,11 @@ int rmc_acs_unmnt(
 	/* Build request body */
 	marshall_LONG (sbp, uid);
 	marshall_LONG (sbp, gid);
+	marshall_LONG (sbp, drive_id.acs);
+	marshall_LONG (sbp, drive_id.lsm);
+	marshall_LONG (sbp, drive_id.panel);
+	marshall_LONG (sbp, drive_id.transport);
 	marshall_STRING (sbp, vid);
-	marshall_STRING (sbp, drive);
 
 	/* Being paranoid; checking the calculated message length against */
 	/* the number of bytes marshalled                                 */
@@ -115,21 +132,15 @@ int rmc_acs_unmnt(
 		return -1;
 	}
 
-        return send2rmc (server, sendbuf, msglen, repbuf, sizeof(repbuf));
+        return send2rmc (rmc_host, sendbuf, msglen, repbuf, sizeof(repbuf));
 }
 
-static int rmc_manual_unmnt(
-        const char *const server, 
-        const char *const vid,
-        const char *const drive) {
+static int rmc_manual_unmnt(const char *const vid, const char *const drive) {
 
         return 0;
 }
 
-static int rmc_smc_unmnt(
-        const char *const server, 
-        const char *const vid,
-        const char *const drive) {
+static int rmc_smc_unmnt(const char *const vid, const char *const drive) {
         
         return 0;
 }
diff --git a/mediachanger/castorrmc/rmc/rmc_unmnt.man b/mediachanger/castorrmc/rmc/rmc_unmnt.man
index ee023a41ee..f988be24f0 100644
--- a/mediachanger/castorrmc/rmc/rmc_unmnt.man
+++ b/mediachanger/castorrmc/rmc/rmc_unmnt.man
@@ -9,27 +9,20 @@ rmc_unmnt \- send a request to the Remote Media Changer daemon to have a volume
 .br
 \fB#include "rmc_api.h"\fR
 .sp
-.BI "int rmc_unmnt (char *" server ,
-.BI "char *" vid ,
-.BI "char *" drive );
+int \fBrmc_unmnt\f[](const char *const \fIvid\f[], const char *const \fIdrive\f[]);
 .SH DESCRIPTION
 .B rmc_unmnt
-asks the Remote Media Changer server running on
-.I server
-to unmount the volume
+asks the Remote media-changer daemon (rmcd) to unmount the volume
 .I vid
 from the drive specified by
 .IR drive .
 .TP
-.I server
-specifies the Remote Media Changer to be contacted.
-.TP
 .I vid
 is the volume visual identifier.
 It must be at most six characters long.
 .TP
 .I drive
-specifies the drive in the robot in one of the following forms:
+specifies the drive in one of the following three forms corresponding to the three supported drive-loader types, namely acs, manual and smc:
 .RS
 .TP
 acs@rmc_host,ACS_NUMBER,LSM_NUMBER,PANEL_NUMBER,TRANSPORT_NUMBER
@@ -49,6 +42,9 @@ unmount, or -1 if the operation failed. In the latter case,
 is set appropriately.
 .SH ERRORS
 .TP 1.2i
+.B EINVAL
+If either \fIvid\f[] or \fIdrive\f[] are passed a NULL pointer.
+.TP
 .B SECOMERR
 Communication error.
 .TP
@@ -61,6 +57,21 @@ Unit attention.
 .TP
 .B ERMCOMSGR
 Hardware error or Medium Removal Prevented.
+.TP
+.B ERMCUKNLDRTYPE
+Unknown drive-loader type.
+.TP
+.B ERMCVIDTOOLONG
+VID is too long.
+.TP
+.B ERMCPARSERMCHOST
+Failed to parse RMC host.
+.TP
+.B ERMCPARSEACSDRV
+Failed to parse ACS drive id.
+.TP
+.B SEINTERNAL
+Internal error
 .SH SEE ALSO
 .BR Cupvlist(1) ,
 .SH AUTHOR
-- 
GitLab