/* * Copyright (C) 2001-2003 by CERN/IT/PDP/DM * All rights reserved */ #include <errno.h> #include <stdlib.h> #include <sys/types.h> #include <netdb.h> #include <unistd.h> #include <netinet/in.h> #include <sys/socket.h> #include "Cnetdb.h" #include "marshall.h" #include "net.h" #include "rmc_api.h" #include "rmc_constants.h" #include "serrno.h" #define PATH_CONF "/etc/cta/cta-rmcd.conf" /* send2tpd - send a request to the SCSI media changer server and wait for the reply */ int send2rmc( const char *const host, const char *const reqp, const int reql, char *const user_repbuf, const int user_repbuf_len) { int actual_replen = 0; int c; char func[16]; char *getconfent(); char *getconfent_fromfile(); char *getenv(); struct hostent *hp; int magic; int n; char *p; char prtbuf[RMC_PRTBUFSZ]; int rep_type; char repbuf[RMC_REPBUFSZ]; char rmchost[CA_MAXHOSTNAMELEN+1]; int s; struct sockaddr_in sin; /* internet socket */ strncpy (func, "send2rmc", 16); sin.sin_family = AF_INET; if ((p = getenv ("RMC_PORT")) || (p = getconfent_fromfile (PATH_CONF,"RMC", "PORT", 0))) { sin.sin_port = htons ((unsigned short)atoi (p)); } else { sin.sin_port = htons ((unsigned short)RMC_PORT); serrno = 0; } if (host && *host) { strcpy (rmchost, host); } else { gethostname (rmchost, CA_MAXHOSTNAMELEN+1); serrno = 0; } if ((hp = Cgethostbyname (rmchost)) == NULL) { rmc_errmsg (func, RMC09, "Host unknown:", rmchost); serrno = ERMCUNREC; return (-1); } sin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0) { rmc_errmsg (func, RMC02, "socket", neterror()); serrno = SECOMERR; return (-1); } if (connect (s, (struct sockaddr *) &sin, sizeof(sin)) < 0) { if (errno == ECONNREFUSED) { rmc_errmsg (func, RMC00, rmchost); (void) close (s); serrno = ERMCNACT; return (-1); } else { rmc_errmsg (func, RMC02, "connect", neterror()); (void) close (s); serrno = SECOMERR; return (-1); } } /* send request to the SCSI media changer server */ if ((n = netwrite (s, reqp, reql)) <= 0) { if (n == 0) rmc_errmsg (func, RMC02, "send", sys_serrlist[SERRNO]); else rmc_errmsg (func, RMC02, "send", neterror()); (void) close (s); serrno = SECOMERR; return (-1); } if (user_repbuf == NULL) { /* does not want a reply */ (void) close (s); return (0); } /* get reply */ while (1) { if ((n = netread (s, repbuf, 3 * LONGSIZE)) <= 0) { if (n == 0) rmc_errmsg (func, RMC02, "recv", sys_serrlist[SERRNO]); else rmc_errmsg (func, RMC02, "recv", neterror()); (void) close (s); serrno = SECOMERR; return (-1); } p = repbuf; unmarshall_LONG (p, magic) ; unmarshall_LONG (p, rep_type) ; unmarshall_LONG (p, c) ; if (rep_type == RMC_RC) { (void) close (s); if (c) { serrno = c; c = -1; } break; } if ((n = netread (s, repbuf, c)) <= 0) { if (n == 0) rmc_errmsg (func, RMC02, "recv", sys_serrlist[SERRNO]); else rmc_errmsg (func, RMC02, "recv", neterror()); (void) close (s); serrno = SECOMERR; return (-1); } p = repbuf; if (rep_type == MSG_ERR) { unmarshall_STRING (p, prtbuf); rmc_errmsg (NULL, "%s", prtbuf); } else { if (actual_replen + c <= user_repbuf_len) n = c; else n = user_repbuf_len - actual_replen; if (n) { memcpy (user_repbuf + actual_replen, repbuf, n); actual_replen += n; } } } return (c); }