|
Программирование >> Структура ядра и системные вызовы
♦else svcp = svc tli create( fd, nconf, 0, 0, 0) ; if (Isvcp) cerr create server handle fails\n ; rc = 0; return; if (progno == UNDEF PROGNUM) /* generate a transient one */ ( progno = gen progNum( versno, nconf, &svcp->xp ltaddr); if (svc reg(svcp, progno, versno, dispatch, nconf)==FALSE) cerr register prognum failed\n ; rc = 0; freenetconfigent( nconf ); /* fd должен содержать дескриптор гнезда, который может принимать значение RPG ANySOGK */ if (progno == UNDEF PROGNUM) /* сгенерировать временный номер */ progno = gen pr6gNum ( versno, &fd, transport ); int proto = 0; if (!strcmp(transport, tcp )) else ( svcp = svctcp create{ fd, TGP BUFSIZ, TCP BUFSIZ ); if (fd) proto = IPPROTO TGP; svcp = svcudp create ( fd ); if (fd) proto = IPPROTO UDP; if (Isvcp) cerr create server handle fails\n ; rc = 0; return; if (fd)i pmap unset( progno, versno ); if (!svc register(svcp, progno, versno, dispatch, proto)) { cerr could not register RPG program/ver: progno / versno endl; rc = 0; lendif prgnum = progno, vernum > versno; rc = 1; /* Возвратить номер программы */ u long prognoО { return prgnum; ); /* Функция-деструктор */ ~RPG svc() pmap unsGt( prgnum, vernum ); svc unregister( prgnum, vernum ); if (svcp) svc destroy(svcp); /* Проверка правильности создания объекта сервера */ int good О { return rc; }; /* Сервер ожидает RPG-запросы от клиентов */ static void run О ( svc run{); }; /* Опрос на предмет наличия RPC-запросов. Это делается для асинхронного обратного вызова RPG */ static int ро11( time t timeout ) ( int read fds = svc fds; struct timeval stry; stry.tv sec = timeout; stry.tv usec = 0; ♦ifndef HPUX switch (select(32, (fd set*)Sread fds, 0, 0, fistry)) ♦else ♦endif switch (select{32, &read fds, 0, 0, Sstry)) case -1: /*if (errno != EINTR) perror( poll );*/ return -1; case 0: return 0; /* нет событий */ default: svc getreq( read fds }; return 1; /* Регистрация RPG-функции и начало обслуживания RPC-запроса */ int run func( int procnum, rpcprog func ) if (goodO) i { if (func) add proc( procnum, func ); run(); /* функция ничего не возвращает */ return -1; /* Регистрация новой RPC-функции */ void add proc( unsigned procnum, rpcprog func ) for (int i=0; i < numProg; i++} if (progList[i].func==func} return; if (++numProg == 1) progList = (RPCPROG INFO*)malloc(sizeof(RPCPROG INFO)); else progList = (RPCPR0G INFO*)realloc((void*)progList, sizeof(RPCPROG INFO)*numprog); progList [numProg-1] . func = func; ,;, progList[numProg-1].prgnum = prgnum; progList[numProg-1].vernum = vernum; progList[numProg-1].prcnum = procnum; /* Вызывается RPC-функцией для получения значений аргументов от клиента */ int getargs( SVCXPRT* transp, xdrproc t func, caddr t argp } { if (!svc getargs( transp, func, argp}} { svcerr decode(transp); return -1; } else return RPC SUCCESS; /* Вызывается RPC-функцией для отправки ответа клиенту */ int reply( SVCXPRT* transp, xdrproc t func, caddr t argp ) ( if (!svc sendreply(transp, func, argp}} ( cerr Cant send replyXn ; #ifdef HPUX perror( svc sendreply ) ; lelse svcerr systemerr(transp); #endif return -1; } else return RPC SUCCESS; #ifdef SYSV4 /* Генерировать временный номер RPC-программы для асинхронного обратного вызова */ static unsigned long gen progNum( unsigned long versnum, struct netconfig* nconf, struct netbuf* addr) static unsigned long transient prognum = OxSFFFFFFF; while (!rpcb set( transient prognum++, versnum, nconf, addr)} continue; return transient prognum -1; #endif static unsigned long gen progNum ( unsigned long versnum, int* soG)cp, char* nettype ) static unsigned long transient prognum = OxSFFFFFFF; int s, len, proto = IPPROTO UDP, soc)ctype = SOCK DGRAM; , * struct soc)caddr in addr; if (Istrcmp(nettype, tcp )) { soc)ctype = SOCK STREAM; proto = IPPROTO TCP; if (*soc)cp== RPC ANYSOCK) { if ((s = soc)cet{AF INET, soc)ctype, 0)) < 0} { perror ( soc)cet ) ; return 0; *soc)cp = s; else s = *soc)cp; addr.sin addr.s addr = 0; addr.sin family = AF INET; addr.sin port = 0; len = sizeof(addr); (void)bind( s, (struct socjcaddr*} Saddr, len ); if (getsocJcname ( s, (struct socJcaddr*) saddr, slen } < 0) perror ( getsocJcname ) ; return 0; while (!pmap set( transient prognum-, versnum, proto, addr.sin port}) continue; return transient prognum -1; /.-------------------------------------------------------- /* Класс RPC-объектов клиента /.----------------------------------------------------------- class RPC cls ( CLIENT *clntp; char *server; public: /* Функция-конструктор. Создает RPC-объект клиента для заданного сервера, номера программы и ее версии */ RPC cls( char* hostname, unsigned prognum, unsigned vernum, char* nettype) ♦ifdef SYSV4 if (!(clntp=clnt create(hostname,prognum,vernum,nettype))) clnt pcreateerror(hostname); else ♦else server = new char[strlen(hostname)+1]; strcpy(server,hostname); struct hostent* hp = gethostbyname(hostname); struct soc)caddr in server addr; int addrlen, sock = RPC ANYSOCK; if (!hp) cerr Invalid host name: hostname \n ; else ( addrlen = sizeof (struct soc)caddr in); bcopy( hp->h addr, (caddr t)&server addr.sin addr, hp->h length); server addr.sin family = AF INET; server addr.sin port = 0; if (nettype && !strcmp(nettype, tcp )) clntp=clnttcp create(&server addr, prognum, vernum, &SOC)c, TCP BUFSIZ, TCP BUFSIZ], else { struct timeval stry; stry.tv sec = 3; stry.tv usec = 0; clntp=clntudp create(&server addr, prognum, vernum, stry, &soc)c) ; ♦endif if (Iclntp) clnt pcreateerror(hostname); else { server = new char(strlen(hostname)+1]; strcpy(server,hostname); if (clntp) set auth ( AUTH NONE ); /* destructor function */ ~RPC cls() { (void)clnt destroy( clntp ); }; /* Проверка правильности создания клиентского объекта */ int goodO ( return clntp ? 1 : 0; ); /* Установить данные аутентификации */ void set auth{ int choice, unsigned timeout = 60 ) switch (choice) ♦ifdef SYSV4 ♦else ♦endif ♦ifdef SySV4 case AUTH NONE: clntp->cl auth == authnone create0; brea)c; case AUTH SYS: case AUTH SHORT: clntp->cl auth = authsys create default0; clntp->cl auth = authunix create default0; brea)c; case AUTH DES: { char netname(MAXNETNAMELEN+l]; des bloc)c c)cey; if {lcey gendes (&c)cey)) perror ( )tey gende s ], Ц if (!user2netname{netname, getuidO, netcom.com )) { clnt perror(clntp,server); else clntp->cl auth = authdes seccreate(netname, timeout, server, &c)cey); if (!(clntp->cl auth)) {
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |