rfainfo.c

来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 689 行 · 第 1/2 页

C
689
字号
/* * RFA - Remote File Access * * Access and Management for a partial file system tree that exists * at two sites either as master files or slave files * * rfainfo.c : functions to manipulate fileinfo structure and files * * Contributed by Oliver Wenzel, GMD Berlin, 1990 * * $Header: /xtel/isode/isode/others/rfa/RCS/rfainfo.c,v 9.0 1992/06/16 12:47:25 isode Rel $ * * $Log: rfainfo.c,v $ * Revision 9.0  1992/06/16  12:47:25  isode * Release 8.0 * */#ifndef       lintstatic char *rcsid = "$Header: /xtel/isode/isode/others/rfa/RCS/rfainfo.c,v 9.0 1992/06/16 12:47:25 isode Rel $";#endif/* *                              NOTICE * *    Acquisition, use, and distribution of this module and related *    materials are subject to the restrictions of a license agreement. *    Consult the Preface in the User's Manual for the full terms of *    this agreement. * */#include <stdio.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include "sys.file.h"#include <sys/time.h>#include <ctype.h>#include <pwd.h>#include <grp.h>#include <dirent.h>#include <unistd.h>#include <signal.h>#include "psap.h"#include "logger.h"#include "rfainfo.h"#include "rfa.h"#define MAXSTAT 4struct LockEntry {	FILE			*le_filep;	char			 le_fn[512];	struct LockEntry 	*le_next;} static *lockList = NULL;static int timedout = 0;extern char *sys_errname();char rfaErrStr[512];/*------------------------------------------------------ * str2status - convert status string to integer code *------------------------------------------------------*/int str2status (stat)    char *stat;{    int i = 0;    switch(*(stat++)) {	case '-':	    SET_STATUS(i, RI_UNREGISTERED); 	    break;	case 'M':	case 'm':	    SET_STATUS(i, RI_MASTER); 	    break;	case 'S':	case 's':	    SET_STATUS(i, RI_SLAVE); 	    break;	default:	    return NOTOK;    }    switch(*(stat++)) {	case '-':	    SET_LOCKINFO(i, RI_UNLOCKED); 	    break;	case 'L':	case 'l':	    SET_LOCKINFO(i, RI_LOCKED); 	    break;	default:	    return NOTOK;    }    switch(*(stat++)) {	case '-':	    SET_TRANSFER(i, RI_TR_REQ); 	    break;	case 'A':	case 'a':	    SET_TRANSFER(i, RI_TR_AUTO); 	    break;	default:	    return NOTOK;    }    return i;}/*------------------------------------------------------ * status2str - convert status to string *------------------------------------------------------*/char *status2str(stat)    int stat;{    static char sbuf[5];    register char *s = sbuf;    switch(RI_STATUS(stat)) {	case RI_UNREGISTERED: 		*s = '-';		break;	case RI_MASTER: 		*s = 'M';		break;	case RI_SLAVE: 		*s = 'S';		break;	default:		sbuf[0] = '?';    }    s++;    switch(RI_LOCKINFO(stat)) {	case RI_LOCKED: 		*s = 'L';		break;	case RI_UNLOCKED: 		*s = '-';		break;	default:		*s = '?';    }    s++;    switch(RI_TRANSFER(stat)) {	case RI_TR_AUTO: 		*s = 'A';		break;	case RI_TR_REQ: 		*s = '-';		break;	default:		*s = '?';    }    *(++s) = '\0';    return sbuf;}/*------------------------------------------------------ * mallocRfaInfo - malloc list elements *------------------------------------------------------*/struct RfaInfo *mallocRfaInfo (fn)    char *fn;{    register struct RfaInfo *rfa;    if ((rfa = (struct RfaInfo *) malloc(sizeof(struct RfaInfo))) == NULL) {	sprintf(rfaErrStr, "out of memory");	advise(LLOG_EXCEPTIONS,NULLCP,rfaErrStr);	return NULL;    }    bzero((char *)rfa, sizeof(struct RfaInfo));    rfa->ri_filename = fn;    return rfa;}	/*------------------------------------------------------ * freeRfaInfoList - free list elements *------------------------------------------------------*/void freeRfaInfoList (rfa)   struct RfaInfo *rfa;{   struct RfaInfo *r;   for (; rfa; rfa = r) {	if (rfa->ri_filename)	    free(rfa->ri_filename);	if (rfa->ri_lckname)	    free(rfa->ri_lckname);	if (rfa->ri_owner)	    free(rfa->ri_owner);	if (rfa->ri_group)	    free(rfa->ri_group);	r = rfa->ri_next;	free((char *)rfa);    }}/*------------------------------------------------------ * lock_timeout - handler for lock timeout *------------------------------------------------------*//* ARGSUSED */SFD lock_timeout(sig) int sig;{    timedout++;}/*------------------------------------------------------ * lckRfainfo  *------------------------------------------------------*/static struct LockEntry *lockRfainfo(fn, fp)    char *fn;    FILE *fp;{    struct LockEntry *le;    struct itimerval itv;    if ((le = (struct LockEntry *)malloc(sizeof(struct LockEntry))) == NULL) {	sprintf(rfaErrStr, "can't lock (no memory)"); 	advise (LLOG_EXCEPTIONS, NULLCP, rfaErrStr);	return NULL;    }    strcpy (le->le_fn, fn);    le->le_filep = fp;    /*-- set timer --*/    itv.it_interval.tv_sec = 0L;    itv.it_interval.tv_usec = 0L;    itv.it_value.tv_sec = LOCK_TIMEOUT;    itv.it_value.tv_usec = 0L;    if (setitimer(ITIMER_REAL, &itv, (struct itimerval *)NULL) != -1) {	signal(SIGALRM, lock_timeout);    }    timedout = 0;    if (lockf(fileno(fp), F_LOCK, 0L) == -1) {	if (timedout)		    sprintf(rfaErrStr, "lock timed out");	else	    sprintf(rfaErrStr, "can't lock (%s)", sys_errname(errno));	advise (LLOG_EXCEPTIONS, NULLCP, rfaErrStr);	free((char *)le);	itv.it_value.tv_sec = 0L;	setitimer(ITIMER_REAL, &itv, (struct itimerval *)NULL);	signal(SIGALRM, SIG_DFL);	return NULL;    }    itv.it_value.tv_sec = 0L;    setitimer(ITIMER_REAL, &itv, (struct itimerval *)NULL);    signal(SIGALRM, SIG_DFL);    le->le_next = lockList;    lockList = le;    return le;}/*------------------------------------------------------ * closeAndUnlockRfainfo *------------------------------------------------------*/static int closeAndUnlockRfainfo(fn)    char *fn;{    struct LockEntry *le, **lep;    for (lep = &lockList; *lep; lep = &((*lep)->le_next))	if (strcmp((*lep)->le_fn, fn) == 0) {	    le = *lep;	    *lep = le->le_next;	    if (lockf(fileno(le->le_filep), F_ULOCK, 0L) == -1)  {		sprintf(rfaErrStr, "can't unlock (%s)",sys_errname(errno));		advise (LLOG_EXCEPTIONS, NULLCP, rfaErrStr);		if (le->le_filep)		    fclose(le->le_filep);		free((char *)le);		return NOTOK;	    }	    if (le->le_filep)		fclose(le->le_filep);	    free((char *)le);	    return OK;	}    sprintf(rfaErrStr, "can't unlock (not locked)");    advise (LLOG_EXCEPTIONS, NULLCP, rfaErrStr);    return NOTOK;}/*------------------------------------------------------ * releaseRfaInfoList - unlock list and free it *------------------------------------------------------*/void releaseRfaInfoList(fn, rfa)    char *fn;    struct RfaInfo *rfa;{    closeAndUnlockRfainfo(fn);    freeRfaInfoList(rfa);}/*------------------------------------------------------ * statFile - return RfaInfo with results of stat(2) for "fn" *------------------------------------------------------*/static int statFile(fn, rfa)    char *fn;    struct RfaInfo *rfa;{    struct stat st;    struct group *gr, *getgrgid();    struct passwd *pw, *getpwuid();    char   lnkbuf[BUFSIZ];    char   buf[100];    int    rc;    static char lastuname[100], lastgname[100];    static int lastuid = -1, lastgid = -1;    /*advise (LLOG_DEBUG, NULLCP, "statFile:  '%s'", fn);*/    if (lstat(fn,&st) == -1) {	advise (LLOG_EXCEPTIONS, NULLCP, "cant stat '%s':%s", fn,		sys_errname(errno));	sprintf(rfaErrStr, "%s (%s)", fn, sys_errname(errno));	return NOTOK;    }    rfa->ri_size = st.st_size;    rfa->ri_accTime = st.st_atime;    rfa->ri_modTime = st.st_mtime;    rfa->ri_mode = st.st_mode;    /*--- get user and group of owner ---*/    if(st.st_uid == lastuid)	rfa->ri_owner = strdup(lastuname);    else 	if ((pw = getpwuid (lastuid = st.st_uid)) == NULL) {	    advise (LLOG_EXCEPTIONS, NULLCP, "Unknown user-id '%d'", lastuid);	    sprintf(lastuname, "uid %d", lastuid);	    rfa->ri_owner = strdup(lastuname);	} else {	    rfa->ri_owner = strdup(pw->pw_name);	    strcpy(lastuname, pw->pw_name);	}    if(st.st_gid == lastgid)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?