ibm-information-center/dist/eclipse/plugins/i5OS.ic.rzahz_5.4.0.1/clntpgm.htm

636 lines
21 KiB
HTML
Raw Permalink Normal View History

2024-04-02 14:02:31 +00:00
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<meta name="generator" content="HTML Tidy, see www.w3.org">
<meta http-equiv="Content-Type" content=
"text/html; charset=utf-8">
<title>Example: Client program</title>
<LINK rel="stylesheet" type="text/css" href="../rzahg/ic.css">
</HEAD>
<body bgcolor="#FFFFFF">
<!-- Java sync-link -->
<SCRIPT LANGUAGE="Javascript" SRC="../rzahg/synch.js" TYPE="text/javascript"></SCRIPT>
<h2>Example: Client program</h2>
<pre>
/**********************************************************************/
/* */
/* Name: qshc.c */
/* */
/* Description: This program is a client for an interactive qsh */
/* session running on a server. The program */
/* first connects to a server on the specified */
/* server and sends the user name and password of */
/* the client. After the qsh session is started, */
/* the program takes input from stdin and sends it */
/* to the server and receives output from the server */
/* and displays it on stdout. */
/* */
/* Parameters: 1. Host running the qsh server (either host name or */
/* IP address). */
/* */
/* Options: 1. -n to force prompt for user name and password. */
/* 2. -p to specify port of qsh server. */
/* */
/* Notes: 1. The user name and password are sent as plain text */
/* to the server. */
/* 2. All translations from ASCII to EBCDIC are done by */
/* this program on the client. */
/* 3. The program includes translation tables for */
/* converting between EBCDIC code page 37 (US English)*/
/* and ASCII code page 850 (US English). You can */
/* modify these tables to support other code pages. */
/* Or if your system supports the iconv APIs, you */
/* can define USE_ICONV to translate using iconv(). */
/* 4. This program has been tested on AIX<SUP>(R)</SUP> 4.1.5 and */
/* Linux<SUP>(TM)</SUP> 2.0.29. */
/* */
/**********************************************************************/
/* Remove the comments from the following line to use iconv(). */
/* #define USE_ICONV 1 */
/**********************************************************************/
/* Includes */
/**********************************************************************/
#include &lt;stdio.h&gt; /* perror() */
#include &lt;sys/socket.h&gt; /* socket(), bind(), and so on */
#include &lt;netinet/in.h&gt; /* sockaddr_in, INADDR_ANY, and so on */
#include &lt;unistd.h&gt; /* close(), read(), write() and so on */
#include &lt;stdlib.h&gt; /* exit() */
#include &lt;stdlib.h&gt; /* exit(), memset() */
#include &lt;sys/ioctl.h&gt; /* ioctl() */
#include &lt;errno.h&gt; /* errno and values */
#include &lt;string.h&gt; /* strlen() */
#include &lt;arpa/inet.h&gt; /* inet_addr() */
#include &lt;netdb.h&gt; /* gethostbyname() */
#include &lt;pwd.h&gt; /* getpwuid() */
#include &lt;signal.h&gt; /* sigaction(), and so on */
#ifdef _AIX
#include &lt;sys/select.h&gt; /* select() */
#include &lt;strings.h&gt; /* bzero() for FD_ZERO */
#endif
#ifdef __linux__
#include &lt;sys/time.h&gt; /* FD_SET(), select */
#endif
#ifdef USE_ICONV
#include &lt;iconv.h&gt; /* iconv(), and so on */
#endif
/**********************************************************************/
/* Constants */
/**********************************************************************/
#define QSH_PORT 6042
#define DEFAULT_BUF 4096
/**********************************************************************/
/* Types */
/**********************************************************************/
typedef unsigned char uchar;
/**********************************************************************/
/* Global Variables */
/**********************************************************************/
char *sysname; /* Long host name of server system */
#ifdef USE_ICONV
iconv_t ecd; /* Conversion descriptor for ASCII to EBCDIC */
iconv_t acd; /* Conversion descriptor for EBCDIC to ASCII */
#else
/* EBCDIC to ASCII translation table */
static uchar AsciiTable[256] =
{
0x00,0x01,0x02,0x03,0x20,0x09,0x20,0x7f, /* 00-07 */
0x20,0x20,0x20,0x0b,0x0c,0x0d,0x0e,0x0f, /* 08-0f */
0x10,0x11,0x12,0x13,0x20,0x0a,0x08,0x20, /* 10-17 */
0x18,0x19,0x20,0x20,0x20,0x1d,0x1e,0x1f, /* 18-1f */
0x20,0x20,0x1c,0x20,0x20,0x0a,0x17,0x1b, /* 20-27 */
0x20,0x20,0x20,0x20,0x20,0x05,0x06,0x07, /* 28-2f */
0x20,0x20,0x16,0x20,0x20,0x20,0x20,0x04, /* 30-37 */
0x20,0x20,0x20,0x20,0x14,0x15,0x20,0x1a, /* 38-3f */
0x20,0x20,0x83,0x84,0x85,0xa0,0xc6,0x86, /* 40-47 */
0x87,0xa4,0xbd,0x2e,0x3c,0x28,0x2b,0x7c, /* 48-4f */
0x26,0x82,0x88,0x89,0x8a,0xa1,0x8c,0x8b, /* 50-57 */
0x8d,0xe1,0x21,0x24,0x2a,0x29,0x3b,0xaa, /* 58-5f */
0x2d,0x2f,0xb6,0x8e,0xb7,0xb5,0xc7,0x8f, /* 60-67 */
0x80,0xa5,0xdd,0x2c,0x25,0x5f,0x3e,0x3f, /* 68-6f */
0x9b,0x90,0xd2,0xd3,0xd4,0xd6,0xd7,0xd8, /* 70-77 */
0xde,0x60,0x3a,0x23,0x40,0x27,0x3d,0x22, /* 78-7f */
0x9d,0x61,0x62,0x63,0x64,0x65,0x66,0x67, /* 80-87 */
0x68,0x69,0xae,0xaf,0xd0,0xec,0xe7,0xf1, /* 88-8f */
0xf8,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70, /* 90-97 */
0x71,0x72,0xa6,0xa7,0x91,0xf7,0x92,0xcf, /* 98-9f */
0xe6,0x7e,0x73,0x74,0x75,0x76,0x77,0x78, /* a8-a7 */
0x79,0x7a,0xad,0xa8,0xd1,0xed,0xe8,0xa9, /* a8-af */
0x5e,0x9c,0xbe,0xfa,0xb8,0x15,0x14,0xac, /* b0-b7 */
0xab,0xf3,0x5b,0x5d,0xee,0xf9,0xef,0x9e, /* b8-bf */
0x7b,0x41,0x42,0x43,0x44,0x45,0x46,0x47, /* c0-c7 */
0x48,0x49,0xf0,0x93,0x94,0x95,0xa2,0xe4, /* c8-cf */
0x7d,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50, /* d0-d7 */
0x51,0x52,0xfb,0x96,0x81,0x97,0xa3,0x98, /* d8-df */
0x5c,0xf6,0x53,0x54,0x55,0x56,0x57,0x58, /* e0-e7 */
0x59,0x5a,0xfc,0xe2,0x99,0xe3,0xe0,0xe5, /* e8-ef */
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, /* f0-f7 */
0x38,0x39,0xfd,0xea,0x9a,0xeb,0xe9,0xff /* f8-ff */
};
/* ASCII to EBCDIC translation table */
static uchar EbcdicTable[256] =
{
0x00,0x01,0x02,0x03,0x37,0x2d,0x2e,0x2f, /* 00-07 */
0x16,0x05,0x25,0x0b,0x0c,0x0d,0x0e,0x0f, /* 08-0f */
0x10,0x11,0x12,0x13,0x3c,0x3d,0x32,0x26, /* 10-17 */
0x18,0x19,0x3f,0x27,0x22,0x1d,0x1e,0x1f, /* 18-1f */
0x40,0x5a,0x7f,0x7b,0x5b,0x6c,0x50,0x7d, /* 20-27 */
0x4d,0x5d,0x5c,0x4e,0x6b,0x60,0x4b,0x61, /* 28-2f */
0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7, /* 30-37 */
0xf8,0xf9,0x7a,0x5e,0x4c,0x7e,0x6e,0x6f, /* 38-3f */
0x7c,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7, /* 40-47 */
0xc8,0xc9,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6, /* 48-4f */
0xd7,0xd8,0xd9,0xe2,0xe3,0xe4,0xe5,0xe6, /* 50-57 */
0xe7,0xe8,0xe9,0xba,0xe0,0xbb,0xb0,0x6d, /* 58-5f */
0x79,0x81,0x82,0x83,0x84,0x85,0x86,0x87, /* 60-67 */
0x88,0x89,0x91,0x92,0x93,0x94,0x95,0x96, /* 68-6f */
0x97,0x98,0x99,0xa2,0xa3,0xa4,0xa5,0xa6, /* 70-77 */
0xa7,0xa8,0xa9,0xc0,0x4f,0xd0,0xa1,0x07, /* 78-7f */
0x68,0xdc,0x51,0x42,0x43,0x44,0x47,0x48, /* 80-87 */
0x52,0x53,0x54,0x57,0x56,0x58,0x63,0x67, /* 88-8f */
0x71,0x9c,0x9e,0xcb,0xcc,0xcd,0xdb,0xdd, /* 90-97 */
0xdf,0xec,0xfc,0x70,0xb1,0x80,0xbf,0x40, /* 98-9f */
0x45,0x55,0xee,0xde,0x49,0x69,0x9a,0x9b, /* a8-a7 */
0xab,0xaf,0x5f,0xb8,0xb7,0xaa,0x8a,0x8b, /* a8-af */
0x40,0x40,0x40,0x40,0x40,0x65,0x62,0x64, /* b0-b7 */
0xb4,0x40,0x40,0x40,0x40,0x4a,0xb2,0x40, /* b8-bf */
0x40,0x40,0x40,0x40,0x40,0x40,0x46,0x66, /* c0-c7 */
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x9f, /* c8-cf */
0x8c,0xac,0x72,0x73,0x74,0x89,0x75,0x76, /* d0-d7 */
0x77,0x40,0x40,0x40,0x40,0x6a,0x78,0x40, /* d8-df */
0xee,0x59,0xeb,0xed,0xcf,0xef,0xa0,0x8e, /* e0-e7 */
0xae,0xfe,0xfb,0xfd,0x8d,0xad,0xbc,0xbe, /* e8-ef */
0xca,0x8f,0x40,0xb9,0xb6,0xb5,0xe1,0x9d, /* f0-f7 */
0x90,0xbd,0xb3,0xda,0xea,0xfa,0x40,0x40 /* f8-ff */
};
#endif /* USE_ICONV */
/**********************************************************************/
/* Function Prototypes */
/**********************************************************************/
int ConvertToEBCDIC(char *, size_t, char *, size_t);
int ConvertToASCII(char *, size_t, char *, size_t);
int GetPassword(char *, char *, char *);
int Translate(uchar *, size_t, uchar *, uchar *);
void MySignalHandler(int);
void usage(void);
int main (int argc, char *argv[])
{
struct sigaction sigact; /* Signal action */
int c; /* Option letter */
int nflag=0; /* True when -n option is specified */
int port=QSH_PORT; /* Port to connect to on server */
int sd; /* Socket to server */
fd_set read_set; /* For select() */
int rc; /* Return code */
struct sockaddr_in svr_addr; /* AF_INET socket address */
long ip_addr; /* IP address of server system */
struct in_addr host_addr; /* Host address for gethostbyaddr() */
char *hostname; /* Short host name of server system */
size_t len; /* Length of input string */
char *ascii_user; /* Username in ASCII */
char *ebcdic_user; /* Username in EBCDIC */
char *ascii_pwd; /* Password in ASCII */
char *ebcdic_pwd; /* Password in EBCDIC */
struct hostent *host_p; /* Pointer to hostent structure returned by
gethostbyname() */
char *ascii_buf; /* Buffer for ASCII text */
char *ebcdic_buf; /* Buffer for EBCDIC text */
int buf_size; /* Amount of data read from server */
/********************************************************************/
/* Initialization. */
/********************************************************************/
#ifdef USE_ICONV
/* Open the conversion descriptors for converting between ASCII and
EBCDIC. Assume the server job is running in CCSID 37.
This must be changed if the server job is running in a
different CCSID. The input parameters to iconv_open() may need to
be changed depending on the operating system. This ioonv_open() is
coded for AIX. */
if ((acd = iconv_open("IBM-850", "IBM-037")) &lt; 0) {
perror("qshc: iconv_open() failed for ASCII to EBCDIC");
exit(1);
}
if ((ecd = iconv_open("IBM-037", "IBM-850")) &lt; 0) {
perror("qshc: iconv_open() failed for EBCDIC to ASCII");
exit(1);
}
#endif /* USE_IOONV */
/* Set up a signal handler for SIGINT. The signal is sent to the
process when the user presses &lt;ctrl&gt;c. */
sigemptyset(&amp;sigact.sa_mask);
sigact.sa_flags = 0;
sigact.sa_handler = MySignalHandler;
if (sigaction(SIGINT, &amp;sigact, NULL) != 0) {
perror("qshc: sigaction(SIGINT) failed");
exit(1);
}
/********************************************************************/
/* Process the input parameters. */
/********************************************************************/
if (argc &lt; 2) {
usage();
}
/* Process the options. */
while ((c = getopt(argc, argv, "hnp:")) != EOF) {
switch (c) {
case 'n':
nflag = 1;
break;
case 'p':
port = atoi(optarg);
break;
case 'h':
default:
usage();
break;
} /* End of switch */
} /* End of while */
/* Convert a dotted decimal address to a 32-bit IP address. */
hostname = argv[optind];
ip_addr = inet_addr(hostname);
/* When inet_addr() returns -1 assume the user specified
a host name. */
if (ip_addr == -1) {
/* Try to find the host by name. */
host_p = gethostbyname(hostname);
if (host_p) {
memcpy(&amp;ip_addr, host_p-&gt;h_addr, host_p-&gt;h_length);
sysname = host_p-&gt;h_name;
}
else {
fprintf(stderr, "qshc: Could not find host %s\n", hostname);
exit(1);
}
} /* End of if */
/* The user specified a IP address. */
else {
/* Try to find the host by address. */
host_addr.s_addr = ip_addr;
host_p = gethostbyaddr((char *)&amp;host_addr.s_addr, sizeof(host_addr),
AF_INET);
if (host_p) {
sysname = host_p-&gt;h_name;
}
else {
fprintf(stderr, "qshc: Could not find host %s\n", hostname);
exit(1);
}
} /* End of else */
/********************************************************************/
/* Connect to the qsh server on the specified system. */
/********************************************************************/
/* Create a socket. */
if ((sd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) &lt; 0) {
perror("qshc: socket() failed");
exit(1);
}
/* Connect to the qsh server on the specified system. */
memset(&amp;svr_addr, '\0', sizeof(svr_addr));
svr_addr.sin_family = AF_INET;
svr_addr.sin_port = htons(port);
svr_addr.sin_addr.s_addr = ip_addr;
if (connect(sd, (struct sockaddr *)&amp;svr_addr, sizeof(svr_addr)) != 0) {
perror("qshc: connect() failed");
exit(1);
}
/********************************************************************/
/* Send the user name and password to the server. */
/********************************************************************/
/* Allocate buffers for translating input and output. */
ascii_buf = (char *)malloc(DEFAULT_BUF);
memset(ascii_buf, '\0', DEFAULT_BUF);
ebcdic_buf = (char *)malloc(DEFAULT_BUF);
memset(ebcdic_buf, '\0', DEFAULT_BUF);
ascii_user = ascii_buf;
ascii_pwd = ascii_buf + 100;
ebcdic_user = ebcdic_buf;
ebcdic_pwd = ebcdic_buf + 100;
/* Prompt the user for the user name and password. */
if (nflag) {
printf("Enter user name: ");
gets(ascii_user);
ascii_pwd = getpass("Enter password: ");
}
/* Get the user name and password from the ~/.netrc file. */
else {
if (GetPassword(hostname, ascii_user, ascii_pwd) != 0) {
fprintf(stderr, "qshc: Could not find user or password in ~/.netrc\n");
exit(1);
}
}
/* Convert the user name and password to EBCDIC. */
if (ConvertToEBCDIC(ascii_user, strlen(ascii_user)+1, ebcdic_user, 11) &lt; 0) {
fprintf(stderr, "qshc: Could not convert user %s to EBCDIC\n", ascii_user);
exit(1);
}
if (ConvertToEBCDIC(ascii_pwd, strlen(ascii_pwd)+1, ebcdic_pwd, 11) &lt; 0) {
fprintf(stderr, "qshc: Could not convert password %s to EBCDIC\n",
ascii_pwd);
exit(1);
}
/* Send the user name and password to the qsh server. Note that the
user name and password are sent as plain text. */
if ((rc = write(sd, (void *)ebcdic_user, strlen(ebcdic_user)+1)) &lt; 0) {
perror("qshc: write() failed sending username\n");
close(sd);
exit(1);
}
if ((rc = write(sd, (void *)ebcdic_pwd, strlen(ebcdic_pwd)+1)) &lt; 0) {
perror("qshc: write() failed sending password\n");
close(sd);
exit(1);
}
printf("Started qsh session on %s\n\n", sysname);
/********************************************************************/
/* Process input and output between the user and the remote shell. */
/********************************************************************/
/* Loop forever. */
while (1) {
/* Select on stdin and the socket connected to the remote shell. */
FD_ZERO(&amp;read_set);
FD_SET(0, &amp;read_set);
FD_SET(sd, &amp;read_set);
rc = select(sd+1, &amp;read_set, NULL, NULL, NULL);
if ((rc &lt; 0) &amp;&amp; (errno != EINTR)) {
perror("qshc: select() failed");
exit(1);
}
if (rc == 0) {
continue;
}
/* Process data entered by the terminal user. */
if (FD_ISSET(0, &amp;read_set)) {
/* Read the data from the terminal. */
gets(ascii_buf);
/* Convert the string to EBCDIC. */
len = strlen(ascii_buf);
if (ConvertToEBCDIC(ascii_buf, len, ebcdic_buf, DEFAULT_BUF) &lt; 0) {
fprintf(stderr, "qshc: Could not convert input string to EBCDIC\n");
continue;
}
/* Put a newline on the end of the string. */
*(ebcdic_buf+len) = 0x25;
/* Send the data to the remote shell. */
if (write(sd, ebcdic_buf, len+1) &lt; 0) {
perror("qshc: write() failed sending input");
}
}
/* Process data from the remote shell. */
if (FD_ISSET(sd, &amp;read_set)) {
/* Read the data from the remote shell. */
buf_size = read(sd, ebcdic_buf, DEFAULT_BUF-1);
/* There was a failure reading from the remote shell. */
if (buf_size &lt; 0) {
perror("\nqshc: error reading data from remote shell");
printf("Ended qsh session on %s\n", sysname);
exit(0);
}
/* The remote shell process ended. */
else if (buf_size == 0) {
printf("\nEnded qsh session on %s\n", sysname);
exit(0);
}
/* Process the data from the remote shell. */
else {
/* Convert to ASCII. */
*(ebcdic_buf+buf_size) = '\0';
if (ConvertToASCII(ebcdic_buf, buf_size+1, ascii_buf,
DEFAULT_BUF) &gt;= 0) {
write(1, ascii_buf, buf_size);
}
}
}
} /* End of while */
exit(0);
} /* End of main() */
/*
* Convert a string from ASCII to EBCDIC.
*/
int
ConvertToEBCDIC(char *ibuf, size_t ileft, char *obuf, size_t oleft)
{
int rc;
#ifdef USE_ICONV
rc = iconv(ecd, (const char**)&amp;ibuf, &amp;ileft, &amp;obuf, &amp;oleft);
#else
rc = Translate((uchar *)ibuf, ileft, (uchar *)obuf, EbcdicTable);
#endif
if (rc &lt; 0)
perror("qshc: error converting to EBCDIC");
return rc;
} /* End of ConvertToEBCDIC() */
/*
* Convert a string from EBCDIC to ASCII.
*/
int
ConvertToASCII(char *ibuf, size_t ileft, char *obuf, size_t oleft)
{
int rc;
#ifdef USE_ICONV
rc = iconv(acd, (const char**)&amp;ibuf, &amp;ileft, &amp;obuf, &amp;oleft);
#else
rc = Translate((uchar *)ibuf, ileft, (uchar *)obuf, AsciiTable);
#endif
if (rc &lt; 0)
perror("qshc: error converting to ASCII");
return rc;
} /* End of ConvertToASCII() */
/*
* Get the user name and password for the specified system from the
* ~/.netrc file.
*/
int
GetPassword(char *sysname, char *logname, char *password)
{
#define BUFSIZE 256
char buffer[BUFSIZE];
char *systag, *logtag;
int logflag = 0, pwdflag = 0;
FILE *netrc;
struct passwd *pwdbuf;
int rc=0;
/* Get user's home directory. */
pwdbuf = getpwuid(getuid());
/* Does user have a .netrc file in their home directory? */
strcat(strcpy(buffer, pwdbuf-&gt;pw_dir), "/.netrc");
if ((netrc = fopen(buffer, "r")) == NULL) {
perror("qshc: open() failed for ~/.netrc file");
return -1;
}
while (!(logflag || pwdflag) &amp;&amp; fgets(buffer, BUFSIZE, netrc) != NULL) {
/* Find system name in ~/.netrc. */
if ((systag = (char*)strtok(buffer, " \t\n")) != NULL &amp;&amp;
!strncmp(systag, "machine", 7)) {
systag = (char *)strtok(NULL, " \t\n");
if (!strcmp(systag, sysname)) {
/* Find login and password. */
while (!logflag || !pwdflag) {
if ((logtag = (char *)strtok(NULL, " \t\n")) == NULL) {
/* Nothing else on that line... get another. */
while (!logtag) {
fgets(buffer, BUFSIZE, netrc);
logtag = (char *)strtok(buffer, " \t\n");
}
}
if (!strncmp(logtag, "login", 5)) {
strcpy(logname, strtok(NULL, " \n\t"));
++logflag;
}
else if (!strncmp(logtag, "password", 8)) {
strcpy(password, strtok(NULL, " \n\t"));
++pwdflag;
}
else
;
} /* while flags not set */
} /* if found login and passwd in .netrc */
} /* if machine in .netrc */
} /* while fgets */
fclose(netrc);
/* Login and password not found for system. */
if (!(logflag &amp;&amp; pwdflag)) {
rc = -1;
}
return rc;
} /* End of GetPassword() */
#ifndef USE_ICONV
/*
* Translate bytes using the specified translation table.
*/
int
Translate(uchar *ip, size_t ilen, uchar *op, uchar *table)
{
int index;
for (index = 0; index &lt; ilen; ++index) {
*op = table[*ip];
ip++;
op++;
}
return 0;
} /* End of Translate() */
#endif
/*
* Signal handler.
*/
void
MySignalHandler(int signo)
{
switch (signo) {
case SIGINT:
printf("\nqshc: &lt;ctrl&gt;c ends this program\n");
printf("Ended qsh session on %s\n", sysname);
exit(0);
break;
default:
exit(1);
break;
} /* End of switch */
return;
} /* End of MySignalHandler() */
/*
* Display usage message.
*/
void usage(void)
{
fprintf(stderr, "Usage: qshc [-n] [-p port] hostname\n");
exit(1);
} /* End of usage() */
</pre>
<p><strong>Note:</strong> By using the code examples, you agree to the terms of the <a href="codedisclaimer.htm">Code license and disclaimer information</a>.</p>
</body>
</html>