Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Тестовые примеры / ch13 / main_shell / shell_cls
.C#include <iostream.h>
#include <fstream.h>
#include <strstream.h>
#include <stdio.h>
#include <netdir.h>
#include <rpc/rpc.h>
#include <string.h>
#include "mshell.h"
#include <thread.h>
#include "RPC.h"
#define MAXHOSTS 30
#define TMPFILE "/tmp/hosts"
static char *hostlist[MAXHOSTS];
static int numhosts;
extern rwlock_t rwlck;
int exec_host( const char* cmd, char* host )
{
static int res=0;
RPC_cls cl( host, SHELLPROG, SHELLVER, "netpath");
if (!cl.good()) return 1;
cl.set_auth( AUTH_SYS );
if (cl.call( EXECSHELL, (xdrproc_t)xdr_string, (caddr_t)&cmd,
(xdrproc_t)xdr_int, (caddr_t)&res) != RPC_SUCCESS)
return 2;
if (res!=0) {
cerr << "clnt: exec cmd fails\n";
return 4;
}
return 0;
}
/* check if a host has service defined */
int check_host( const char* hostnm )
{
if (rw_rdlock(&rwlck)) perror("rw_rdlock");
int i;
for (i=0; i < numhosts; i++)
if (!strcmp(hostlist[i],hostnm)) break;
if (rw_unlock(&rwlck)) perror("rw_unlock");
return (i < numhosts) ? 1 : 0;
}
/* execute a command on a host */
void* exec_shell( void* argp )
{
static int rc = 0;
char* cmd = (char*)argp;
/* the input string syntax is: <cmd>'/'<host> */
char* host = strrchr(cmd,'/');
*host++ = '\0';
if (!check_host(host)) {
cout << "Invalid host: '" << host << "'\n" << flush;
rc = 1;
thr_exit(&rc);
}
rc = exec_host( cmd, host );
thr_exit(&rc);
return 0;
}
/* display all available hosts to an output stream */
void* display_hosts( void* argp )
{
int rc = 0;
if (rw_tryrdlock(&rwlck)) {
cout << "Host table in processed. please waite...\n";
if (rw_rdlock(&rwlck)) perror("rw_rdlock");
}
if (!numhosts) {
cout << "Host table is empty!\n" << flush;
cout << "please select 'Collect hosts info' option\n" << flush;
rc = -1;
}
else {
char buf[256];
ostrstream(buf,256) << TMPFILE << "." << thr_self();
ofstream ofs (buf);
if (!ofs)
cerr << "Create temp file '" << buf << "' failed\n";
else {
int i;
for ( i=0; i < numhosts; i++)
ofs << i << ": " << hostlist[i] << endl;
ofs.close();
char cmd[256];
ostrstream(cmd,256) << "xterm -title Hosts -e view " << buf;
if (system(cmd)) perror("system");
if (unlink(buf)) perror("unlink");
}
}
if (rw_unlock(&rwlck)) perror("rw_unlock");
thr_exit(&rc);
return 0;
}
/* record a remote host */
int add_host( const char* hostnm )
{
int new_entry = 1;
if (rw_wrlock(&rwlck)) perror("rw_wrlock");
int i;
for ( i=0; i < numhosts; i++)
if (!strcmp(hostlist[i],hostnm)) break;
if (i >= numhosts) {
if (numhosts >= MAXHOSTS)
cerr << "Too many remote hosts detected\n";
else {
hostlist[numhosts] = new char[strlen(hostnm)+1];
strcpy(hostlist[numhosts++],hostnm);
}
}
else new_entry = 0;
if (rw_unlock(&rwlck)) perror("rw_unlock");
return new_entry;
}
/* client's braodcast call back function */
bool_t callme (caddr_t res_p, struct netbuf* addr, struct netconfig *nconf)
{
int i;
struct nd_hostservlist *servp;
if (netdir_getbyaddr(nconf,&servp,addr))
perror("netdir_getbyaddr");
else for ( i=0; i < servp->h_cnt; i++)
if (!add_host( servp->h_hostservs[i].h_host ))
return TRUE; /* end broadcast if found a host twice */
return FALSE; /* get more responses */
}
/* collect remote hosts that have server running on it */
void* collect_hosts( void* argp )
{
/* client sends a broadcast request and waits for responses */
int rc = RPC_cls::broadcast( SHELLPROG, SHELLVER, 0, (resultproc_t)callme,
(xdrproc_t)xdr_void, (caddr_t)NULL,
(xdrproc_t)xdr_void, (caddr_t)NULL);
switch (rc) {
case RPC_SUCCESS:
break;
case RPC_TIMEDOUT:
if (numhosts) break;
default:
cerr << "RPC broadcast failed\n";
rc = 1;
}
thr_exit(&rc);
return 0;
}
Соседние файлы в папке main_shell