064ec37e9a
- 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 ======*/
|