Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
17
Добавлен:
01.05.2014
Размер:
3.23 Кб
Скачать
/* 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;
}
Соседние файлы в папке scan3