/* ----------------------------------------------------------------<Prolog>-
Name: smtupmc.c
Title: UPM client interface
Package: Libero SMT 2.x
Written: 1996/09/06 iMatix SMT kernel team smt@imatix.com
Revised: 1999/08/18
Synopsis: Connects to the UPM daemon and lets you issue UPM commands.
Copyright: Copyright (c) 1991-2000 iMatix Corporation
License: This is free software; you can redistribute it and/or modify
it under the terms of the SMT License Agreement as provided
in the file LICENSE.TXT. This software is distributed in
the hope that it will be useful, but without any warranty.
------------------------------------------------------------------</Prolog>-*/
#include "smtdefn.h" /* SMT definitions */
#include "smtupm.h" /* SMT UPM definitions */
/*- Definitions -------------------------------------------------------------*/
#define AGENT_NAME "smtupmc" /* Name of our agent */
#define SINGLE_THREADED TRUE
#define UPMC_VERSION "1.0"
/*- Function prototypes -----------------------------------------------------*/
static void put_upm_message (THREAD *thread, dbyte ident, char *body);
static dbyte get_upm_message (THREAD *thread, char *body);
/*- Global variables used in this source file only --------------------------*/
static char
*portname, /* Connection port */
*args; /* Command-line arguments */
static sock_t
upm_socket = 0; /* Socket to UPM daemon */
static QID
sockq, /* Socket agent event queue */
tranq; /* Transfer agent event queue */
static char
**token_list = NULL, /* Parsed command line */
upm_body [LINE_MAX]; /* Message from UPM daemon */
static dbyte
upm_id; /* UPM message id */
static byte
msg_body [LINE_MAX]; /* Message sent to socket agent */
static int
msg_size; /* Size of formatted msg_body */
static DESCR /* Descriptor for exdr_writed */
msg = { LINE_MAX, msg_body };
#include "smtupmc.d" /* Include dialog data */
/******************** INITIALISE AGENT - ENTRY POINT *********************/
/* ---------------------------------------------------------------------[<]-
Function: smtupmc_init
Synopsis: Initialises the SMT UPM client agent. Returns 0 if okay,
-1 if there was an error. The UPM client agent allows you to pass
commands to the UPM daemon. See the SMT documentation for details.
---------------------------------------------------------------------[>]-*/
int
smtupmc_init (char *p_args, char *p_portname)
{
AGENT *agent; /* Handle for our agent */
THREAD *thread; /* Handle to console thread */
# include "smtupmc.i" /* Include dialog interpreter */
/* Shutdown event comes from Kernel */
method_declare (agent, "SHUTDOWN", shutdown_event, SMT_PRIORITY_MAX);
/* Reply events from socket agent */
method_declare (agent, "SOCK_INPUT_OK", ok_event, 0);
method_declare (agent, "SOCK_OUTPUT_OK", ok_event, 0);
method_declare (agent, "SOCK_READ_OK", ok_event, 0);
method_declare (agent, "SOCK_WRITE_OK", ok_event, 0);
method_declare (agent, "SOCK_CLOSED", sock_closed_event, 0);
method_declare (agent, "SOCK_ERROR", sock_error_event, 0);
method_declare (agent, "SOCK_TIMEOUT", sock_error_event, 0);
/* Reply events from transfer agent */
method_declare (agent, "TRAN_GETF_OK", ok_event, 0);
method_declare (agent, "TRAN_PUTF_OK", SMT_NULL_EVENT, 0);
method_declare (agent, "TRAN_CLOSED", sock_closed_event, 0);
method_declare (agent, "TRAN_ERROR", sock_error_event, 0);
/* Create initial, unnamed thread */
thread_create (AGENT_NAME, "");
/* Ensure that socket agent is running, else start it up */
smtsock_init ();
if ((thread = thread_lookup (SMT_SOCKET, "")) != NULL)
sockq = thread-> queue-> qid;
else
return (-1);
/* Ensure that transfer agent is running, else start it up */
smttran_init ();
if ((thread = thread_lookup (SMT_TRANSFER, "")) != NULL)
tranq = thread-> queue-> qid;
else
return (-1);
/* Signal okay to caller that we initialised okay */
args = p_args; /* Get command-line arguments */
portname = p_portname;
return (0);
}
/************************* INITIALISE THE THREAD *************************/
MODULE initialise_the_thread (THREAD *thread)
{
the_next_event = ok_event;
}
/************************* CONNECT TO UPM DAEMON *************************/
MODULE connect_to_upm_daemon (THREAD *thread)
{
printf ("upmc> 100- Connecting to UPM daemon...\n");
msg_size = exdr_writed (&msg, SMT_SOCK_CONNECT, 0,
"TCP", "", portname, 0, (qbyte) 0, (qbyte) 0);
event_send (
&sockq, /* Send to socket agent */
&thread-> queue-> qid, /* Queue for reply */
"CONNECT", /* Name of event to send */
msg_body, msg_size, /* Event body and size */
NULL, NULL, NULL, /* No response events */
0); /* No timeout */
}
/************************* STORE CONNECTION DATA *************************/
MODULE store_connection_data (THREAD *thread)
{
/* Reply message contains connected socket number plus tag (unused) */
exdr_read (thread-> event-> body, SMT_SOCK_OK, &upm_socket, NULL);
}
/*************************** GET DAEMON MESSAGE **************************/
MODULE get_daemon_message (THREAD *thread)
{
/* Ask the transfer agent to read a block from the socket */
msg_size = exdr_writed (&msg, SMT_TRAN_GETB, upm_socket, NULL);
event_send (
&tranq, /* Send to transfer agent */
&thread-> queue-> qid, /* Queue for reply */
"GET_BLOCK", /* Name of event to send */
msg_body, msg_size, /* Event body and size */
NULL, NULL, NULL, /* No response events */
0); /* No timeout */
event_wait (); /* Wait for reply event */
}
/************************** CHECK DAEMON MESSAGE *************************/
MODULE check_daemon_message (THREAD *thread)
{
/* This table converts a UPM message id into an event for the dialog */
static struct {
dbyte id;
event_t event;
} idents [] = {
{ UPM_READY, upm_ready_event },
{ UPM_ERROR, upm_error_event },
{ UPM_HALTING, upm_halting_event },
{ UPM_TASK_ID, upm_task_id_event },
{ UPM_TASK_OK, upm_task_ok_event },
{ UPM_TASK_NF, upm_task_nf_event },
{ UPM_TASK_RUNNING, upm_task_running_event },
{ UPM_TASK_STOPPED, upm_task_stopped_event },
{ UPM_START_OK, upm_start_ok_event },
{ UPM_START_ERROR, upm_start_error_event },
{ UPM_STOP_OK, upm_stop_ok_event },
{ UPM_STOP_ERROR, upm_stop_error_event },
{ 0, 0 }
};
int
ident_nbr;
if (the_external_event == ok_event)
{
/* Get arguments from message */
upm_id = get_upm_message (thread, upm_body);
for (ident_nbr = 0; idents [ident_nbr].id; ident_nbr++)
if (idents [ident_nbr].id == upm_id)
{
the_next_event = idents [ident_nbr].event;
break;
}
if (idents [ident_nbr].id == 0)
{
signal_unexpected_message (thread);
raise_exception (exception_event);
}
}
else
raise_exception (the_external_event);
}
/* -------------------------------------------------------------------------
* get_upm_message -- local
*
* Decodes the thread body to give a message id and a message body. Puts
* the message body in the specified string and returns the message id.
*/
static dbyte
get_upm_message (THREAD *thread, char *body)
{
byte
*msg_body_addr = msg_body;
dbyte
upm_ident;
/* Get buffer from transfer agent */
exdr_read (thread-> event-> body, SMT_TRAN_GETB_OK,
NULL, &msg_body_addr);
/* Decode UPM message */
exdr_read (msg_body, SMT_UPM_MESSAGE, &upm_ident, &body);
return (upm_ident);
}
/************************* GET USER COMMAND INPUT ************************/
MODULE get_user_command_input (THREAD *thread)
{
static char
input_line [LINE_MAX + 1];
static struct {
char *name;
event_t event;
} keywords [] = {
{ "LIST", list_event },
{ "START", start_event },
{ "STOP", stop_event },
{ "STATUS", status_event },
{ "HALT", halt_event },
{ "EXIT", exit_event },
{ "QUIT", exit_event },
{ "HELP", help_event },
{ "VERSION", version_event },
{ NULL, 0 }
};
int
keyword_nbr;
/* If we got function arguments, use those, else prompt the user */
if (args && strused (args))
{
strncpy (input_line, args, LINE_MAX);
input_line [LINE_MAX] = '\0'; /* Ensure delimited, if looong */
args = "exit"; /* Next time treat as Exit */
}
else
{
/* Show upmc prompt and wait for user command */
printf ("upmc> ");
fflush (stdout);
if (fgets (input_line, LINE_MAX, stdin) == NULL)
strclr (input_line); /* Treat EOF as empty */
}
if (token_list)
tok_free (token_list);
token_list = tok_split (input_line);
/* Get event corresponding to user command */
if (token_list [0] && *token_list [0])
{
the_next_event = error_event;
strupc (token_list [0]);
for (keyword_nbr = 0; keywords [keyword_nbr].name; keyword_nbr++)
if (streq (token_list [0], keywords [keyword_nbr].name))
{
the_next_event = keywords [keyword_nbr].event;
break;
}
}
else
the_next_event = empty_event;
}
/************************ SEND DAEMON LIST COMMAND ***********************/
MODULE send_daemon_list_command (THREAD *thread)
{
put_upm_message (thread, UPM_LIST, "");
}
static void
put_upm_message (THREAD *thread, dbyte ident, char *body)
{
static byte
upm_body [LINE_MAX]; /* Message to UPM client agent */
static DESCR /* Descriptor for exdr_writed */
upm = { LINE_MAX, upm_body };
int
upm_size; /* Size of formatted upm_body */
upm_size = exdr_writed (&upm, SMT_UPM_MESSAGE, ident, body);
msg_size = exdr_writed (&msg, SMT_TRAN_PUTB,
upm_socket, upm_size, upm_body, NULL);
event_send (
&tranq, /* Send to transfer agent */
&thread-> queue-> qid, /* Queue for reply */
"PUT_BLOCK", /* Name of event to send */
msg_body, msg_size, /* Event body and size */
NULL, NULL, NULL, /* No response events */
0); /* No timeout */
}
/*********************** SEND DAEMON START COMMAND ***********************/
MODULE send_daemon_start_command (THREAD *thread)
{
put_upm_message (thread, UPM_START, token_list [1]);
}
/************************ SEND DAEMON STOP COMMAND ***********************/
MODULE send_daemon_stop_command (THREAD *thread)
{
put_upm_message (thread, UPM_STOP, token_list [1]);
}
/*********************** SEND DAEMON STATUS COMMAND **********************/
MODULE send_daemon_status_command (THREAD *thread)
{
put_upm_message (thread, UPM_STATUS, token_list [1]);
}
/************************ SEND DAEMON HALT COMMAND ***********************/
MODULE send_daemon_halt_command (THREAD *thread)
{
put_upm_message (thread, UPM_HALT, "");
}
/************************ SHOW VERSION INFORMATION ***********************/
MODULE show_version_information (THREAD *thread)
{
printf ("upmc> 101- UPM client version %s\n", UPMC_VERSION);
}
/************************* SHOW HELP INFORMATION *************************/
MODULE show_help_information (THREAD *thread)
{
# define HELP_TEXT \
"Commands and arguments can be in any case. Commands are:\n" \
"LIST - list all known tasks\n" \
"START [task | ALL] - start specified task (default all)\n" \
"STOP [task | ALL] - stop specified task (default all)\n" \
"STATUS [task | ALL] - show status for specified task (default all)\n" \
"HALT - halt UPM daemon\n" \
"EXIT - end this UPM client session\n" \
"QUIT - end this UPM client session\n" \
"HELP - show this information\n" \
"VERSION - show UPM client version\n"
puts (HELP_TEXT);
}
/************************* SIGNAL CONNECTED OKAY *************************/
MODULE signal_connected_okay (THREAD *thread)
{
printf ("upmc> 102- Connected to UPM daemon version %s\n", upm_body);
}
/***************************** SHOW TASK NAME ****************************/
MODULE show_task_name (THREAD *thread)
{
printf ("upmc> 200- %s\n", upm_body);
}
/************************* SIGNAL TASK STARTED OK ************************/
MODULE signal_task_started_ok (THREAD *thread)
{
printf ("upmc> 201- task started successfully: %s\n", upm_body);
}
/************************ SIGNAL TASK NOT STARTED ************************/
MODULE signal_task_not_started (THREAD *thread)
{
printf ("upmc> 202- task not started: %s\n", upm_body);
}
/************************* SIGNAL TASK STOPPED OK ************************/
MODULE signal_task_stopped_ok (THREAD *thread)
{
printf ("upmc> 203- task stopped successfully: %s\n", upm_body);
}
/************************ SIGNAL TASK NOT STOPPED ************************/
MODULE signal_task_not_stopped (THREAD *thread)
{
printf ("upmc> 204- task not stopped: %s\n", upm_body);
}
/************************* SIGNAL TASK NOT KNOWN *************************/
MODULE signal_task_not_known (THREAD *thread)
{
printf ("upmc> 205- task not defined: %s\n", upm_body);
}
/************************** SIGNAL TASK RUNNING **************************/
MODULE signal_task_running (THREAD *thread)
{
printf ("upmc> 206- %s running\n", upm_body);
}
/************************** SIGNAL TASK STOPPED **************************/
MODULE signal_task_stopped (THREAD *thread)
{
printf ("upmc> 207- %s stopped\n", upm_body);
}
/************************** SIGNAL SOCKET CLOSED *************************/
MODULE signal_socket_closed (THREAD *thread)
{
printf ("upmc> 300- UPM daemon closed connection\n");
}
/************************** SIGNAL SOCKET ERROR **************************/
MODULE signal_socket_error (THREAD *thread)
{
printf ("upmc> 301- UPD daemon connection failed: %s\n",
thread-> event-> body);
}
/************************* SIGNAL INVALID COMMAND ************************/
MODULE signal_invalid_command (THREAD *thread)
{
printf ("upmc> 302- Invalid command - 'help' shows possible commands\n");
}
/*********************** SIGNAL UNEXPECTED MESSAGE ***********************/
MODULE signal_unexpected_message (THREAD *thread)
{
printf ("upmc> 303- Unexpected message from UPM daemon: %d\n", upm_id);
}
/************************* SIGNAL UPM FATAL ERROR ************************/
MODULE signal_upm_fatal_error (THREAD *thread)
{
printf ("upmc> 304- Fatal error from UPM daemon: %s\n", upm_body);
}
/************************* TERMINATE THE THREAD **************************/
MODULE terminate_the_thread (THREAD *thread)
{
if (upm_socket)
close_socket (upm_socket);
if (token_list)
tok_free (token_list); /* Free-up allocated memory */
smt_shutdown (); /* End the entire application */
the_next_event = terminate_event;
}
Generated by Framer 1.0 © 1997 iMatix