Files
sicspsi/sinqhm/SinqHM_bootUtil.c
cvs 064ec37e9a - Rearranged directory structure for forking out ANSTO
- 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
2003-06-20 10:18:47 +00:00

632 lines
23 KiB
C
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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"
#ifdef MV2600
#include "../config/mv2604/config.h"
#else
#if (CPU == PPC603)
#include "../config/mv1603/config.h"
#elif (CPU == PPC604)
#include "../config/mv1604/config.h"
#endif
#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 ========*/