1
0
Files
irix-657m-src/eoe/cmd/mediad/CompatClient.C
2022-09-29 17:59:04 +03:00

220 lines
5.1 KiB
C

#include "CompatClient.H"
#include <assert.h>
#include <bstring.h>
#include <ctype.h>
#include <errno.h>
#include <mntent.h>
#include <mediad.h>
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include "CompatListener.H" // for MEDIAD_SOCKNAME
#include "Fsd.H"
#include "Log.H"
CompatClient::CompatClient()
: _sent(false), _verbose(false)
{
bzero(&_msg, sizeof _msg);
bzero(&_reply, sizeof _reply);
}
void
CompatClient::verbose(bool yesno)
{
assert(!_sent);
_verbose = yesno;
}
const rmsg&
CompatClient::reply()
{
assert(_sent);
return _reply;
}
const char *
CompatClient::message(int code)
{
static const char *msg_array[] = {
" ", /* no error */
"Incorrect usage. Check the man page.",
"The drive is busy. Make sure no programs are using the drive.",
"Unable to eject. Try hardware eject.",
"There is no medium in the drive. Make sure you are specifying the right drive.",
"Software eject not supported. Use hardware eject.",
"No such device. Check your scsi id, fsname, or dir.",
"A system error has occured. See /usr/adm/SYSLOG for more info.",
"Could not access a device. Check permissions on the device.",
"No mediad is running. Make sure that mediad is running.",
"Another mediad is running. Only one is allowed at a time.",
"There are more than one removable media device on the system. Please specify one.",
"Mediad was terminated by a signal. You must restart mediad.",
"The device has been unmounted. Use hardware eject to remove the device now."
};
const int nmsgs = sizeof msg_array / sizeof msg_array[0];
if (code >= 0 && code < nmsgs)
return msg_array[code];
else
return NULL;
}
// Make sure that mediad is not already running on the system before I
// start. Returns a 1 if there is one
// running already, 0 otherwise.
void
CompatClient::send_test()
{
_msg.mtype = MSG_TEST;
send_mediad_sockmsg(DUPMEDIAD_TIMEOUT);
}
void
CompatClient::send_eject(const char *fsname, int ctlr, int id, int lun)
{
_msg.mtype = MSG_EJECT;
if (fsname)
{ strncpy(_msg.filename, fsname, sizeof _msg.filename - 1);
_msg.ctrl = -1;
_msg.scsi = -1;
_msg.lun = -1;
}
else
{ _msg.ctrl = ctlr;
_msg.scsi = id;
_msg.lun = lun;
}
send_mediad_sockmsg(EJECT_TIMEOUT);
}
void
CompatClient::send_kill()
{
_msg.mtype = MSG_TERM;
send_mediad_sockmsg(KILL_TIMEOUT);
}
void
CompatClient::send_show_mpoint(const char *fsname)
{
_msg.mtype = MSG_SHOWMOUNT;
strncpy(_msg.filename, fsname, sizeof _msg.filename);
send_mediad_sockmsg(SOCK_TIMEOUT);
}
void
CompatClient::send_start_entry(const char *fsname)
{
_msg.mtype = MSG_STARTENTRY;
strncpy(_msg.filename, fsname, sizeof _msg.filename);
send_mediad_sockmsg(SOCK_TIMEOUT);
}
void
CompatClient::send_query_dev(const char *fsname)
{
_msg.mtype = MSG_QUERY;
strncpy(_msg.filename, fsname, sizeof _msg.filename);
send_mediad_sockmsg(SOCK_TIMEOUT);
}
void
CompatClient::send_stop_entry(const char *fsname)
{
_msg.mtype = MSG_STOPENTRY;
strncpy(_msg.filename, fsname, sizeof _msg.filename);
send_mediad_sockmsg(SOCK_TIMEOUT);
}
void
CompatClient::send_set_log_level(int level)
{
_msg.mtype = MSG_SETLOGLEVEL;
_msg.scsi = level;
send_mediad_sockmsg(SOCK_TIMEOUT);
}
void
CompatClient::sigalrm_handler()
{ }
/*
* General purpose send mediad a packet on the socket routine.
*/
void
CompatClient::send_mediad_sockmsg(int wait_time)
{
assert(!_sent);
_sent = true;
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0)
{
Log::perror("can't create socket");
_reply.error = RMED_ENOMEDIAD;
return;
}
struct sockaddr_un addr;
bzero(&addr, sizeof addr);
addr.sun_family = AF_UNIX;
assert(strlen(CompatListener::MEDIAD_SOCKNAME) < sizeof addr.sun_path);
strcpy(addr.sun_path, CompatListener::MEDIAD_SOCKNAME);
if (connect(sock, (struct sockaddr *) &addr, sizeof addr) == -1)
{ if (_verbose)
Log::perror("can't connect to mediad");
(void) close(sock);
_reply.error = RMED_ENOMEDIAD;
return;
}
(void) signal(SIGALRM, (SIG_PF) sigalrm_handler);
alarm(wait_time);
int ret = write(sock, &_msg, sizeof _msg);
alarm(0);
if (ret < 0)
{
if (errno == EINTR)
{ Log::error("send to mediad timed out after %d seconds", wait_time);
(void) close(sock);
_reply.error = RMED_ENOMEDIAD;
return;
}
Log::perror("failed to send message to mediad");
(void) close(sock);
_reply.error = RMED_ENOMEDIAD;
return;
}
(void) signal(SIGALRM, (SIG_PF) sigalrm_handler);
alarm(wait_time);
ret = read(sock, &_reply, sizeof _reply);
alarm(0);
if (ret < 0)
{
if (errno == EINTR)
{ if (_verbose)
Log::error("mediad did not reply after %d seconds", wait_time);
(void) close(sock);
_reply.error = RMED_ENOMEDIAD;
return;
}
Log::perror("failed to receive reply from mediad");
(void) close(sock);
_reply.error = RMED_ENOMEDIAD;
return;
}
Log::debug("received reply code %d", _reply.error);
(void) close(sock);
}