Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Тестовые примеры / ch12 / scan3 / scan_svc3
.C/* server program: low-level RPC APIs */
/* usage: scan_svc3 <ttl> */
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <malloc.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <signal.h>
#include "scan2.h"
#include "RPC.h"
char* transp = "tcp";
extern int errno;
static RPC_svc *svcp = 0;
static int work_in_progress = 0;
static int ttl = 60; /* time-to-live: 60 seconds */
int scandir( SVCXPRT* xtrp )
{
DIR *dirp;
struct dirent *d;
infolist nl, *nlp;
struct stat statv;
res res;
argPtr darg = 0;
work_in_progress = 1;
if (svcp->getargs( xtrp, (xdrproc_t)xdr_argPtr, (caddr_t)&darg)!=RPC_SUCCESS)
return -1;
cerr << "server: get dir: '" << darg->dir_name << "', lflag=" << darg->lflag << endl;
if (!(dirp = opendir(darg->dir_name))) {
res.errno = errno;
(void)svcp->reply(xtrp, (xdrproc_t)xdr_res, (caddr_t)&res);
return -2;
}
xdr_free((xdrproc_t)xdr_res, (char*)&res);
nlp = &res.res_u.list;
while (d=readdir(dirp)) {
nl = *nlp = (infolist)malloc(sizeof(struct dirinfo));
nl->name = strdup(d->d_name);
nlp = &nl->next;
if (darg->lflag) {
char pathnm[256];
sprintf(pathnm,"%s/%s",darg->dir_name,d->d_name);
if (!stat(pathnm,&statv)) {
nl->uid = statv.st_uid;
nl->modtime = statv.st_mtime;
}
}
}
*nlp = 0;
res.errno = 0;
closedir(dirp);
if (svcp->reply(xtrp, (xdrproc_t)xdr_res, (caddr_t)&res)!=RPC_SUCCESS)
return -2;
work_in_progress = 0;
return RPC_SUCCESS;
}
void done( int sig )
{
if (work_in_progress) {
/* re-schedule time-out */
signal( SIGALRM, (void(*)(int)) done );
alarm( ttl );
}
char msg[ 1024 ];
time_t tim = time(0);
sprintf( msg, "svc (%d) exiting: %s", getpid(), ctime(&tim) );
write( 1, msg, strlen(msg) );
exit(0);
}
int main(int argc, char* argv[])
{
char msg[ 1024 ];
FILE *fp = fopen("/dev/console","w");
fprintf( fp, "sv3: argc=%d, argv[1]=%s\n", argc, argc > 1 ? argv[1] : "Nil" );
if (argc > 1 && sscanf(argv[1],"%d",&ttl)!=1) {
cerr << "Invalid argument: " << argv[1] << endl;
return 1;
}
switch (fork()) {
case 0: break;
case -1: perror( "fork");
default: return errno;
}
struct rlimit rls;
rls.rlim_max = 0;
getrlimit(RLIMIT_NOFILE, &rls);
if (rls.rlim_max == 0) {
fprintf( fp, "getrlimit failed\n");
return 1;
}
for (int i = 1; i < rls.rlim_max; i++)
(void) close(i);
int fd = open("/dev/console", 2);
(void) dup2(fd, 1);
(void) dup2(fd, 2);
setsid();
time_t tim = time(0);
sprintf( msg, "svc (%d)starting: %s", getpid(), ctime(&tim) );
write( 1, msg, strlen(msg) );
svcp = new RPC_svc( 0, transp, SCANPROG, SCANVER );
if (!svcp || !svcp->good()) {
sprintf(msg, "RPC_svc failed\n");
write(1, msg, strlen(msg) );
exit( 1 );
}
svcp->add_proc( SCANDIR, scandir );
signal( SIGALRM, (void(*)(int)) done );
alarm( ttl );
svcp->run();
return 0;
}