
- Refactored site specific stuff into a site module - PSI specific stuff is now in the PSI directory. - The old version has been tagged with pre-ansto
1312 lines
44 KiB
C
Executable File
1312 lines
44 KiB
C
Executable File
#define IDENT "1A01"
|
||
/*---------------------------------------------------------------------------*/
|
||
#ifdef __DECC
|
||
#pragma module SINQHM_BOOTUTIL_CLIENT IDENT
|
||
#endif
|
||
/*
|
||
** Link_options - Here is the Linker Option File
|
||
**! sinqhm_bootutil_client
|
||
**! tas_src:[lib]sinq_dbg/lib
|
||
**! sys$share:decw$xlibshr/share
|
||
**!!
|
||
**!! To build SINQHM_BOOTUTIL_CLIENT on LNSA09
|
||
**!!
|
||
**!! $ import tasmad
|
||
**!! $ define/job deltat_c_tlb sinq_c_tlb
|
||
**!! $ sss := tas_src:[sinqhm]
|
||
**!! $ bui 'sss'sinqhm_bootutil_client debug
|
||
** Link_options_end
|
||
**
|
||
** +--------------------------------------------------------------+
|
||
** | Paul Scherrer Institute |
|
||
** | Computing Section |
|
||
** | |
|
||
** | This software may be used freely by non-profit organizations.|
|
||
** | It may be copied provided that the name of P.S.I. and of the |
|
||
** | author is included. Neither P.S.I. nor the author assume any |
|
||
** | responsibility for the use of this software outside of P.S.I.|
|
||
** +--------------------------------------------------------------+
|
||
**
|
||
** Module Name . . . . . . . . : [...SINQHM]SINQHM_BOOTUTIL_CLIENT.C
|
||
**
|
||
** Author . . . . . . . . . . : D. Maden
|
||
** Date of creation . . . . . . : Aug 1999
|
||
**
|
||
** SINQHM_BOOTUTIL_CLIENT is the main program of an Internet Client which
|
||
** communicates with SINQHM_BOOTUTIL running on a SINQ Histogram Memory.
|
||
** It allows the user to inspect and modify the boot parameters of the
|
||
** histogram memory.
|
||
**
|
||
** Updates:
|
||
** 27-Aug-1999 1A01 DM. Initial version.
|
||
**
|
||
** The following logical name definitions are used ...
|
||
**
|
||
** SINQHM_FRONTEND -
|
||
** "<hostname>, - The host where SINQHM_BOOTUTIL is running.
|
||
** <port>" TCP/IP port number of SINQHM_BOOTUTIL (dflt = 2300).
|
||
**====================================================================
|
||
*/
|
||
|
||
#include <errno.h>
|
||
#include <netdb.h>
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <signal.h>
|
||
#include <time.h>
|
||
|
||
#include <netinet/in.h>
|
||
|
||
#include <sys/types.h>
|
||
#include <ctype.h>
|
||
#include <arpa/inet.h>
|
||
#include <math.h>
|
||
#include <sys/socket.h>
|
||
#include <string.h>
|
||
#include <X11/Intrinsic.h>
|
||
|
||
#ifdef __VMS
|
||
#include <ucx$inetdef.h>
|
||
#include <sys/unixio.h>
|
||
#include <descrip>
|
||
#else
|
||
#include <unistd.h>
|
||
#endif
|
||
|
||
#ifdef __VMS
|
||
#include <sys/ssdef.h>
|
||
#include <sys/starlet.h>
|
||
#else
|
||
#define SS$_NORMAL EXIT_SUCCESS
|
||
#define SS$_BADPARAM EXIT_FAILURE
|
||
#define SS$_IVBUFLEN EXIT_FAILURE
|
||
#define NO_MEMORY 4
|
||
#endif
|
||
/*
|
||
**==================== Global Definitions =====================================
|
||
*/
|
||
#include <sinq_prototypes.h>
|
||
|
||
#define DFLT_PORT 2300
|
||
#define NIL '\0'
|
||
#define NL '\n'
|
||
#define MAXARR 8192
|
||
#define MAXREC 512
|
||
/*------------------------------------------------------------*/
|
||
/*
|
||
** Define the Data Structures we need
|
||
*/
|
||
/*
|
||
**==================== Global Variables ======================================
|
||
*/
|
||
int My_errno, My_vaxc_errno;
|
||
|
||
int Verbose;
|
||
int Rmt_port;
|
||
char Rmt_host[32];
|
||
static int Cnct_skt = 0; /* Connect socket */
|
||
static int Ctrl_C_has_happened;
|
||
|
||
static XrmOptionDescRec OpTable_0[] = {
|
||
{"-name", ".name", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-h", ".butilHelp", XrmoptionNoArg, (XPointer) "1"},
|
||
{"-he", ".butilHelp", XrmoptionNoArg, (XPointer) "1"},
|
||
{"-hel", ".butilHelp", XrmoptionNoArg, (XPointer) "1"},
|
||
{"-help", ".butilHelp", XrmoptionNoArg, (XPointer) "1"},
|
||
{"-ho", ".butilHost", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-hos", ".butilHost", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-host", ".butilHost", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-port", ".butilPort", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-v", ".butilVerbose", XrmoptionNoArg, (XPointer) "1"},
|
||
{"-?", ".butilHelpItem", XrmoptionSepArg, (XPointer) NULL},
|
||
};
|
||
/*
|
||
**=============================================================================
|
||
** Local routines.
|
||
**
|
||
** CtrlC_Handler : Catch a Ctrl-C interrupt.
|
||
** do_config : Handle the CONFIG command
|
||
** do_reboot : Handle the REBOOT command
|
||
** do_rundown : Handle the RUNDOWN command
|
||
** exit_handler : Exit handler in case a forced exit is made.
|
||
** get_SINQHM_FRONTEND : Extract info from SINQHM_FRONTEND environment variable
|
||
** openConnection : Open connection to server.
|
||
** show_help : Display the help text.
|
||
**----------------------------------------------------------------------------
|
||
** Prototypes
|
||
*/
|
||
void CtrlC_Handler (int sigint);
|
||
int do_config (char *bootline);
|
||
int do_reboot ();
|
||
int do_rundown ();
|
||
void exit_handler ();
|
||
int get_check_resources (XrmDatabase *db,
|
||
char *appName,
|
||
int verbose);
|
||
void get_SINQHM_FRONTEND (char *host, int host_l, char *host_dflt,
|
||
int *port, int port_dflt,
|
||
int *pktlen, int pktlen_dflt);
|
||
int openConnection (char *host, int port);
|
||
int read_boot_line (int skt, char *recd, int s_recd);
|
||
int send_a_close (int skt);
|
||
int setup_xrm_database (XrmDatabase *db,
|
||
char *name[],
|
||
int *argc,
|
||
char *argv[],
|
||
int verbose);
|
||
int show_boot_line (char *bootline);
|
||
void show_help (char *token);
|
||
/*
|
||
**--------------------------------------------------------------------------
|
||
** CtrlC_Handler: Signal handler to detect <Ctrl-C> on keyboard.
|
||
*/
|
||
void CtrlC_Handler (int sigint) {
|
||
/* =============
|
||
*/
|
||
Ctrl_C_has_happened = 1;
|
||
}
|
||
/*
|
||
**--------------------------------------------------------------------------*/
|
||
int do_config (
|
||
/* =========
|
||
** Interact with user to get modified config data.
|
||
** Then send CONFIG command to the target.
|
||
*/
|
||
char *bootline) { /* The current boot-line */
|
||
|
||
#define MAXP 32
|
||
|
||
char my_bootline[1024], old_bootline[1024];
|
||
char buff[132], *tok, *nxttok, *body;
|
||
char prefix[MAXP][64];
|
||
char prompt[MAXP][64];
|
||
char bodies[MAXP][128];
|
||
int is_numeric[MAXP], is_hex[MAXP];
|
||
int i, j, k, status, n_toks, toklen, bootlen;
|
||
|
||
StrJoin (my_bootline, sizeof (my_bootline), bootline, "");
|
||
for (i = 0; i < MAXP; i++) is_numeric[i] = is_hex[i] = False;
|
||
/*
|
||
** Scan through the boot-line setting up a table of prompts
|
||
*/
|
||
n_toks = 0;
|
||
tok = strtok (my_bootline, ":\n");
|
||
while ((tok != NULL) && (n_toks < MAXP)) {
|
||
StrJoin (prefix[n_toks], sizeof (prefix[0]), tok, ":");
|
||
toklen = strlen (tok);
|
||
if (tok[toklen+1] == '\n') { /* Watch out for tokens with no body */
|
||
body = "";
|
||
bodies[n_toks][0] = NIL;
|
||
nxttok = strtok (NULL, ":\n"); /* Skip an empty body */
|
||
}else {
|
||
body = strtok (NULL, "\n");
|
||
if (body == NULL) body = "";
|
||
StrJoin (bodies[n_toks], sizeof (bodies[0]), body, "");
|
||
nxttok = strtok (NULL, ":");
|
||
}
|
||
if ((strcmp (tok, "bootDev") == 0) && (body != NULL)) {
|
||
strcpy (prompt[n_toks], "boot device : ");
|
||
}else if ((strcmp (tok, "procNum") == 0) && (body != NULL)) {
|
||
strcpy (prompt[n_toks], "processor number : ");
|
||
is_numeric[n_toks] = True;
|
||
status = sscanf (body, "%i%n", &i, &j);
|
||
if ((status != 1) || (j != strlen (body))) {
|
||
printf ("do_config: Bad value found for procNum: \"%s\"\n", body);
|
||
return False;
|
||
}
|
||
}else if ((strcmp (tok, "hostName") == 0) && (body != NULL)) {
|
||
strcpy (prompt[n_toks], "host name : ");
|
||
}else if ((strcmp (tok, "bootFile") == 0) && (body != NULL)) {
|
||
strcpy (prompt[n_toks], "file name : ");
|
||
}else if ((strcmp (tok, "ead") == 0) && (body != NULL)) {
|
||
strcpy (prompt[n_toks], "inet on ethernet (e) : ");
|
||
}else if ((strcmp (tok, "bad") == 0) && (body != NULL)) {
|
||
strcpy (prompt[n_toks], "inet on backplane (b): ");
|
||
}else if ((strcmp (tok, "had") == 0) && (body != NULL)) {
|
||
strcpy (prompt[n_toks], "host inet (h) : ");
|
||
}else if ((strcmp (tok, "gad") == 0) && (body != NULL)) {
|
||
strcpy (prompt[n_toks], "gateway inet (g) : ");
|
||
}else if ((strcmp (tok, "usr") == 0) && (body != NULL)) {
|
||
strcpy (prompt[n_toks], "user (u) : ");
|
||
}else if ((strcmp (tok, "passwd") == 0) && (body != NULL)) {
|
||
strcpy (prompt[n_toks], "ftp password (pw) : ");
|
||
}else if ((strcmp (tok, "flags") == 0) && (body != NULL)) {
|
||
strcpy (prompt[n_toks], "flags (f) : ");
|
||
is_numeric[n_toks] = True;
|
||
is_hex[n_toks] = True;
|
||
status = sscanf (body, "%i%n", &i, &j);
|
||
if ((status != 1) || (j != strlen (body))) {
|
||
printf ("do_config: Bad value found for flags: \"%s\"\n", body);
|
||
return False;
|
||
}
|
||
}else if ((strcmp (tok, "targetName") == 0) && (body != NULL)) {
|
||
strcpy (prompt[n_toks], "target name (tn) : ");
|
||
}else if ((strcmp (tok, "startupScript") == 0) && (body != NULL)) {
|
||
strcpy (prompt[n_toks], "startup script (s) : ");
|
||
}else if ((strcmp (tok, "other") == 0) && (body != NULL)) {
|
||
strcpy (prompt[n_toks], "other (o) : ");
|
||
}else {
|
||
printf ("do_config: Bad token found in boot-line: "
|
||
"\"%s\" \"%s\"\n", tok, body);
|
||
return False;
|
||
}
|
||
n_toks++;
|
||
tok = nxttok;
|
||
}
|
||
if (tok != NULL) {
|
||
printf ("\007Too many tokens in the boot-line!\n");
|
||
return False;
|
||
}
|
||
if (n_toks <= 0) {
|
||
printf ("\007No tokens in the boot-line!\n");
|
||
return False;
|
||
}
|
||
re_edit:
|
||
/*=======
|
||
*/ printf ("\n'.' = clear field; '-' = go to previous field; ");
|
||
#ifdef __VMS
|
||
printf ("^Z = quit\n\n");
|
||
#else
|
||
printf ("^D = quit\n\n");
|
||
#endif
|
||
i = 0;
|
||
while (i < n_toks) {
|
||
printf ("%s%s ", prompt[i], bodies[i]);
|
||
if (fgets (buff, sizeof (buff), stdin) == NULL) break;
|
||
if (strlen (buff) == (sizeof (buff) - 1)) {
|
||
printf ("\n\007Input buffer overflow, try again!\n");
|
||
i--;
|
||
return False;
|
||
}
|
||
j = sizeof (buff); StrEdit (buff, buff, "trim compress", &j);
|
||
if (j == 0) {
|
||
/* Empty input -- leave the field unchanged */
|
||
}else if (StrMatch (buff, ".", 1)) {
|
||
bodies[i][0] = NIL; /* "." -- clear the field */
|
||
}else if (StrMatch (buff, "-", 1)) {
|
||
i -= 2; /* "-" -- go to previous field */
|
||
if (i < 0) i = -1;
|
||
}else if (j >= sizeof (bodies[0])) {
|
||
printf ("\007Input too long, try again!\n");
|
||
i--;
|
||
}else {
|
||
if (is_numeric[i]) {
|
||
status = sscanf (buff, "%i%n", &k, &j);
|
||
if ((status != 1) || (j != strlen (buff))) {
|
||
printf ("\007Value must be an integer, \"%s\" is invalid. "
|
||
"Try again!\n", buff);
|
||
i--;
|
||
}else {
|
||
if (is_hex[i]) {
|
||
sprintf (bodies[i], "0x%x", k);
|
||
}else {
|
||
sprintf (bodies[i], "%d", k);
|
||
}
|
||
}
|
||
}else {
|
||
StrJoin (bodies[i], sizeof (bodies[0]), buff, "");
|
||
}
|
||
}
|
||
i++;
|
||
}
|
||
|
||
i = printf ("\n\nNew boot-line for %s is:\n", Rmt_host);
|
||
for (j = 3; j < i; j++) printf ("="); printf ("\n");
|
||
my_bootline[0] = NIL;
|
||
for (i = 0; i < n_toks; i++) {
|
||
if (bodies[i][0] != NIL) printf ("%s%s\n", prompt[i], bodies[i]);
|
||
StrJoin (my_bootline, sizeof (my_bootline), my_bootline, prefix[i]);
|
||
StrJoin (my_bootline, sizeof (my_bootline), my_bootline, bodies[i]);
|
||
StrJoin (my_bootline, sizeof (my_bootline), my_bootline, "\n");
|
||
}
|
||
|
||
printf ("\nType \"Yes\" to configure, ");
|
||
#ifdef __VMS
|
||
printf ("^Z");
|
||
#else
|
||
printf ("^D");
|
||
#endif
|
||
printf (" to abandon and anything else to re-edit: ");
|
||
|
||
if (fgets (buff, sizeof (buff), stdin) == NULL) return False;
|
||
if (strlen (buff) == (sizeof (buff) - 1)) {
|
||
printf ("\n\007Input buffer overflow, no config performed!\n");
|
||
return False;
|
||
}
|
||
i = sizeof (buff); StrEdit (buff, buff, "trim compress lowercase", &i);
|
||
if (!StrMatch (buff, "yes", 3)) goto re_edit;
|
||
|
||
Cnct_skt = openConnection (Rmt_host, Rmt_port);
|
||
read_boot_line (Cnct_skt, old_bootline, sizeof (old_bootline));
|
||
|
||
strcpy (buff, "CONFIG");
|
||
bootlen = strlen (my_bootline) + 1; /* Get string length */
|
||
bootlen = (bootlen + 3) & (~3); /* Round up to a multiple of 4 */
|
||
i = sprintf (&buff[8], "%04.4d", bootlen); /* Convert to ASCII */
|
||
if (i != 4) {
|
||
printf ("\007The new boot line is too long! CONFIG has not "
|
||
"been performed.\n");
|
||
return False;
|
||
}
|
||
status = send (Cnct_skt, buff, 12, 0);
|
||
if (status != 12) FailInet ("do_config - bad send");
|
||
status = send (Cnct_skt, my_bootline, bootlen, 0);
|
||
if (status != bootlen) FailInet ("do_config - bad send");
|
||
status = recv (Cnct_skt, buff, 4, 0); /* Await the response */
|
||
close (Cnct_skt);
|
||
Cnct_skt = 0;
|
||
if (status != 4) {
|
||
FailInet ("do_config - bad recv");
|
||
return False;
|
||
}
|
||
if (!StrMatch (buff, "OK", 2)) {
|
||
printf ("\007Config command rejected by target!\n");
|
||
return False;
|
||
}
|
||
printf ("The boot-line of %s has been re-configured successfully.\n",
|
||
Rmt_host);
|
||
return True;
|
||
}
|
||
/*
|
||
**--------------------------------------------------------------------------*/
|
||
int do_reboot (
|
||
/* =========
|
||
** Send REBOOT command to the target.
|
||
*/
|
||
) {
|
||
|
||
char ist_bootline[1024], buff[128];
|
||
int i, status;
|
||
|
||
printf ("Type \"Yes\" to re-boot %s: ", Rmt_host);
|
||
if (fgets (buff, sizeof (buff), stdin) == NULL) exit (EXIT_FAILURE);
|
||
if (strlen (buff) == (sizeof (buff) - 1)) {
|
||
printf ("\n\007Input buffer overflow, no re-boot performed!\n");
|
||
exit (EXIT_FAILURE);
|
||
}
|
||
i = sizeof (buff); StrEdit (buff, buff, "trim compress lowercase", &i);
|
||
if (!StrMatch (buff, "yes", 3)) {
|
||
printf ("No re-boot performed!\n");
|
||
exit (EXIT_FAILURE);
|
||
}
|
||
|
||
Cnct_skt = openConnection (Rmt_host, Rmt_port);
|
||
read_boot_line (Cnct_skt, ist_bootline, sizeof (ist_bootline));
|
||
|
||
strcpy (buff, "REBOOT");
|
||
status = send (Cnct_skt, buff, 8, 0);
|
||
if (status != 8) FailInet ("do_reboot - bad send");
|
||
|
||
status = recv (Cnct_skt, buff, 4, 0); /* Await the response */
|
||
close (Cnct_skt);
|
||
Cnct_skt = 0;
|
||
if (status != 4) {
|
||
FailInet ("do_reboot - bad recv");
|
||
return False;
|
||
}
|
||
if (!StrMatch (buff, "OK", 2)) {
|
||
printf ("\007Reboot command rejected by target!\n");
|
||
return False;
|
||
}
|
||
printf ("%s is rebooting.\n", Rmt_host);
|
||
return True;
|
||
}
|
||
/*
|
||
**--------------------------------------------------------------------------*/
|
||
int do_rundown (
|
||
/* ==========
|
||
** Send RUNDOWN command to the target.
|
||
*/
|
||
) {
|
||
|
||
char ist_bootline[1024], buff[128];
|
||
int i, status;
|
||
|
||
printf ("Type \"Yes\" to rundown bootUtil on %s: ", Rmt_host);
|
||
if (fgets (buff, sizeof (buff), stdin) == NULL) exit (EXIT_FAILURE);
|
||
if (strlen (buff) == (sizeof (buff) - 1)) {
|
||
printf ("\n\007Input buffer overflow, no rundown performed!\n");
|
||
exit (EXIT_FAILURE);
|
||
}
|
||
i = sizeof (buff); StrEdit (buff, buff, "trim compress lowercase", &i);
|
||
if (!StrMatch (buff, "yes", 3)) {
|
||
printf ("No rundown performed!\n");
|
||
exit (EXIT_FAILURE);
|
||
}
|
||
|
||
Cnct_skt = openConnection (Rmt_host, Rmt_port);
|
||
read_boot_line (Cnct_skt, ist_bootline, sizeof (ist_bootline));
|
||
|
||
strcpy (buff, "RUNDOWN");
|
||
status = send (Cnct_skt, buff, 8, 0);
|
||
if (status != 8) FailInet ("do_rundown - bad send");
|
||
|
||
status = recv (Cnct_skt, buff, 4, 0); /* Await the response */
|
||
close (Cnct_skt);
|
||
Cnct_skt = 0;
|
||
if (status != 4) {
|
||
FailInet ("do_rundown - bad recv");
|
||
return False;
|
||
}
|
||
if (!StrMatch (buff, "OK", 2)) {
|
||
printf ("\007Rundown command rejected by target!\n");
|
||
return False;
|
||
}
|
||
printf ("The bootUtil server on %s is running down.\n", Rmt_host);
|
||
return True;
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------*/
|
||
void exit_handler () {
|
||
/* ============
|
||
** We must exit. Tidy up first.
|
||
** Close TCP/IP link to front-end.
|
||
*/
|
||
int status;
|
||
char buff[16];
|
||
/*
|
||
** Tell server we're quitting.
|
||
*/
|
||
if (Cnct_skt != 0) {
|
||
printf ("Closing connection to %s ...\n", Rmt_host);
|
||
status = send (Cnct_skt, "-001", 4, 0);
|
||
status = close (Cnct_skt);
|
||
Cnct_skt = 0;
|
||
if (status != 0) FailInet ("EXIT_HANDLER -- R/W-Socket close error\n");
|
||
}
|
||
}
|
||
/*
|
||
**--------------------------------------------------------------------------*/
|
||
void flushNet (
|
||
/* ========
|
||
** Flush bytes from the server.
|
||
**
|
||
*/ int nbytes) { /* Number of bytes to flush */
|
||
|
||
char buff[256];
|
||
int i, status, bytes_to_come, bytes_to_get;
|
||
|
||
bytes_to_come = nbytes;
|
||
|
||
while (bytes_to_come > 0) {
|
||
bytes_to_get = (bytes_to_come > sizeof (buff)) ?
|
||
sizeof (buff) : bytes_to_get;
|
||
status = recv (Cnct_skt, buff, bytes_to_get, 0);
|
||
if (status <= 0) break;
|
||
bytes_to_come -= status;
|
||
}
|
||
if (bytes_to_come != 0) {
|
||
if (status < 0) {
|
||
FailInet ("R/W-Socket recv error in flushNet");
|
||
}else if (status == 0) {
|
||
FailInet ("R/W-Socket recv error in flushNet -- return code = 0");
|
||
}
|
||
exit (EXIT_FAILURE);
|
||
}
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** get_check_resources - get and check our resources
|
||
*/
|
||
int get_check_resources (
|
||
/* ===================
|
||
*/ XrmDatabase *db,
|
||
char *appName,
|
||
int verbose) {
|
||
|
||
int status, len, do_help;
|
||
char buff[80];
|
||
char *type;
|
||
XrmValue value;
|
||
time_t time_now;
|
||
float tmp_secs;
|
||
/*---------------------------------------------------------- -help */
|
||
status = XrmGetResource (*db,
|
||
StrJoin (buff, sizeof (buff),
|
||
appName, ".butilHelp"),
|
||
"ProgramName.Values",
|
||
&type, &value);
|
||
do_help = (status) ? True : False;
|
||
if (do_help) {
|
||
show_help (NULL);
|
||
exit (EXIT_SUCCESS);
|
||
}
|
||
/*---------------------------------------------------------- -? */
|
||
status = XrmGetResource (*db,
|
||
StrJoin (buff, sizeof (buff),
|
||
appName, ".butilHelpItem"),
|
||
"ProgramName.Values",
|
||
&type, &value);
|
||
do_help = (status) ? True : False;
|
||
if (do_help) {
|
||
len = sizeof (buff);
|
||
StrEdit (buff, value.addr, "trim lowercase", &len);
|
||
show_help (buff);
|
||
exit (EXIT_SUCCESS);
|
||
}
|
||
/*---------------------------------------------------------- -verbose */
|
||
status = XrmGetResource (*db,
|
||
StrJoin (buff, sizeof (buff),
|
||
appName, ".butilVerbose"),
|
||
"ProgramName.Values",
|
||
&type, &value);
|
||
Verbose = verbose = (status) ? True : False;
|
||
/*---------------------------------------------------------- -host */
|
||
status = XrmGetResource (*db,
|
||
StrJoin (buff, sizeof (buff),
|
||
appName, ".butilHost"),
|
||
"ProgramName.Values",
|
||
&type, &value);
|
||
if (!status) {
|
||
Rmt_host[0] = NIL;
|
||
}else {
|
||
StrJoin (Rmt_host, sizeof (Rmt_host), value.addr, "");
|
||
if (verbose) printf ("Target processor is \"%s\".\n", Rmt_host);
|
||
}
|
||
/*---------------------------------------------------------- -port */
|
||
status = XrmGetResource (*db,
|
||
StrJoin (buff, sizeof (buff),
|
||
appName, ".butilPort"),
|
||
"ProgramName.Values",
|
||
&type, &value);
|
||
if (!status || (sscanf (value.addr, "%d", &Rmt_port) != 1)) {
|
||
Rmt_port = DFLT_PORT;
|
||
if (verbose) printf ("Using the default TCP/IP port number of ");
|
||
}else {
|
||
if (verbose) printf ("TCP/IP port number = ");
|
||
}
|
||
if (verbose) printf ("%d\n", Rmt_port);
|
||
/*----------------------------------------------------------*/
|
||
return True;
|
||
}
|
||
/*
|
||
**--------------------------------------------------------------------------*/
|
||
void get_SINQHM_FRONTEND (
|
||
/* ===================
|
||
** Extract info from the SINQHM_FRONTEND
|
||
** environment variable.
|
||
*/
|
||
char *host, int host_l, char *host_dflt,
|
||
int *port, int port_dflt,
|
||
int *pktlen, int pktlen_dflt) {
|
||
|
||
int env_len;
|
||
char *p_env, *token;
|
||
char my_env[100];
|
||
|
||
p_env = getenv ("SINQHM_FRONTEND"); /* Get pointer to env var */
|
||
if (p_env == NULL) {
|
||
/* Env. var. not found, prompt the user ... */
|
||
printf ("\n"
|
||
" The name of the Histogram Memory is defined neither as part of "
|
||
"the command,\n"
|
||
" nor via the environment variable SINQHM_FRONTEND nor in the "
|
||
"resource data\n"
|
||
" base. You must therefore specify the details of the Hist Mem "
|
||
"interactively.\n"
|
||
"\n"
|
||
" Please specify the following on a single line:\n");
|
||
if ((host_dflt == NULL) || (host_dflt[0] == NIL)) {
|
||
printf ("\n"
|
||
" Name of Histogram Memory (no default)\n"
|
||
" TCP/IP port number of HM server (default = %d)\n"
|
||
" Max send/rcve packet size (default = %d)\n",
|
||
port_dflt, pktlen_dflt);
|
||
}else {
|
||
printf ("\n"
|
||
" Name of Histogram Memory (default = \"%s\")\n"
|
||
" TCP/IP port number of HM server (default = %d)\n"
|
||
" Max send/rcve packet size (default = %d)\n",
|
||
host_dflt, port_dflt, pktlen_dflt);
|
||
}
|
||
printf ("\n"
|
||
"Specify Hist Mem information> ");
|
||
if (fgets (my_env, sizeof (my_env), stdin) == NULL) exit (EXIT_SUCCESS);
|
||
env_len = strlen (my_env);
|
||
if (my_env[env_len-1] != '\n') {
|
||
printf ("Name is too long!\n");
|
||
exit (EXIT_FAILURE);
|
||
}
|
||
env_len = sizeof (my_env);
|
||
StrEdit (my_env, my_env, "uncomment compress trim", &env_len);
|
||
}else { /* Make a local copy of it in case the original is in ..
|
||
** .. read-protected memory (strtok needs to be able to ..
|
||
** .. modify it */
|
||
env_len = sizeof (my_env);
|
||
StrEdit (my_env, p_env, "uncomment compress trim", &env_len);
|
||
}
|
||
token = (env_len == 0) ? NULL : strtok (my_env, " \t\n,"); /* Get host token */
|
||
if ((token == NULL) || (token[0] == ' ')) {
|
||
/* Host token not found, return defaults */
|
||
StrJoin (host, host_l, host_dflt, "");
|
||
*port = port_dflt;
|
||
*pktlen = pktlen_dflt;
|
||
}else {
|
||
StrJoin (host, host_l, token, "");
|
||
token = strtok (NULL, " \t\n,"); /* Get port token */
|
||
if (token == NULL) {
|
||
*port = port_dflt; /* Port token not found, return defaults */
|
||
*pktlen = pktlen_dflt;
|
||
}else {
|
||
if (sscanf (token, "%d", port) != 1) {
|
||
*port = port_dflt; /* Port token illegal, return defaults */
|
||
*pktlen = pktlen_dflt;
|
||
}else {
|
||
token = strtok (NULL, " \t,"); /* Get packet-size token */
|
||
if (token == NULL) {
|
||
*pktlen = pktlen_dflt; /* Packet-size token not found, use dflt */
|
||
}else {
|
||
if (sscanf (token, "%d", pktlen) != 1) {
|
||
*pktlen = pktlen_dflt; /* Packet-size token illegal, use dflt */
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
/*
|
||
**--------------------------------------------------------------------------*/
|
||
int openConnection (
|
||
/* ==============
|
||
** Open connection to histogram memory front-end.
|
||
*/
|
||
char *host,
|
||
int port) {
|
||
|
||
int i, status, my_skt;
|
||
struct sockaddr_in lcl_sockname;
|
||
struct sockaddr_in rmt_sockname;
|
||
int rmt_inet_addr;
|
||
struct in_addr *rmt_inet_addr_pntr;
|
||
struct hostent *rmt_hostent;
|
||
int rmt_sockname_len;
|
||
unsigned int oto_len, oto_status;
|
||
char old_time_out[4];
|
||
union {
|
||
char chars[4];
|
||
int val;
|
||
} time_out;
|
||
/*
|
||
** Get Internet address of the front-end.
|
||
*/
|
||
for (i=0; i < strlen (host); i++) host[i] = tolower (host[i]);
|
||
rmt_hostent = gethostbyname (host);
|
||
if (rmt_hostent == NULL) {
|
||
/*
|
||
** The following code is to handle hosts which are not yet
|
||
** in the BIND data base.
|
||
*/
|
||
if (strcmp (host, "sqfe01") == 0) {
|
||
rmt_inet_addr_pntr = (struct in_addr *) &rmt_inet_addr;
|
||
rmt_inet_addr = inet_addr ("129.129.56.181");
|
||
}else {
|
||
printf ("Target processor is %s.\n", host);
|
||
FailInet ("\nGethostbyname error.");
|
||
}
|
||
}else {
|
||
rmt_inet_addr_pntr = (struct in_addr *) rmt_hostent->h_addr_list[0];
|
||
}
|
||
printf (" Target processor is %s ", host);
|
||
printf ("(%s)\n", inet_ntoa (*rmt_inet_addr_pntr));
|
||
printf (" Server Port %d\n", port);
|
||
/*
|
||
** Create a TCP/IP socket for prelim. connect to server and bind it.
|
||
*/
|
||
my_skt = socket (AF_INET, SOCK_STREAM, 0);
|
||
if (my_skt == -1) FailInet ("Socket error.\n");
|
||
|
||
lcl_sockname.sin_family = AF_INET;
|
||
lcl_sockname.sin_port = htons (0);
|
||
lcl_sockname.sin_addr.s_addr = 0;
|
||
status = bind (my_skt, (struct sockaddr *) &lcl_sockname,
|
||
sizeof (lcl_sockname));
|
||
if (status == -1) FailInet ("Bind error.\n");
|
||
/*---------------------------
|
||
** Set short time-out (VMS systems only)
|
||
*/
|
||
#ifdef __VMS
|
||
oto_len = sizeof (old_time_out); /* Save current time-out first */
|
||
oto_status = getsockopt (my_skt, IPPROTO_TCP, UCX$C_TCP_PROBE_IDLE,
|
||
old_time_out, &oto_len);
|
||
if (oto_status == 0) {
|
||
time_out.val = 5; /* Set new time-out */
|
||
status = setsockopt (my_skt, IPPROTO_TCP, UCX$C_TCP_PROBE_IDLE,
|
||
time_out.chars, sizeof (time_out));
|
||
}
|
||
#endif
|
||
/*
|
||
**========================================= Now connect to the server.
|
||
*/
|
||
rmt_sockname_len = sizeof (rmt_sockname);
|
||
rmt_sockname.sin_family = AF_INET;
|
||
rmt_sockname.sin_port = htons (port);
|
||
rmt_sockname.sin_addr.s_addr = rmt_inet_addr_pntr->s_addr;
|
||
status = connect (my_skt, (struct sockaddr *) &rmt_sockname,
|
||
sizeof (rmt_sockname));
|
||
if (status == -1) {
|
||
GetErrno (&My_errno, &My_vaxc_errno);
|
||
FailInet ("Connect error\n");
|
||
}
|
||
/*---------------------------
|
||
** Restore time-out (VMS only)
|
||
*/
|
||
#ifdef __VMS
|
||
if (oto_status == 0) {
|
||
setsockopt (my_skt, IPPROTO_TCP, UCX$C_TCP_PROBE_IDLE,
|
||
old_time_out, oto_len);
|
||
}
|
||
#endif
|
||
return my_skt;
|
||
}
|
||
/*
|
||
**--------------------------------------------------------------------------*/
|
||
int read_boot_line (
|
||
/* ==============
|
||
** Get the boot line from the server.
|
||
*/
|
||
int skt, /* The socket to read from */
|
||
char *recd, /* Buffer to receive the boot line */
|
||
int s_recd) { /* Size of buffer */
|
||
|
||
char hdr_buff[8], *p_addr;
|
||
int i, j, len, status, bytes_to_come;
|
||
/*----------------------------------------
|
||
** Get first 4 bytes which gives the length to follow
|
||
*/
|
||
status = recv (skt, hdr_buff, 4, 0);
|
||
if (status != 4) FailInet ("recv error on bootline header.\n");
|
||
|
||
i = sscanf (hdr_buff, "%4d%n", &len, &j); /* Convert to binary */
|
||
if ((i != 1) || (j != 4)) {
|
||
printf ("Header bytes are not ASCII coded decimal: 0x%x 0x%x 0x%x 0x%x\n",
|
||
hdr_buff[0], hdr_buff[1], hdr_buff[2], hdr_buff[3]);
|
||
exit (EXIT_FAILURE);
|
||
}
|
||
|
||
if (len >= s_recd) {
|
||
printf (" Boot-line length is %d\n", len);
|
||
printf ("Too long for buffer. Buffer length = %d\n", s_recd);
|
||
flushNet (len);
|
||
exit (EXIT_FAILURE);
|
||
}
|
||
|
||
bytes_to_come = len;
|
||
p_addr = recd;
|
||
|
||
while (bytes_to_come > 0) {
|
||
status = recv (skt, p_addr, bytes_to_come, 0);
|
||
if (status <= 0) break;
|
||
bytes_to_come -= status;
|
||
p_addr += status;
|
||
}
|
||
if (bytes_to_come != 0) {
|
||
if (status < 0) {
|
||
FailInet ("R/W-Socket recv error");
|
||
}else if (status == 0) {
|
||
FailInet ("R/W-Socket recv error -- return code = 0");
|
||
}
|
||
exit (EXIT_FAILURE);
|
||
}
|
||
i = strlen (recd);
|
||
if (i > len) {
|
||
printf (" Length of boot-line buffer read from target = %d.\n", len);
|
||
printf (" String length of boot-line = %d.\n", i);
|
||
printf (" It appears as though the boot-line is not null terminated!");
|
||
exit (EXIT_FAILURE);
|
||
}
|
||
return True;
|
||
}
|
||
/*
|
||
**--------------------------------------------------------------------------*/
|
||
int send_a_close (
|
||
/* ============
|
||
** Send a "CLOSE" message to the target host.
|
||
*/
|
||
int skt) { /* The socket to send to. */
|
||
|
||
char cmnd_buff[32], buff[32];
|
||
int status, i, bootlen;
|
||
|
||
strcpy (cmnd_buff, "CLOSE");
|
||
status = send (skt, cmnd_buff, 8, 0);
|
||
if (status != 8) FailInet ("send_a_close - bad send");
|
||
|
||
status = recv (skt, buff, 4, 0); /* Await the response */
|
||
/* But do not check it */
|
||
return True;
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------*/
|
||
int setup_xrm_database (
|
||
/* ==================
|
||
** Setup Resource Manager Database
|
||
*/
|
||
XrmDatabase *db,
|
||
char *name[],
|
||
int *argc,
|
||
char *argv[],
|
||
int verbose) {
|
||
|
||
static char our_name[80] = "Unknown"; /* This holds the program name */
|
||
static char lkup_name[80] = "Unknown"; /* Name for looking in database */
|
||
|
||
int status, i, first = True;
|
||
char text[80];
|
||
char full_nm0[80];
|
||
char full_nm1[80];
|
||
char *p_fil[] = {0,0,0,0,0,0,0,0,0,0};
|
||
char *my_name;
|
||
char *my_name_last;
|
||
|
||
char *name_type;
|
||
XrmValue name_value;
|
||
|
||
XrmDatabase cmnd_line_db = NULL;
|
||
XrmDatabase lcl_db = NULL;
|
||
/*-----------------------------------------------------
|
||
** This routine merges some resource databases with options specified on
|
||
** the command line. Resources can then be looked up using XrmGetResource.
|
||
** This is a bit like the X-toolkit routine XtAppInitialize does for the
|
||
** extraction of resources by XtGetApplicationResources.
|
||
**
|
||
** I can't help but think that there's a simpler way of doing this but I
|
||
** can't find it in the X manuals. Basically, the problem arises with wanting
|
||
** to avoid the calling program being associated with an X-display, i.e. it
|
||
** is intended for use by "command-line oriented" programs. All the nice,
|
||
** easy-to-use resource/command-line setup routines in Xlib or Xtlib seem to
|
||
** assume one is going to use a display -- not surprising, I suppose,
|
||
** since the concept of Xlib is for writing window based applications!
|
||
**
|
||
** Anyway, the point is that the following way turns out to be lacking
|
||
** when it gets tested in anger.
|
||
*/
|
||
status = True; /* Assume success */
|
||
|
||
our_name[0] = NIL;
|
||
/*
|
||
** Make a list of the databases to be merged, highest priority first.
|
||
*/
|
||
#ifdef __VMS
|
||
p_fil[0] = "decw$user_defaults:SinQ_rc.dat";
|
||
p_fil[1] = "decw$group_defaults:SinQ_rc.dat";
|
||
p_fil[2] = "decw$system_defaults:SinQ_rc.dat";
|
||
p_fil[3] = "decw$user_defaults:decw$xdefaults.dat";
|
||
p_fil[4] = "decw$group_defaults:decw$xdefaults.dat";
|
||
p_fil[5] = "decw$system_defaults:decw$xdefaults.dat";
|
||
p_fil[6] = NULL;
|
||
if (*argc > 0) { /* Find out what we are called - parse file nm */
|
||
my_name = strstr (argv[0], "]"); /* Find end of directory, i.e. "]" */
|
||
my_name++; /* Skip over "]" */
|
||
if (my_name[0] == '[') { /* Handle possible concealed device */
|
||
my_name = strstr (my_name, "]");
|
||
my_name++;
|
||
}
|
||
i = sizeof (our_name);
|
||
StrEdit (our_name, my_name, "lowercase", &i); /* Copy the rest */
|
||
strtok (our_name, "."); /* Close it off at "." */
|
||
}
|
||
#else
|
||
p_fil[0] = StrJoin (full_nm0, sizeof (full_nm0),
|
||
getenv ("HOME"), "/SinQ_rc");
|
||
p_fil[1] = "/usr/lib/X11/app-defaults/SinQ_rc";
|
||
p_fil[2] = StrJoin (full_nm1, sizeof (full_nm1),
|
||
getenv ("HOME"), "/.Xdefaults");
|
||
p_fil[3] = "/usr/lib/X11/app-defaults/Xdefaults";
|
||
p_fil[4] = NULL;
|
||
if (*argc > 0) { /* Find out what we are called - parse file nm */
|
||
/* Find end of directories */
|
||
my_name = argv[0] - 1;
|
||
while (my_name != NULL) {
|
||
my_name_last = my_name;
|
||
my_name_last++;
|
||
my_name = strstr (my_name_last, "/");
|
||
}
|
||
StrJoin (our_name, sizeof (our_name), my_name_last, "");
|
||
}
|
||
#endif
|
||
if (verbose) printf ("My name is \"%s\"\n", our_name);
|
||
/*
|
||
** Initialise and combine all databases
|
||
*/
|
||
XrmInitialize ();
|
||
for (i = 0; i < XtNumber (p_fil); i++) {
|
||
if (p_fil[i] == NULL) break;
|
||
status = XrmCombineFileDatabase (p_fil[i], &lcl_db, False);
|
||
if ((status != 0) && verbose) {
|
||
if (first)
|
||
printf ("Resource database created from file %s.\n", p_fil[i]);
|
||
if (!first)
|
||
printf ("File %s merged into resource database.\n", p_fil[i]);
|
||
first = False;
|
||
}
|
||
}
|
||
/*----------------------------------------------------------------
|
||
** See if there's anything specified on cmnd line, incl "name".
|
||
*/
|
||
XrmParseCommand (&cmnd_line_db,
|
||
OpTable_0, XtNumber(OpTable_0), our_name, argc, argv);
|
||
if (cmnd_line_db != NULL) {
|
||
/*
|
||
** There was at least 1 item on cmnd line. Process the line.
|
||
** If -name was specified, adopt it.
|
||
*/
|
||
status = XrmGetResource (cmnd_line_db, /* See if a name was specified */
|
||
StrJoin (text, sizeof (text), our_name, ".name"),
|
||
"ProgramName.Values",
|
||
&name_type, &name_value);
|
||
if (status) {
|
||
i = sizeof (lkup_name);
|
||
StrEdit (lkup_name, name_value.addr, "lowercase", &i);
|
||
printf ("Option list name is \"%s\"\n", lkup_name);
|
||
}else {
|
||
strcpy (lkup_name, our_name);
|
||
}
|
||
/*
|
||
** Loop over all items in OpTable_0 and merge them into database,
|
||
** taking care of any possible name changes.
|
||
*/
|
||
for (i = 0; i < XtNumber (OpTable_0); i++) {
|
||
if (strcmp (OpTable_0[i].option, "-name") == 0) continue;
|
||
status = XrmGetResource (cmnd_line_db,
|
||
StrJoin (text, sizeof (text),
|
||
our_name, OpTable_0[i].specifier),
|
||
"ProgramName.Values",
|
||
&name_type, &name_value);
|
||
if (status) {
|
||
StrJoin (text, sizeof (text), lkup_name, OpTable_0[i].specifier);
|
||
XrmPutResource (&lcl_db, text, "String", &name_value);
|
||
}
|
||
}
|
||
}
|
||
/*----------------------------------------------------------------
|
||
*/
|
||
*name = lkup_name;
|
||
*db = lcl_db;
|
||
if ((lcl_db == NULL) && verbose)
|
||
printf ("\007Warning -- no resource database found.\n");
|
||
|
||
XrmDestroyDatabase (cmnd_line_db);
|
||
/*
|
||
** XrmPutFileDatabase (lcl_db, "sinqhm_client.db");
|
||
*/
|
||
return status;
|
||
}
|
||
/*
|
||
**--------------------------------------------------------------------------*/
|
||
int show_boot_line (
|
||
/* ==============
|
||
** Display the boot line.
|
||
**
|
||
*/ char *recd) { /* The boot-line as received from serever */
|
||
|
||
char *tok, *body;
|
||
int i, j, status, toklen, empty;
|
||
|
||
/*
|
||
** Scan through the boot-line printing non-null items.
|
||
*/
|
||
empty = True;
|
||
tok = strtok (recd, ":\n");
|
||
while (tok != NULL) {
|
||
toklen = strlen (tok);
|
||
if (tok[toklen+1] == '\n') { /* Watch out for tokens with no body */
|
||
tok = strtok (NULL, ":\n"); /* Skip an empty body */
|
||
}else {
|
||
body = strtok (NULL, "\n");
|
||
if ((strcmp (tok, "bootDev") == 0) && (body != NULL)) {
|
||
empty = False;
|
||
printf (" boot device : %s\n", body);
|
||
}else if ((strcmp (tok, "procNum") == 0) && (body != NULL)) {
|
||
status = sscanf (body, "%i%n", &i, &j);
|
||
if ((status != 1) || (j != strlen (body))) {
|
||
printf ("show_boot_line: Bad value found for procNum: \"%s\"\n", body);
|
||
}else {
|
||
empty = False;
|
||
printf (" processor number : %s\n", body);
|
||
}
|
||
}else if ((strcmp (tok, "hostName") == 0) && (body != NULL)) {
|
||
empty = False;
|
||
printf (" host name : %s\n", body);
|
||
}else if ((strcmp (tok, "bootFile") == 0) && (body != NULL)) {
|
||
empty = False;
|
||
printf (" file name : %s\n", body);
|
||
}else if ((strcmp (tok, "ead") == 0) && (body != NULL)) {
|
||
empty = False;
|
||
printf (" inet on ethernet (e) : %s\n", body);
|
||
}else if ((strcmp (tok, "bad") == 0) && (body != NULL)) {
|
||
empty = False;
|
||
printf (" inet on backplane (b): %s\n", body);
|
||
}else if ((strcmp (tok, "had") == 0) && (body != NULL)) {
|
||
empty = False;
|
||
printf (" host inet (h) : %s\n", body);
|
||
}else if ((strcmp (tok, "gad") == 0) && (body != NULL)) {
|
||
empty = False;
|
||
printf (" gateway inet (g) : %s\n", body);
|
||
}else if ((strcmp (tok, "usr") == 0) && (body != NULL)) {
|
||
empty = False;
|
||
printf (" user (u) : %s\n", body);
|
||
}else if ((strcmp (tok, "passwd") == 0) && (body != NULL)) {
|
||
empty = False;
|
||
printf (" ftp password (pw) : %s\n", body);
|
||
}else if ((strcmp (tok, "flags") == 0) && (body != NULL)) {
|
||
status = sscanf (body, "%i%n", &i, &j);
|
||
if ((status != 1) || (j != strlen (body))) {
|
||
printf ("show_boot_line: Bad value found for flags: \"%s\"\n", body);
|
||
}else {
|
||
empty = False;
|
||
printf (" flags (f) : %s\n", body);
|
||
}
|
||
}else if ((strcmp (tok, "targetName") == 0) && (body != NULL)) {
|
||
empty = False;
|
||
printf (" target name (tn) : %s\n", body);
|
||
}else if ((strcmp (tok, "startupScript") == 0) && (body != NULL)) {
|
||
empty = False;
|
||
printf (" startup script (s) : %s\n", body);
|
||
}else if ((strcmp (tok, "other") == 0) && (body != NULL)) {
|
||
empty = False;
|
||
printf (" other (o) : %s\n", body);
|
||
}else {
|
||
if (body != NULL) {
|
||
printf ("show_boot_line: Bad token found in boot-line: "
|
||
"\"%s\" \"%s\"\n", tok, body);
|
||
}else {
|
||
printf ("show_boot_line: Token found with NULL body in boot-line: "
|
||
"\"%s\"\n", tok);
|
||
}
|
||
}
|
||
tok = strtok (NULL, ":");
|
||
}
|
||
}
|
||
if (empty) printf (" The boot-line was empty!\n");
|
||
return EXIT_SUCCESS;
|
||
}
|
||
/*
|
||
**--------------------------------------------------------------------------*/
|
||
void show_help (char *token) {
|
||
/* =========
|
||
** Display help text
|
||
*/
|
||
int len;
|
||
|
||
if ((token == NULL) || (token[0] == NIL)) {
|
||
printf ("\n"
|
||
" The following commands are recognised by SINQHM_BOOTUTIL_CLIENT:\n"
|
||
"\n"
|
||
" help or ? - generate this help text.\n"
|
||
" config - interactive configuration of target boot-line.\n"
|
||
" reboot - reboot the target.\n"
|
||
" rundown - cause the bootUtil server on the target to exit.\n"
|
||
" show - display the boot-line of the target.\n"
|
||
"\n"
|
||
" To get more detailed help on a specific command, specify:\n"
|
||
"\n"
|
||
" HELP <cmnd>\n"
|
||
"\n"
|
||
" on the command line. For information on the environment setup "
|
||
"for the\n"
|
||
" program, specify:\n"
|
||
"\n"
|
||
" HELP SETUP\n"
|
||
"\n"
|
||
" on the command line.\n"
|
||
"\n");
|
||
} else if (StrMatch ("CONFIG", token, 1) == 0) {
|
||
printf ("\n"
|
||
" Config:\n"
|
||
" The current boot-line information will be displayed. The "
|
||
"user will then\n"
|
||
" be prompted for new settings for each field of the boot-"
|
||
"line. The modified\n"
|
||
" boot-line will then be displayed and the user asked whether "
|
||
"it should be\n"
|
||
" written to the non-volatile memory of the target or not.\n"
|
||
"\n");
|
||
}else if (StrMatch ("REBOOT", token, 2) == 0) {
|
||
printf ("\n"
|
||
" Reboot\n"
|
||
" The target processor will be rebooted.\n"
|
||
"\n");
|
||
}else if (StrMatch ("RUNDOWN", token, 2) == 0) {
|
||
printf ("\n"
|
||
" Rundown\n"
|
||
" The bootUtil server on the target processor will be "
|
||
"requested to exit.\n"
|
||
" Manual intervention on the target will then be necessary "
|
||
"before this program\n"
|
||
" can be used again.\n"
|
||
"\n");
|
||
}else if (StrMatch ("SHOW", token, 1) == 0) {
|
||
printf ("\n"
|
||
" Show:\n"
|
||
" The current boot-line information of the target will be "
|
||
"displayed.\n"
|
||
"\n");
|
||
}else if (StrMatch ("SETUP", token, 2) == 0) {
|
||
printf ("\n"
|
||
" Setup:\n"
|
||
" The target host with which SinqHM_bootUtil_Client is to "
|
||
"communicate\n"
|
||
" can most easily be specified via options of the form:\n"
|
||
"\n"
|
||
" -host <target-name> -port <port>\n"
|
||
"\n"
|
||
" on the command line. There is no default for <target-name> "
|
||
"whereas\n"
|
||
" <port>, which specifies the TCP/IP port number at which "
|
||
"the SinqHM_bootUtil\n"
|
||
" server is accepting connections on the target, defaults "
|
||
"to 2300.\n"
|
||
"\n"
|
||
" Alternatively, the environment variable SINQHM_FRONTEND "
|
||
"may be defined.\n"
|
||
" On Unix systems this is done thus:\n"
|
||
"\n"
|
||
" setenv SINQHM_FRONTEND \"<target-name> <port>\"\n"
|
||
"\n"
|
||
" On VMS systems, logical names are used instead, e.g.\n"
|
||
"\n"
|
||
" define/job sinqhm_frontend \"<target-name> <port>\"\n"
|
||
"\n"
|
||
" It is also possible to specify <target-name> and <port> in "
|
||
"an X-resources\n"
|
||
" data base. The resource names are \"butilHost\" and "
|
||
"\"butilPort\".\n"
|
||
"\n");
|
||
}else {
|
||
printf ("Sorry, no help available for \"%s\"!\n", token);
|
||
}
|
||
}
|
||
/*
|
||
**==========================================================================
|
||
**
|
||
** Main line program
|
||
** ------------------
|
||
**==========================================================================*/
|
||
int main (int argc, char *argv[]) {
|
||
/* ====
|
||
*/
|
||
int i, j, k, status, is, dummy, cmnd_len;
|
||
|
||
char cmnd[16], ist_bootline[1024], new_bootline[1024], buff[1024];
|
||
int boot_line_changed;
|
||
|
||
char recd[256], recd1[256];
|
||
char last_recd[256] = {NIL};
|
||
char *verb;
|
||
int l_recd;
|
||
XrmDatabase my_db;
|
||
char *appName;
|
||
/*============================================================================
|
||
*/
|
||
printf ("SinqHM_bootUtil_Client Ident \"%s\" started.\n", IDENT);
|
||
/*============================================================================
|
||
** Declare an exit handler to tidy up if we get forced to exit.
|
||
*/
|
||
is = atexit (exit_handler);
|
||
if (is != 0) {
|
||
printf ("SINQHM_BOOTUTIL_CLIENT -- error setting up exit handler.");
|
||
return EXIT_FAILURE;
|
||
}
|
||
/*-------------------------------------------------------------
|
||
** Setup the resource database and look up the resources.
|
||
*/
|
||
Verbose = False;
|
||
for (i = 1; i < argc; i++) if (strcmp ("-v", argv[i]) == 0) Verbose = True;
|
||
|
||
setup_xrm_database (&my_db, &appName, &argc, argv, Verbose);
|
||
status = get_check_resources (&my_db, appName, Verbose);
|
||
if (!status) return False;
|
||
/*============================================================================
|
||
** Analyse the arguments to see what has to be done.
|
||
*/
|
||
if (argc > 1) { /* There should just be at least one argument remaining.
|
||
*/
|
||
StrJoin (cmnd, sizeof (cmnd), argv[1], "");
|
||
cmnd_len = sizeof (cmnd);
|
||
StrEdit (cmnd, argv[1], "upcase", &cmnd_len); /* Cvt to upper case */
|
||
if (cmnd[0] == '-') /* Ignore a leading "-" */
|
||
StrJoin (cmnd, sizeof (cmnd), &cmnd[1], "");
|
||
}else {
|
||
printf ("\n No command was specified on the command line, "
|
||
"default is \"SHOW\".\n"
|
||
" Specify \"HELP\" for help.\n\n");
|
||
strcpy (cmnd, "SHOW");
|
||
}
|
||
if (StrMatch (cmnd, "HELP", 1) || StrMatch (cmnd, "?", 1)) {
|
||
if (argc > 2) show_help (argv[2]); else show_help (NULL);
|
||
return EXIT_SUCCESS;
|
||
}
|
||
|
||
if (!StrMatch (cmnd, "CONFIG", 1) &&
|
||
!StrMatch (cmnd, "REBOOT", 6) &&
|
||
!StrMatch (cmnd, "RUNDOWN", 7) &&
|
||
!StrMatch (cmnd, "SHOW", 1)) {
|
||
printf ("\n\"%s\" is not a recognised command.\n\n", cmnd);
|
||
show_help (NULL);
|
||
return EXIT_FAILURE;
|
||
}
|
||
/*============================================================================
|
||
** Find out the location of the bootUtil Server and make
|
||
** a connection to it. Any errors during this phase cause the program
|
||
** to exit with an error status.
|
||
*/
|
||
if (Rmt_host[0] == NIL) {
|
||
get_SINQHM_FRONTEND (Rmt_host, sizeof (Rmt_host), "",
|
||
&Rmt_port, DFLT_PORT,
|
||
&dummy, 0);
|
||
if (Rmt_host[0] == NIL) {
|
||
printf ("\n"
|
||
" No target processor has been specified!\n"
|
||
"\n");
|
||
show_help ("setup");
|
||
return EXIT_FAILURE;
|
||
}
|
||
}
|
||
/*============================================================================*/
|
||
Cnct_skt = openConnection (Rmt_host, Rmt_port);
|
||
status = read_boot_line (Cnct_skt, ist_bootline, sizeof (ist_bootline));
|
||
status = send_a_close (Cnct_skt);
|
||
close (Cnct_skt);
|
||
Cnct_skt = 0;
|
||
|
||
strcpy (new_bootline, ist_bootline);
|
||
boot_line_changed = False;
|
||
|
||
i = printf ("\nCurrent boot-line of %s is:\n", Rmt_host);
|
||
for (j = 3; j < i; j++) printf ("="); printf ("\n");
|
||
status = show_boot_line (ist_bootline);
|
||
/*
|
||
**=========================================== Carry out the command =========
|
||
*/
|
||
if (StrMatch (cmnd, "CONFIG", 1)) { /* Modify the configuration? */
|
||
status = do_config (new_bootline);
|
||
if (status) {
|
||
Cnct_skt = openConnection (Rmt_host, Rmt_port);
|
||
status = read_boot_line (Cnct_skt, ist_bootline, sizeof (ist_bootline));
|
||
status = send_a_close (Cnct_skt);
|
||
close (Cnct_skt);
|
||
Cnct_skt = 0;
|
||
if (status) {
|
||
i = printf ("\nNew boot-line of %s is:\n", Rmt_host);
|
||
for (j = 3; j < i; j++) printf ("="); printf ("\n");
|
||
status = show_boot_line (ist_bootline);
|
||
printf ("\n");
|
||
}else {
|
||
printf ("\007Error getting new boot-line information!\n");
|
||
}
|
||
}
|
||
}else if (StrMatch (cmnd, "REBOOT", 2)) { /* Reboot? */
|
||
status = do_reboot ();
|
||
}else if (StrMatch (cmnd, "RUNDOWN", 2)) { /* Rundown? */
|
||
status = do_rundown ();
|
||
}else if (StrMatch (cmnd, "SHOW", 1)) { /* Show? */
|
||
/* Already done! */
|
||
}else {
|
||
printf ("\n Illegal command - try \"HELP\".\n");
|
||
status = EXIT_FAILURE;
|
||
}
|
||
|
||
return status;
|
||
}
|
||
/*==================================== End of SINQHM_BOOTUTIL_CLIENT.C ======*/
|