636 lines
21 KiB
HTML
636 lines
21 KiB
HTML
|
<!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 <stdio.h> /* perror() */
|
||
|
#include <sys/socket.h> /* socket(), bind(), and so on */
|
||
|
#include <netinet/in.h> /* sockaddr_in, INADDR_ANY, and so on */
|
||
|
#include <unistd.h> /* close(), read(), write() and so on */
|
||
|
#include <stdlib.h> /* exit() */
|
||
|
#include <stdlib.h> /* exit(), memset() */
|
||
|
#include <sys/ioctl.h> /* ioctl() */
|
||
|
#include <errno.h> /* errno and values */
|
||
|
#include <string.h> /* strlen() */
|
||
|
#include <arpa/inet.h> /* inet_addr() */
|
||
|
#include <netdb.h> /* gethostbyname() */
|
||
|
#include <pwd.h> /* getpwuid() */
|
||
|
#include <signal.h> /* sigaction(), and so on */
|
||
|
|
||
|
#ifdef _AIX
|
||
|
#include <sys/select.h> /* select() */
|
||
|
#include <strings.h> /* bzero() for FD_ZERO */
|
||
|
#endif
|
||
|
#ifdef __linux__
|
||
|
#include <sys/time.h> /* FD_SET(), select */
|
||
|
#endif
|
||
|
|
||
|
#ifdef USE_ICONV
|
||
|
#include <iconv.h> /* 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")) < 0) {
|
||
|
perror("qshc: iconv_open() failed for ASCII to EBCDIC");
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
if ((ecd = iconv_open("IBM-037", "IBM-850")) < 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 <ctrl>c. */
|
||
|
sigemptyset(&sigact.sa_mask);
|
||
|
sigact.sa_flags = 0;
|
||
|
sigact.sa_handler = MySignalHandler;
|
||
|
if (sigaction(SIGINT, &sigact, NULL) != 0) {
|
||
|
perror("qshc: sigaction(SIGINT) failed");
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
/********************************************************************/
|
||
|
/* Process the input parameters. */
|
||
|
/********************************************************************/
|
||
|
|
||
|
if (argc < 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(&ip_addr, host_p->h_addr, host_p->h_length);
|
||
|
sysname = host_p->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 *)&host_addr.s_addr, sizeof(host_addr),
|
||
|
AF_INET);
|
||
|
if (host_p) {
|
||
|
sysname = host_p->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)) < 0) {
|
||
|
perror("qshc: socket() failed");
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
/* Connect to the qsh server on the specified system. */
|
||
|
memset(&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 *)&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) < 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) < 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)) < 0) {
|
||
|
perror("qshc: write() failed sending username\n");
|
||
|
close(sd);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
if ((rc = write(sd, (void *)ebcdic_pwd, strlen(ebcdic_pwd)+1)) < 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(&read_set);
|
||
|
FD_SET(0, &read_set);
|
||
|
FD_SET(sd, &read_set);
|
||
|
|
||
|
rc = select(sd+1, &read_set, NULL, NULL, NULL);
|
||
|
|
||
|
if ((rc < 0) && (errno != EINTR)) {
|
||
|
perror("qshc: select() failed");
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
if (rc == 0) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
/* Process data entered by the terminal user. */
|
||
|
if (FD_ISSET(0, &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) < 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) < 0) {
|
||
|
perror("qshc: write() failed sending input");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Process data from the remote shell. */
|
||
|
if (FD_ISSET(sd, &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 < 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) >= 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**)&ibuf, &ileft, &obuf, &oleft);
|
||
|
#else
|
||
|
rc = Translate((uchar *)ibuf, ileft, (uchar *)obuf, EbcdicTable);
|
||
|
#endif
|
||
|
if (rc < 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**)&ibuf, &ileft, &obuf, &oleft);
|
||
|
#else
|
||
|
rc = Translate((uchar *)ibuf, ileft, (uchar *)obuf, AsciiTable);
|
||
|
#endif
|
||
|
if (rc < 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->pw_dir), "/.netrc");
|
||
|
|
||
|
if ((netrc = fopen(buffer, "r")) == NULL) {
|
||
|
perror("qshc: open() failed for ~/.netrc file");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
while (!(logflag || pwdflag) && fgets(buffer, BUFSIZE, netrc) != NULL) {
|
||
|
/* Find system name in ~/.netrc. */
|
||
|
if ((systag = (char*)strtok(buffer, " \t\n")) != NULL &&
|
||
|
!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 && 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 < 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: <ctrl>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>
|
||
|
|