vxWorks boot utility server
This commit is contained in:
627
sinqhm/sinqhm_bootutil.c
Executable file
627
sinqhm/sinqhm_bootutil.c
Executable file
@ -0,0 +1,627 @@
|
||||
#define IDENT "1A02"
|
||||
/*
|
||||
** +--------------------------------------------------------------+
|
||||
** | Paul Scherrer Institute |
|
||||
** | SINQ Division |
|
||||
** | |
|
||||
** | 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.c
|
||||
**
|
||||
** Author . . . . . . . . . . : D. Maden
|
||||
** Date of creation . . . . . . : Aug 1999
|
||||
**
|
||||
** Updates:
|
||||
** 1A01 16-Aug-1999 DM Initial version.
|
||||
**---------------------------------------------------------------------------
|
||||
** SinqHM_bootUtil.c is a simple TCP/IP server for VxWorks.
|
||||
** It obtains information about the VxWorks boot line.
|
||||
*/
|
||||
/*
|
||||
** To compile and link this program for VxWorks on PSS123, use:
|
||||
**
|
||||
set src = "lnsa09:tas_src:[sinqhm]"
|
||||
rcp -p "${src}SinqHM_bootUtil.c" SinqHM_bootUtil.c
|
||||
ccvx -I${WIND_BASE}/target/config/all SinqHM_bootUtil.c
|
||||
** where
|
||||
ccvx = ccppc -O0 \
|
||||
-mcpu=603 \
|
||||
-I${WIND_BASE}/target/h \
|
||||
-fno-builtin \
|
||||
-fno-for-scope \
|
||||
-nostdinc \
|
||||
-DCPU=PPC603 \
|
||||
-D_GNU_TOOL \
|
||||
-gdwarf -c -Wimplicit
|
||||
|
||||
** and, on the target,
|
||||
**
|
||||
** -> ld < /home/pss123/aco/maden/wind/SinqHM/Dflt/SinqHM_srv.o
|
||||
** -> ld < /home/pss123/aco/maden/wind/SinqHM/SinqHM_bootUtil.o
|
||||
** -> taskSpawn "bootUtil", 100, 8, 20000, SinqHM_bootUtil, <port>
|
||||
** ^
|
||||
** |
|
||||
** TCP/IP port number of the "bootUtil" service, dflt = 2300 -+
|
||||
**
|
||||
**====================================================================
|
||||
*/
|
||||
#include "vxWorks.h" /* always first */
|
||||
#include "taskLib.h"
|
||||
#include "sockLib.h"
|
||||
#include "bootLib.h"
|
||||
#include "rebootLib.h"
|
||||
#include "sysLib.h"
|
||||
#include "usrLib.h"
|
||||
#include "ioLib.h"
|
||||
|
||||
#if (CPU == PPC603)
|
||||
#include "../config/mv1603/config.h"
|
||||
#elif (CPU == PPC604)
|
||||
#include "../config/mv1604/config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
/*
|
||||
**==================== Global Definitions =====================================
|
||||
*/
|
||||
|
||||
#include "SinqHM_def.h"
|
||||
|
||||
#define MAX_ACTIONS 8
|
||||
#define MAX_ARGS 10
|
||||
#define SBU_PORT_DFLT 2300 /* The Dflt Internet Port for Server Requests */
|
||||
/*
|
||||
**==================== Global Variables =====================================
|
||||
*/
|
||||
uint Sbu_port; /* The port number to use for the service */
|
||||
char Sbu_name[20]; /* Our task name */
|
||||
/*
|
||||
**=============================================================================
|
||||
** Local routine prototypes.
|
||||
*/
|
||||
int sbu_doConfig (int skt);
|
||||
void sbu_doReboot ();
|
||||
void sbu_failInet (char *text);
|
||||
void sbu_failInet_str (char *text, char *str);
|
||||
void sbu_getErrno (int *his_errno);
|
||||
void sbu_showHelp (char *errmsg);
|
||||
|
||||
char *StrJoin (
|
||||
char *result,
|
||||
int result_size,
|
||||
char *str_a,
|
||||
char *str_b);
|
||||
int sbu_doConfig (int skt);
|
||||
/*
|
||||
**--------------------------------------------------------------------------*/
|
||||
int sbu_doConfig (int skt) {
|
||||
/* ============
|
||||
** Configure the vxWorks boot information
|
||||
*/
|
||||
char hdr_buff[8], *p_addr, recd[1024];
|
||||
int status, i, j, l_recd, bytes_to_come, toklen, changed;
|
||||
char *boot_line_addr, *b_status, *tok, *body;
|
||||
BOOT_PARAMS my_boot_params;
|
||||
|
||||
/*----------------------------------------
|
||||
** Get the new boot information over the network.
|
||||
**
|
||||
** Get first 4 bytes which gives the length to follow
|
||||
*/
|
||||
status = recv (skt, hdr_buff, 4, 0);
|
||||
if (status != 4) sbu_failInet ("recv error on bootline header.\n");
|
||||
|
||||
i = sscanf (hdr_buff, "%4d%n", &l_recd, &j); /* Convert to binary */
|
||||
if ((i != 1) || (j != 4)) {
|
||||
sprintf (recd, "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]);
|
||||
sbu_failInet (recd);
|
||||
}
|
||||
|
||||
if (l_recd >= sizeof (recd)) {
|
||||
sprintf (recd, "Too long for buffer. Buffer length = %d\n", l_recd);
|
||||
sbu_failInet (recd);
|
||||
}
|
||||
|
||||
bytes_to_come = l_recd;
|
||||
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) {
|
||||
sbu_failInet ("R/W-Socket recv error");
|
||||
}else if (status == 0) {
|
||||
sbu_failInet ("R/W-Socket recv error -- return code = 0");
|
||||
}
|
||||
sbu_failInet ("R/W-Socket recv error -- not enough data received");
|
||||
}
|
||||
/*
|
||||
** Initialise the boot line structure with the existing
|
||||
** contents of the boot line.
|
||||
*/
|
||||
boot_line_addr = (char *) BOOT_LINE_ADRS; /* Get pointer to the boot line */
|
||||
b_status = bootStringToStruct (boot_line_addr, &my_boot_params);
|
||||
if (*b_status != EOS) {
|
||||
printf ("\n%s: Bad status from \"bootStringToStruct\": 0x%02x\n",
|
||||
Sbu_name, *b_status);
|
||||
return False;
|
||||
}
|
||||
/*
|
||||
** Now scan through the new boot string replacing items in
|
||||
** the boot line structure as we find them.
|
||||
*/
|
||||
printf ("\nNew boot-line items are:\n");
|
||||
changed = False;
|
||||
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)) {
|
||||
if (strcmp (my_boot_params.bootDev, body) != 0) {
|
||||
changed = True;
|
||||
printf (" boot device : %s\n", body);
|
||||
strcpy (my_boot_params.bootDev, body);
|
||||
}
|
||||
}else if ((strcmp (tok, "procNum") == 0) && (body != NULL)) {
|
||||
status = sscanf (body, "%i%n", &i, &j);
|
||||
if ((status != 1) || (j != strlen (body))) {
|
||||
printf ("\n%s: Bad value found for procNum: \"%s\"\n", Sbu_name, body);
|
||||
return False;
|
||||
}
|
||||
if (my_boot_params.procNum != i) {
|
||||
changed = True;
|
||||
printf (" processor number : %s\n", body);
|
||||
my_boot_params.procNum = i;
|
||||
}
|
||||
}else if ((strcmp (tok, "hostName") == 0) && (body != NULL)) {
|
||||
if (strcmp (my_boot_params.hostName, body) != 0) {
|
||||
changed = True;
|
||||
printf (" host name : %s\n", body);
|
||||
strcpy (my_boot_params.hostName, body);
|
||||
}
|
||||
}else if ((strcmp (tok, "bootFile") == 0) && (body != NULL)) {
|
||||
if (strcmp (my_boot_params.bootFile, body) != 0) {
|
||||
changed = True;
|
||||
printf (" file name : %s\n", body);
|
||||
strcpy (my_boot_params.bootFile, body);
|
||||
}
|
||||
}else if ((strcmp (tok, "ead") == 0) && (body != NULL)) {
|
||||
if (strcmp (my_boot_params.ead, body) != 0) {
|
||||
changed = True;
|
||||
printf (" inet on ethernet (e) : %s\n", body);
|
||||
strcpy (my_boot_params.ead, body);
|
||||
}
|
||||
}else if ((strcmp (tok, "bad") == 0) && (body != NULL)) {
|
||||
if (strcmp (my_boot_params.bad, body) != 0) {
|
||||
changed = True;
|
||||
printf (" inet on backplane (b): %s\n", body);
|
||||
strcpy (my_boot_params.bad, body);
|
||||
}
|
||||
}else if ((strcmp (tok, "had") == 0) && (body != NULL)) {
|
||||
if (strcmp (my_boot_params.had, body) != 0) {
|
||||
changed = True;
|
||||
printf (" host inet (h) : %s\n", body);
|
||||
strcpy (my_boot_params.had, body);
|
||||
}
|
||||
}else if ((strcmp (tok, "gad") == 0) && (body != NULL)) {
|
||||
if (strcmp (my_boot_params.gad, body) != 0) {
|
||||
changed = True;
|
||||
printf (" gateway inet (g) : %s\n", body);
|
||||
strcpy (my_boot_params.gad, body);
|
||||
}
|
||||
}else if ((strcmp (tok, "usr") == 0) && (body != NULL)) {
|
||||
if (strcmp (my_boot_params.usr, body) != 0) {
|
||||
changed = True;
|
||||
printf (" user (u) : %s\n", body);
|
||||
strcpy (my_boot_params.usr, body);
|
||||
}
|
||||
}else if ((strcmp (tok, "passwd") == 0) && (body != NULL)) {
|
||||
if (strcmp (my_boot_params.passwd, body) != 0) {
|
||||
changed = True;
|
||||
printf (" ftp password (pw) : %s\n", body);
|
||||
strcpy (my_boot_params.passwd, body);
|
||||
}
|
||||
}else if ((strcmp (tok, "flags") == 0) && (body != NULL)) {
|
||||
status = sscanf (body, "%i%n", &i, &j);
|
||||
if ((status != 1) || (j != strlen (body))) {
|
||||
printf ("\n%s: Bad value found for flags: \"%s\"\n", Sbu_name, body);
|
||||
return False;
|
||||
}
|
||||
if (my_boot_params.flags != i) {
|
||||
changed = True;
|
||||
printf (" flags (f) : %s\n", body);
|
||||
my_boot_params.flags = i;
|
||||
}
|
||||
}else if ((strcmp (tok, "targetName") == 0) && (body != NULL)) {
|
||||
if (strcmp (my_boot_params.targetName, body) != 0) {
|
||||
changed = True;
|
||||
printf (" target name (tn) : %s\n", body);
|
||||
strcpy (my_boot_params.targetName, body);
|
||||
}
|
||||
}else if ((strcmp (tok, "startupScript") == 0) && (body != NULL)) {
|
||||
if (strcmp (my_boot_params.startupScript, body) != 0) {
|
||||
changed = True;
|
||||
printf (" startup script (s) : %s\n", body);
|
||||
strcpy (my_boot_params.startupScript, body);
|
||||
}
|
||||
}else if ((strcmp (tok, "other") == 0) && (body != NULL)) {
|
||||
if (strcmp (my_boot_params.other, body) != 0) {
|
||||
changed = True;
|
||||
printf (" other (o) : %s\n", body);
|
||||
strcpy (my_boot_params.other, body);
|
||||
}
|
||||
}else {
|
||||
if (body != NULL) {
|
||||
printf ("\n%s: Bad token found in new boot string: \"%s\" \"%s\"\n",
|
||||
Sbu_name, tok, body);
|
||||
}else {
|
||||
printf ("\n%s: Token found with NULL body in new boot string: \"%s\"\n",
|
||||
Sbu_name, tok);
|
||||
}
|
||||
printf ("\n%s: Boot string has not been re-configured!\n", Sbu_name);
|
||||
return False;
|
||||
}
|
||||
tok = strtok (NULL, ":");
|
||||
}
|
||||
}
|
||||
if (!changed) printf (" Nothing has been changed!\n");
|
||||
|
||||
status = bootStructToString (boot_line_addr, &my_boot_params);
|
||||
if (status != OK) {
|
||||
printf ("\n%s: Bad status from \"bootStringToStruct\": 0x%02x\n", Sbu_name,
|
||||
status);
|
||||
return False;
|
||||
}
|
||||
b_status = bootStringToStruct (boot_line_addr, &my_boot_params);
|
||||
if (*b_status != EOS) {
|
||||
printf ("\n%s: Bad status from \"bootStringToStruct\": 0x%02x\n",
|
||||
Sbu_name, *b_status);
|
||||
return False;
|
||||
}
|
||||
printf ("\nResulting vxWorks Boot-Line is:\n"
|
||||
" =================\n");
|
||||
|
||||
printf (" boot device : %s\n", my_boot_params.bootDev);
|
||||
printf (" processor number : %d\n", my_boot_params.procNum);
|
||||
printf (" host name : %s\n", my_boot_params.hostName);
|
||||
printf (" file name : %s\n", my_boot_params.bootFile);
|
||||
printf (" inet on ethernet (e) : %s\n", my_boot_params.ead);
|
||||
printf (" inet on backplane (b): %s\n", my_boot_params.bad);
|
||||
printf (" host inet (h) : %s\n", my_boot_params.had);
|
||||
printf (" gateway inet (g) : %s\n", my_boot_params.gad);
|
||||
printf (" user (u) : %s\n", my_boot_params.usr);
|
||||
printf (" ftp password (pw) : %s\n", my_boot_params.passwd);
|
||||
printf (" flags (f) : 0x%x\n", my_boot_params.flags);
|
||||
printf (" target name (tn) : %s\n", my_boot_params.targetName);
|
||||
printf (" startup script (s) : %s\n", my_boot_params.startupScript);
|
||||
printf (" other (o) : %s\n\n", my_boot_params.other);
|
||||
/*
|
||||
** Write to non-volatile RAM
|
||||
*/
|
||||
status = sysNvRamSet (BOOT_LINE_ADRS, strlen (BOOT_LINE_ADRS) + 1, 0);
|
||||
if (status != OK) {
|
||||
printf ("\n%s: Bad status from \"sysNvRamSet\": 0x%02x\n",
|
||||
Sbu_name, status);
|
||||
return False;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
/*
|
||||
**--------------------------------------------------------------------------*/
|
||||
void sbu_doReboot () {
|
||||
/* ============
|
||||
** Re-boot the vxWorks system by calling reboot.
|
||||
*/
|
||||
printf ("This processor is about to be re-booted ...\n");
|
||||
taskDelay (sysClkRateGet ()/4);
|
||||
reboot (BOOT_CLEAR);
|
||||
exit (EXIT_SUCCESS); /* Should not get here! */
|
||||
}
|
||||
/*
|
||||
**--------------------------------------------------------------------------*/
|
||||
void sbu_failInet (char *text) {
|
||||
/* =============
|
||||
** Output the given text and exit the process.
|
||||
*/
|
||||
int my_errno;
|
||||
|
||||
sbu_getErrno (&my_errno);
|
||||
printf ("\n### Internet Error ###\n");
|
||||
printf ( " ### errno = %d.\n", my_errno);
|
||||
perror (text);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void sbu_failInet_str (char *fmt, char *str) {
|
||||
/* ================
|
||||
** Call to failInet with an extra parameter.
|
||||
*/
|
||||
char my_buff[132];
|
||||
|
||||
sprintf (my_buff, fmt, str);
|
||||
sbu_failInet (my_buff);
|
||||
/* No return */
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void sbu_getErrno (int *his_errno) {
|
||||
/* =============
|
||||
*/
|
||||
*his_errno = errno; /* Make copy of errno */
|
||||
return;
|
||||
}
|
||||
/*
|
||||
**--------------------------------------------------------------------------*/
|
||||
void sbu_showHelp (char *errmsg) {
|
||||
/* =============
|
||||
*/
|
||||
if (errmsg != NULL) {
|
||||
printf ("\007\n%s\n", errmsg);
|
||||
taskDelay (5 * sysClkRateGet ()); /* Give user time to read message */
|
||||
}
|
||||
printf ("\n"
|
||||
"The \"other\" field may be specified as follows:\n"
|
||||
"\n"
|
||||
" <action>=<arg0>,..,<argn>/<action>=...\n"
|
||||
"\n"
|
||||
"There must be no white space characters in the string. The string may\n"
|
||||
"be specified in upper or lower case.\n"
|
||||
"\n"
|
||||
"<action> may be \"sp\" for \"spawn a task\" or\n"
|
||||
" \"cfg\" for \"configure SinqHM_srv\"\n"
|
||||
"\n"
|
||||
"The following \"sp\" commands are available:\n"
|
||||
"\n"
|
||||
" a) sp=SinqHM,<port>,<use-lev-gen>,<VMIO10-base>\n"
|
||||
" where\n"
|
||||
" <port> = TCP/IP port number for server. Dflt=2400.\n"
|
||||
" <use-lev-gen> = flag to indicate if timing levels should be\n"
|
||||
" generated via a VMIO10 module. If non-zero,\n"
|
||||
" timing levels are generated. Dflt=0.\n"
|
||||
" <VMIO10-base> = base address of VMIO10 level-generator\n"
|
||||
" module. Dflt=0x1900.\n"
|
||||
" This action spawns the SinqHM histogram memory server task.\n"
|
||||
"\n"
|
||||
" b) sp=lwl,<port>,<VMIO10-base>,<verbosity>\n"
|
||||
" where\n"
|
||||
" <port> = TCP/IP port number for server. Dflt=3501.\n"
|
||||
" <VMIO10-base> = base address of VMIO10 test-generator\n"
|
||||
" module. Dflt=0x1800.\n"
|
||||
" <verbosity> = verbosity flag. If non-zero, the program is\n"
|
||||
" verbose. Dflt=0.\n"
|
||||
" This action spawns the lwl_server task which can be used to feed\n"
|
||||
" data packets into the hist memory fibre-optic (Licht-Wellen-Leiter)\n"
|
||||
" link via a VMIO10 test-generator. If the test generator is absent,\n"
|
||||
" the action can be omitted to avoid a boot-time error message.\n"
|
||||
"\n"
|
||||
"The following \"cfg\" commands are available:\n"
|
||||
"\n"
|
||||
" a) cfg=HM_DIG,<#-bins>,<#-hists>,<bin-width>,<compress>,<lo-bin>\n"
|
||||
" where\n"
|
||||
" <#-bins> = number of bins per histogram. No default.\n"
|
||||
" <#-hists> = number of defined histograms. Dflt=1.\n"
|
||||
" <bin-width> = Number of bytes per bin. Dflt=4.\n"
|
||||
" <compress> = Bin compression factor. Dflt=1.\n"
|
||||
" <lo-bin> = First bin. Dflt=0.\n"
|
||||
"\n"
|
||||
" b) cfg=TOF,<#-bins>,<#-cntrs>,<bin-width>,<compress>,<lo-cntr>\n"
|
||||
" where\n"
|
||||
" <#-bins> = number of bins per histogram. No default.\n"
|
||||
" <#-cntrs> = number of neutron counters. No default.\n"
|
||||
" <bin-width> = Number of bytes per bin. Dflt=4.\n"
|
||||
" <compress> = Bin compression factor. Dflt=1.\n"
|
||||
" <lo-cntr> = # of first counter. Dflt=0.\n"
|
||||
"\n"
|
||||
" c) cfg=HM_PSD,... same arguments as HM_DIG (for now).\n"
|
||||
"\n"
|
||||
"For example:\n"
|
||||
" other=\"sp=SinqHM/cfg=HM_DIG,400\"\n"
|
||||
"\n");
|
||||
}
|
||||
/*
|
||||
**==============================================================================
|
||||
**
|
||||
** Main line program
|
||||
**
|
||||
**============================================================================*/
|
||||
|
||||
int SinqHM_bootUtil (int port, int arg2, int arg3, int arg4,
|
||||
/* ===============
|
||||
*/ int arg5, int arg6, int arg7, int arg8, int arg9,
|
||||
int suspend) {
|
||||
/*
|
||||
** Arguments:
|
||||
** port the TCP/IP port number to use. If 0, use default.
|
||||
** suspend sunspend ourself immediately if non-zero.
|
||||
*/
|
||||
char *local_mem, boot_line[1024], buff[128], cmnd[8];
|
||||
char *my_task_name;
|
||||
BOOT_PARAMS my_params;
|
||||
|
||||
int status, keep_going, cl_port, my_errno, bl_len;
|
||||
char *b_status, *p_host;
|
||||
|
||||
int my_skt; /* Connection socket */
|
||||
int rw_skt; /* Read/write socket */
|
||||
struct sockaddr_in lcl_sockname;
|
||||
struct sockaddr_in rmt_sockname;
|
||||
int rmt_sockname_len;
|
||||
/*============================================================================
|
||||
*/
|
||||
my_task_name = taskName (taskIdSelf());
|
||||
if (suspend != 0) {
|
||||
printf ("\n%s: Suspending ...\n", my_task_name);
|
||||
taskSuspend (0); /* We've been told to suspend ourself, ..
|
||||
** .. presumably for debug reasons.
|
||||
*/
|
||||
printf ("\n%s: ... suspension ended!\n", my_task_name);
|
||||
}
|
||||
/*============================================================================
|
||||
** Perform the initialisation of variables ...
|
||||
*/
|
||||
StrJoin (Sbu_name, sizeof (Sbu_name), taskName (taskIdSelf ()), "");
|
||||
printf ("\n%s: Started -- program ident = \"%s\".\n", Sbu_name, IDENT);
|
||||
|
||||
local_mem = (char *) BOOT_LINE_ADRS; /* Get pointer to the boot line */
|
||||
/*============================================================================
|
||||
*/
|
||||
b_status = bootStringToStruct (local_mem, &my_params); /* Parse boot line */
|
||||
if (*b_status != EOS) {
|
||||
printf ("\n%s: Bad status from \"bootStringToStruct\": 0x%02x\n",
|
||||
Sbu_name, *b_status);
|
||||
return False;
|
||||
}
|
||||
|
||||
Sbu_port = SBU_PORT_DFLT;
|
||||
if ((port >= 128) && (port < 32768)) Sbu_port = port;
|
||||
|
||||
/*============================================================================
|
||||
** Create a TCP/IP socket for receiving connection requests, bind it and
|
||||
** set it to listen.
|
||||
*/
|
||||
my_skt = socket (AF_INET, SOCK_STREAM, 0);
|
||||
if (my_skt == -1)
|
||||
sbu_failInet_str ("\n%s: socket error", Sbu_name);
|
||||
lcl_sockname.sin_family = AF_INET;
|
||||
lcl_sockname.sin_port = htons (Sbu_port);
|
||||
lcl_sockname.sin_addr.s_addr = 0;
|
||||
status = bind (my_skt, (struct sockaddr *) &lcl_sockname,
|
||||
sizeof (lcl_sockname));
|
||||
if (status != 0) sbu_failInet_str ("\n%s: bind error", Sbu_name);
|
||||
|
||||
status = listen (my_skt, 5);
|
||||
if (status != 0) sbu_failInet_str ("\n%s: listen error", Sbu_name);
|
||||
|
||||
/*
|
||||
** Clients must now connect to us.
|
||||
**
|
||||
** When a connection arrives, the boot line is sent to the client.
|
||||
*/
|
||||
printf ("\n%s: waiting for connections on Port %d\n", Sbu_name, Sbu_port);
|
||||
keep_going = True;
|
||||
while (keep_going) {
|
||||
rmt_sockname_len = sizeof (rmt_sockname);
|
||||
rw_skt = accept (my_skt, (struct sockaddr *) &rmt_sockname,
|
||||
&rmt_sockname_len);
|
||||
if (rw_skt == -1) {
|
||||
sbu_getErrno (&my_errno);
|
||||
sbu_failInet_str ("\n%s: accept error", Sbu_name);
|
||||
/* No return */
|
||||
}
|
||||
p_host = inet_ntoa (rmt_sockname.sin_addr);
|
||||
cl_port = ntohs (rmt_sockname.sin_port);
|
||||
|
||||
b_status = bootStringToStruct (local_mem, &my_params); /* Parse boot line */
|
||||
if (*b_status != EOS) {
|
||||
printf ("\n%s: Bad status from \"bootStringToStruct\": 0x%02x\n", Sbu_name,
|
||||
*b_status);
|
||||
return False;
|
||||
}
|
||||
StrJoin (boot_line, sizeof (boot_line), "bootDev:", my_params.bootDev);
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, "\nprocNum:");
|
||||
sprintf (buff, "%d", my_params.procNum);
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, buff);
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, "\nhostName:");
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, my_params.hostName);
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, "\nbootFile:");
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, my_params.bootFile);
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, "\nead:");
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, my_params.ead);
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, "\nbad:");
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, my_params.bad);
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, "\nhad:");
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, my_params.had);
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, "\ngad:");
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, my_params.gad);
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, "\nusr:");
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, my_params.usr);
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, "\npasswd:");
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, my_params.passwd);
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, "\nflags:");
|
||||
sprintf (buff, "0x%x", my_params.flags);
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, buff);
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, "\ntargetName:");
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, my_params.targetName);
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, "\nstartupScript:");
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, my_params.startupScript);
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, "\nother:");
|
||||
StrJoin (boot_line, sizeof (boot_line), boot_line, my_params.other);
|
||||
|
||||
bl_len = strlen (boot_line) + 1; /* Get len of line (including term'r) */
|
||||
bl_len = (bl_len + 3) & (~3); /* Round up to a multiple of 4 */
|
||||
sprintf (buff, "%04.4d", bl_len);
|
||||
status = send (rw_skt, buff, 4, 0);
|
||||
if (status != 4) {
|
||||
sbu_getErrno (&my_errno);
|
||||
sbu_failInet_str ("\n%s: send error on boot-line header", Sbu_name);
|
||||
/* No return */
|
||||
}
|
||||
status = send (rw_skt, boot_line, bl_len, 0);
|
||||
if (status != bl_len) {
|
||||
sbu_getErrno (&my_errno);
|
||||
sbu_failInet_str ("\n%s: send error on boot-line body", Sbu_name);
|
||||
/* No return */
|
||||
}
|
||||
/*
|
||||
** Now get a command from the client
|
||||
*/
|
||||
status = recv (rw_skt, cmnd, 8, 0);
|
||||
if (status != 8) {
|
||||
sbu_getErrno (&my_errno);
|
||||
sprintf (buff, "\n%s: send error on boot-line body", Sbu_name);
|
||||
perror (buff);
|
||||
}else if (strcmp (cmnd, "CLOSE") == 0) {
|
||||
send (rw_skt, "OK\0\0", 4, 0); /* Acknowledge the command */
|
||||
}else if (strcmp (cmnd, "CONFIG") == 0) {
|
||||
printf ("\n%s: CONFIG command received from Host %s, Port %d ...\n",
|
||||
Sbu_name, p_host, cl_port);
|
||||
status = sbu_doConfig (rw_skt);
|
||||
if (status) {
|
||||
send (rw_skt, "OK\0\0", 4, 0);
|
||||
}else {
|
||||
send (rw_skt, "Err", 4, 0);
|
||||
}
|
||||
}else if (strcmp (cmnd, "REBOOT") == 0) {
|
||||
printf ("\n%s: REBOOT command received from Host %s, Port %d ...\n",
|
||||
Sbu_name, p_host, cl_port);
|
||||
send (rw_skt, "OK\0\0", 4, 0); /* Acknowledge the command */
|
||||
status = close (rw_skt);
|
||||
status = close (my_skt);
|
||||
sbu_doReboot (); /* There is no return from this call! */
|
||||
}else if (strcmp (cmnd, "RUNDOWN") == 0) {
|
||||
printf ("\n%s: RUNDOWN command received from Host %s, Port %d ...\n",
|
||||
Sbu_name, p_host, cl_port);
|
||||
send (rw_skt, "OK\0\0", 4, 0); /* Acknowledge the command */
|
||||
keep_going = False;
|
||||
}else {
|
||||
printf ("\n%s: unrecognised command received from Host %s, Port %d:"
|
||||
"\"%s\"\n", Sbu_name, p_host, cl_port, cmnd);
|
||||
send (rw_skt, "Err", 4, 0);
|
||||
}
|
||||
status = close (rw_skt);
|
||||
}
|
||||
status = close (my_skt);
|
||||
|
||||
return True;
|
||||
}
|
||||
/*================================= End of SinqHM_bootUtil.c ========*/
|
Reference in New Issue
Block a user