-
Victor Kotlyar authoredVictor Kotlyar authored
smc.c 16.11 KiB
/*
* Copyright (C) 1998-2003 by CERN/IT/PDP/DM
* All rights reserved
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "rbtsubr_constants.h"
#include "rmc_api.h"
#include "serrno.h"
#include "smc_constants.h"
#include "getconfent.h"
#include "getopt.h"
#include <ctype.h>
/* exit codes */
#define USERR 1
#define PATH_CONF "/etc/cta/cta-smc.conf"
#define TEXT_RED "\x1b[31;1m"
#define TEXT_NORMAL "\x1b[0m"
extern char *optarg;
static void smc_str_upper(char *const s) {
char *c = NULL;
for(c = s; *c; c++) {
*c = toupper(*c);
}
}
static void smc_usage(const char *const cmd)
{
fprintf (stderr, "Usage:\n");
fprintf (stderr,
" %s -d -D drive_ordinal [-V vid]\n"
" %s -e -V vid\n"
" %s -i [-V vid]\n"
" %s -m -D drive_ordinal -V vid\n"
" %s -q D [-D drive_ordinal] [-j]\n"
" %s -q L [-j]\n"
" %s -q P [-j]\n"
" %s -q S [-N nbelem] [-S starting_slot] [-j]\n"
" %s -q V [-N nbelem] [-V vid] [-j]\n",
cmd, cmd, cmd, cmd, cmd, cmd, cmd, cmd, cmd);
}
void smc_qdrive_humanPrint(const struct robot_info *const robot_info,
const struct smc_element_info *const element_info, const int numberOfElements,
const int useSpectraLib) {
char *pstatus;
int i;
printf (TEXT_RED "Drive Ordinal\tElement Addr.\t Status Vid\n" TEXT_NORMAL);
for (i = 0; i < numberOfElements; i++) {
if (((element_info+i)->state & 0x1) == 0)
pstatus = "free";
else if ((element_info+i)->state & 0x4)
pstatus = "error";
else if ((element_info+i)->state & 0x8 && !useSpectraLib)
pstatus = "unloaded";
else
pstatus = "loaded";
printf ("%13d\t%13d\t%8s %s\n",
(element_info+i)->element_address-robot_info->device_start,
(element_info+i)->element_address, pstatus,
(element_info+i)->name);
}
}
void smc_qdrive_jsonPrint(const struct robot_info *const robot_info,
const struct smc_element_info *const element_info, const int numberOfElements,
const int useSpectraLib) {
char *pstatus;
int i;
printf ("[");
for (i = 0; i < numberOfElements; i++) {
if (((element_info+i)->state & 0x1) == 0)
pstatus = "free";
else if ((element_info+i)->state & 0x4)
pstatus = "error";
else if ((element_info+i)->state & 0x8 && !useSpectraLib)
pstatus = "unloaded";
else
pstatus = "loaded";
if (0 != i) {
printf(",");
}
printf ("{\"driveOrdinal\":%d,"
"\"elementAddress\":%d,"
"\"status\":\"%s\","
"\"vid\":\"%s\"}",
(element_info+i)->element_address-robot_info->device_start,
(element_info+i)->element_address,
pstatus,
(element_info+i)->name);
}
printf ("]");
}
static int smc_qdrive (
const char *const rmchost,
const int fd,
const struct robot_info *const robot_info,
int drvord,
const int isJsonEnabled)
{
int c;
struct smc_element_info *element_info;
int nbelem;
char *smcLibraryType;
char useSpectraLib;
if (drvord < 0) {
drvord = 0;
nbelem = robot_info->device_count;
} else {
nbelem = 1;
}
if ((element_info = malloc (nbelem * sizeof(struct smc_element_info))) == NULL) {
fprintf (stderr, SR012);
return (USERR);
}
if ((c = rmc_read_elem_status (rmchost, 4,
robot_info->device_start+drvord, nbelem, element_info)) < 0) {
free (element_info);
return (c);
}
useSpectraLib=0;
smcLibraryType = getconfent_fromfile(PATH_CONF,"SMC","LIBRARY_TYPE",0);
if (NULL != smcLibraryType &&
0 == strcasecmp(smcLibraryType,"SPECTRA")) {
useSpectraLib = 1;
}
if (isJsonEnabled) {
smc_qdrive_jsonPrint(robot_info, element_info, c, useSpectraLib);
} else {
smc_qdrive_humanPrint(robot_info, element_info, c, useSpectraLib);
}
free (element_info);
return (0);
}
void smc_qlib_humanPrint(const struct robot_info *const robot_info) {
printf ("Vendor/Product/Revision = <%s>\n", robot_info->inquiry);
printf ("Transport Count = %d, Start = %d\n",
robot_info->transport_count, robot_info->transport_start);
printf ("Slot Count = %d, Start = %d\n",
robot_info->slot_count, robot_info->slot_start);
printf ("Port Count = %d, Start = %d\n",
robot_info->port_count, robot_info->port_start);
printf ("Device Count = %d, Start = %d\n",
robot_info->device_count, robot_info->device_start);
}
void smc_qlib_jsonPrint(const struct robot_info *const robot_info) {
char T10Vendor[9];
char prodId[17];
char prodRevLvl[5];
memcpy (T10Vendor, robot_info->inquiry, 8);
T10Vendor[8] = '\0';
memcpy(prodId, robot_info->inquiry + 8, 16);
prodId[16] = '\0';
memcpy(prodRevLvl,robot_info->inquiry + 8 + 16, 4);
prodRevLvl[4] = '\0';
printf ("[");
printf ("{\"inquiry\":{\"vendor\":\"%s\",\"product\":\"%s\",\"revision\":\"%s\"},",
T10Vendor, prodId, prodRevLvl);
printf ("\"transport\":{\"count\":%d,\"start\":%d},",
robot_info->transport_count, robot_info->transport_start);
printf ("\"slot\":{\"count\":%d,\"start\":%d},",
robot_info->slot_count, robot_info->slot_start);
printf ("\"port\":{\"count\":%d,\"start\":%d},",
robot_info->port_count, robot_info->port_start);
printf ("\"device\":{\"count\":%d,\"start\":%d}",
robot_info->device_count, robot_info->device_start);
printf ("}]");
}
static int smc_qlib (const struct robot_info *const robot_info,
const int isJsonEnabled)
{
if (isJsonEnabled) {
smc_qlib_jsonPrint(robot_info);
} else {
smc_qlib_humanPrint(robot_info);
}
return (0);
}
void smc_qport_humanPrint(const struct smc_element_info *const element_info,
const int numberOfElements) {
char *pstatus;
int i;
printf (TEXT_RED "Element Addr.\tVid\tImpExp\n" TEXT_NORMAL);
for (i = 0; i < numberOfElements; i++) {
if (((element_info+i)->state & 0x1) == 0)
pstatus = "";
else if (((element_info+i)->state & 0x2) == 0)
pstatus = "export";
else
pstatus = "import";
printf (" %4d\t%s\t%s\n",
(element_info+i)->element_address,
(element_info+i)->name, pstatus);
}
}
void smc_qport_jsonPrint(const struct smc_element_info *const element_info,
const int numberOfElements) {
char *pstatus;
int i;
printf ("[");
for (i = 0; i < numberOfElements; i++) {
if (((element_info+i)->state & 0x1) == 0)
pstatus = "";
else if (((element_info+i)->state & 0x2) == 0)
pstatus = "export";
else
pstatus = "import";
if (0 != i) {
printf(",");
}
printf ("{\"elementAddress\":%d,"
"\"vid\":\"%s\","
"\"state\":\"%s\"}",
(element_info+i)->element_address,
(element_info+i)->name,
pstatus);
}
printf ("]");
}
static int smc_qport (
const char *const rmchost,
const int fd,
const struct robot_info *const robot_info,
const int isJsonEnabled)
{
int c;
struct smc_element_info *element_info;
int nbelem;
nbelem = robot_info->port_count;
if ((element_info = malloc (nbelem * sizeof(struct smc_element_info))) == NULL) {
fprintf (stderr, SR012);
return (USERR);
}
if ((c = rmc_read_elem_status (rmchost, 3,
robot_info->port_start, nbelem, element_info)) < 0) {
free (element_info);
return (serrno - ERMCRBTERR);
}
if (isJsonEnabled) {
smc_qport_jsonPrint(element_info, c);
} else {
smc_qport_humanPrint(element_info, c);
}
free (element_info);
return (0);
}
void smc_qslot_humanPrint(const struct smc_element_info *element_info,
const int numberOfElements) {
int i;
printf (TEXT_RED "Element Addr.\tVid\n" TEXT_NORMAL);
for (i = 0; i < numberOfElements; i++) {
printf (" %4d\t%s\n",
element_info[i].element_address, element_info[i].name);
}
}
void smc_qslot_jsonPrint(const struct smc_element_info *element_info,
const int numberOfElements) {
int i;
printf ("[");
for (i = 0; i < numberOfElements; i++) {
if (0 != i) {
printf(",");
}
printf ("{\"elementAddress\":%4d,"
"\"vid\":\"%s\"}",
element_info[i].element_address,
element_info[i].name);
}
printf ("]");
}
static int smc_qslot (
const char *const rmchost,
const int fd,
const struct robot_info *robot_info,
int slotaddr,
int nbelem,
const int isJsonEnabled)
{
int c;
struct smc_element_info *element_info;
if (nbelem == 0) {
if (slotaddr < 0)
nbelem = robot_info->slot_count;
else
nbelem = 1;
}
if (slotaddr < 0)
slotaddr = 0;
if ((element_info = malloc (nbelem * sizeof(struct smc_element_info))) == NULL) {
fprintf (stderr, SR012);
return (USERR);
}
if ((c = rmc_read_elem_status (rmchost, 2, slotaddr,
nbelem, element_info)) < 0) {
free (element_info);
return (serrno - ERMCRBTERR);
}
if (isJsonEnabled) {
smc_qslot_jsonPrint(element_info, c);
} else {
smc_qslot_humanPrint(element_info, c);
}
free (element_info);
return (0);
}
void smc_qvid_humanPrint(const struct smc_element_info *const element_info,
const int numberOfElements){
int i;
char *ptype;
char ptypes[5][6] = {"", "hand", "slot", "port", "drive"};
printf (TEXT_RED "Vid\tElement Addr.\tElement Type\n" TEXT_NORMAL);
for (i = 0; i < numberOfElements; i++) {
ptype = ptypes[(element_info+i)->element_type];
if ((element_info+i)->element_type == 3) {
if (((element_info+i)->state & 0x2) == 0) {
ptype = "export";
} else {
ptype = "import";
}
}
printf ("%s\t %4d\t%s\n",
(element_info+i)->name, (element_info+i)->element_address,
ptype);
}
}
void smc_qvid_jsonPrint(const struct smc_element_info *const element_info,
const int numberOfElements){
int i;
char *ptype;
char ptypes[5][6] = {"", "hand", "slot", "port", "drive"};
printf ("[");
for (i = 0; i < numberOfElements; i++) {
ptype = ptypes[(element_info+i)->element_type];
if ((element_info+i)->element_type == 3) {
if (((element_info+i)->state & 0x2) == 0) {
ptype = "export";
} else {
ptype = "import";
}
}
if (0 != i) {
printf(",");
}
printf ("{\"vid\":\"%s\","
"\"elementAddress\":%d,"
"\"elementType\":\"%s\"}",
(element_info+i)->name,
(element_info+i)->element_address,
ptype);
}
printf ("]");
}
static int smc_qvid (
const char *const rmchost,
const int fd,
const struct robot_info *const robot_info,
const char *reqvid,
int nbelem,
const int isJsonEnabled)
{
int c;
struct smc_element_info *element_info;
const char *vid;
if (*reqvid)
vid = reqvid;
else
vid = "*";
if (nbelem == 0) {
if (strchr (vid, '*') || strchr (vid, '?')) /* pattern matching */
nbelem = robot_info->transport_count + robot_info->slot_count +
robot_info->port_count + robot_info->device_count;
else
nbelem = 1;
}
if ((element_info = malloc (nbelem * sizeof(struct smc_element_info))) == NULL) {
fprintf (stderr, SR012);
return (USERR);
}
if ((c = rmc_find_cartridge (rmchost, vid, 0, 0, nbelem,
element_info)) < 0) {
free (element_info);
return (serrno - ERMCRBTERR);
}
if (isJsonEnabled) {
smc_qvid_jsonPrint(element_info, c);
} else {
smc_qvid_humanPrint(element_info, c);
}
free (element_info);
return (0);
}
int main(const int argc,
char **argv)
{
int c;
char *dp;
int drvord = -1;
int errflg = 0;
const int fd = -1;
const int invert = 0;
int n;
int nbelem = 0;
char qry_type = 0;
char req_type = 0;
struct robot_info robot_info;
const char *rmchost = "localhost";
int slotaddr = -1;
char vid[7];
int isJsonEnabled = 0;
/* parse and check command options */
struct option longopts [] = {
{"drive", required_argument, NULL, 'D'},
{"dismount", no_argument, NULL, 'd'},
{"export", no_argument, NULL, 'e'},
{"import", no_argument, NULL, 'i'},
{"mount", no_argument, NULL, 'm'},
{"nbelem", required_argument, NULL, 'N'},
{"query", required_argument, NULL, 'q'},
{"slot", required_argument, NULL, 'S'},
{"vid", required_argument, NULL, 'V'},
{"json", no_argument, NULL, 'j'},
{NULL, 0, NULL, 0}
};
memset (vid, '\0', sizeof(vid));
while ((c = getopt_long(argc, argv, "D:deimN:q:S:V:j", longopts, NULL)) != EOF) {
switch (c) {
case 'D': /* drive ordinal */
drvord = strtol (optarg, &dp, 10);
if (*dp != '\0' || drvord < 0) {
fprintf (stderr, SR001);
errflg++;
}
break;
case 'd': /* demount */
case 'e': /* export */
if (req_type) {
fprintf (stderr, SR002, req_type, c);
errflg++;
} else
req_type = c;
break;
case 'i': /* import */
if (req_type) {
fprintf (stderr, SR002, req_type, c);
errflg++;
} else
req_type = c;
break;
case 'm': /* mount */
if (req_type) {
fprintf (stderr, SR002, req_type, c);
errflg++;
} else
req_type = c;
break;
case 'N': /* number of elements */
nbelem = strtol (optarg, &dp, 10);
if (*dp != '\0' || nbelem <= 0) {
fprintf (stderr, SR010);
errflg++;
}
break;
case 'q': /* query */
if (req_type) {
fprintf (stderr, SR002, req_type, c);
errflg++;
} else {
req_type = c;
qry_type = *optarg;
if (qry_type != 'D' && qry_type != 'L' &&
qry_type != 'P' && qry_type != 'S' &&
qry_type != 'V') {
fprintf (stderr, SR003, qry_type);
errflg++;
}
}
break;
case 'S': /* starting slot */
slotaddr = strtol (optarg, &dp, 10);
if (*dp != '\0' || slotaddr < 0) {
fprintf (stderr, SR001);
errflg++;
}
break;
case 'V': /* vid */
n = strlen (optarg);
if (n > 6) {
fprintf (stderr, SR004, optarg);
errflg++;
} else {
strcpy (vid, optarg);
smc_str_upper (vid);
}
break;
case 'j':
isJsonEnabled = 1;
break;
case '?':
errflg++;
break;
}
}
if (req_type && *rmchost == '\0') {
fprintf (stderr, "rmcserver must be specified\n");
errflg++;
}
if (req_type == 'd' && drvord < 0) {
fprintf (stderr, SR006);
errflg++;
}
if (req_type == 'e' && *vid =='\0') {
fprintf (stderr, SR011);
errflg++;
}
if (req_type == 'm' && (*vid =='\0' || drvord < 0)) {
fprintf (stderr, SR007);
errflg++;
}
if (errflg || req_type == 0) {
smc_usage (argv[0]);
exit (USERR);
}
/* get robot geometry */
if (rmc_get_geometry (rmchost, &robot_info)) {
exit (serrno);
}
if (drvord >= robot_info.device_count) {
fprintf (stderr, SR008, robot_info.device_count);
exit (USERR);
}
if (slotaddr > (robot_info.slot_count + robot_info.slot_start)) {
fprintf (stderr, SR016, robot_info.slot_count + robot_info.slot_start);
exit (USERR);
}
/* process request */
switch (req_type) {
case 'd':
if ((c = rmc_dismount (rmchost, vid, drvord, 0)) < 0) {
c = (serrno == SECOMERR) ? RBT_FAST_RETRY : serrno - ERMCRBTERR;
}
break;
case 'e':
if ((c = rmc_export (rmchost, vid)) < 0) {
c = (serrno == SECOMERR) ? RBT_FAST_RETRY : serrno - ERMCRBTERR;
}
break;
case 'i':
if ((c = rmc_import (rmchost, vid)) < 0) {
c = (serrno == SECOMERR) ? RBT_FAST_RETRY : serrno - ERMCRBTERR;
}
break;
case 'm':
if ((c = rmc_mount (rmchost, vid, invert, drvord)) < 0) {
c = (serrno == SECOMERR) ? RBT_FAST_RETRY : serrno - ERMCRBTERR;
}
break;
case 'q':
switch (qry_type) {
case 'D':
c = smc_qdrive (rmchost, fd, &robot_info, drvord,
isJsonEnabled);
break;
case 'L':
c = smc_qlib (&robot_info, isJsonEnabled);
break;
case 'P':
c = smc_qport (rmchost, fd, &robot_info, isJsonEnabled);
break;
case 'S':
c = smc_qslot (rmchost, fd, &robot_info, slotaddr,
nbelem, isJsonEnabled);
break;
case 'V':
c = smc_qvid (rmchost, fd, &robot_info, vid,
nbelem, isJsonEnabled);
break;
}
break;
}
exit (c);
}