[BACK]Return to fam.c++ CVS log [TXT][DIR] Up to [Development] / fam / libfam

Annotation of fam/libfam/fam.c++, Revision 1.1

1.1     ! trev        1: //  Copyright (C) 1999 Silicon Graphics, Inc.  All Rights Reserved.
        !             2: //
        !             3: //  This program is free software; you can redistribute it and/or modify it
        !             4: //  under the terms of version 2.1 of the GNU Lesser General Public License
        !             5: //  as published by the Free Software Foundation.
        !             6: //
        !             7: //  This program is distributed in the hope that it would be useful, but
        !             8: //  WITHOUT ANY WARRANTY; without even the implied warranty of
        !             9: //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  Further, any
        !            10: //  license provided herein, whether implied or otherwise, is limited to
        !            11: //  this program in accordance with the express provisions of the GNU Lesser
        !            12: //  General Public License.  Patent licenses, if any, provided herein do not
        !            13: //  apply to combinations of this program with other product or programs, or
        !            14: //  any other product whatsoever. This program is distributed without any
        !            15: //  warranty that the program is delivered free of the rightful claim of any
        !            16: //  third person by way of infringement or the like.  See the GNU Lesser
        !            17: //  General Public License for more details.
        !            18: //
        !            19: //  You should have received a copy of the GNU General Public License along
        !            20: //  with this program; if not, write the Free Software Foundation, Inc., 59
        !            21: //  Temple Place - Suite 330, Boston MA 02111-1307, USA.
        !            22:
        !            23: #include <sys/types.h>
        !            24: #include <rpc/rpc.h>
        !            25: #include <sys/time.h>
        !            26: #include <unistd.h>
        !            27: #include <stdlib.h>
        !            28: #include <stdio.h>
        !            29: #include <string.h>
        !            30: #include <sys/param.h>
        !            31: #include <syslog.h>
        !            32: #include <errno.h>
        !            33: #include <netinet/in.h>
        !            34: #include <netdb.h>
        !            35:
        !            36: #include "fam.h"
        !            37: #include "Client.h"
        !            38:
        !            39: //#define DEBUG
        !            40:
        !            41:
        !            42: // Some libserver stuff
        !            43: #define FAMNUMBER 391002 // This is the official rpc number for fam.
        !            44: #define FAMNAME "sgi_fam"
        !            45: #define FAMVERS 2
        !            46: #define LOCALHOSTNUMBER 0x7f000001 // Internet number for loopback.
        !            47:
        !            48: // Error variables - XXX currently not dealt with
        !            49: #define FAM_NUM_ERRORS 1
        !            50: int FAMErrno;
        !            51: char *FamErrlist[FAM_NUM_ERRORS];
        !            52:
        !            53: struct GroupStuff
        !            54: {
        !            55:     GroupStuff();
        !            56:     ~GroupStuff() { delete [] groups; }
        !            57:     int groupString(char *buf, int buflen);
        !            58:
        !            59:     gid_t *groups;
        !            60:     int   ngroups;
        !            61: };
        !            62:
        !            63: static int findFreeReqnum();
        !            64: static int checkRequest(FAMRequest *fr, const char *filename);
        !            65: static int sendSimpleMessage(char code, FAMConnection *fc, const FAMRequest *fr);
        !            66:
        !            67: /**************************************************************************
        !            68: * FAMOpen, FAMClose - opening, closing FAM connections
        !            69: **************************************************************************/
        !            70:
        !            71: int FAMOpen2(FAMConnection* fc, const char* appName)
        !            72: {
        !            73:     int famnumber = FAMNUMBER, famversion = FAMVERS;
        !            74:     struct rpcent *fament = getrpcbyname(FAMNAME);
        !            75:     if(fament != NULL)
        !            76:     {
        !            77:         famnumber = fament->r_number;
        !            78:     }
        !            79:
        !            80:     //  Try to connect.
        !            81:     fc->client = new Client(LOCALHOSTNUMBER, famnumber, famversion);
        !            82:     fc->fd = ((Client *)fc->client)->getSock();
        !            83:     if (fc->fd < 0) {
        !            84: 	delete (Client *)fc->client;
        !            85:         fc->client = NULL;
        !            86: 	return(-1);
        !            87:     }
        !            88:
        !            89:     // Send App name
        !            90:     if (appName) {
        !            91: 	char msg[200];
        !            92: 	snprintf(msg, sizeof(msg), "N0 %d %d %s\n", geteuid(), getegid(), appName);
        !            93: 	((Client *)fc->client)->writeToServer(msg, strlen(msg)+1);
        !            94:     }
        !            95:
        !            96:     return(0);
        !            97: }
        !            98:
        !            99: int FAMOpen(FAMConnection* fc)
        !           100: {
        !           101:     return FAMOpen2(fc, NULL);
        !           102: }
        !           103:
        !           104: int FAMClose(FAMConnection* fc)
        !           105: {
        !           106:     delete (Client *)fc->client;
        !           107:     return(0);
        !           108: }
        !           109:
        !           110:
        !           111:
        !           112: /**************************************************************************
        !           113: * FAMMonitorDirectory, FAMMonitorFile - monitor directory or file
        !           114: **************************************************************************/
        !           115:
        !           116: #define ILLEGAL_REQUEST -1
        !           117:
        !           118: static int FAMMonitor(FAMConnection *fc, const char *filename, FAMRequest* fr,
        !           119: 	       void* userData, int code)
        !           120: {
        !           121:
        !           122:     if (!filename || filename[0] != '/')
        !           123: 	return -1;
        !           124:
        !           125:     int reqnum = fr->reqnum;
        !           126:     Client *client = (Client *)fc->client;
        !           127:     // store user data if necessary
        !           128:     if(userData != NULL) client->storeUserData(reqnum, userData);
        !           129:
        !           130:     GroupStuff groups;
        !           131:     char msg[MSGBUFSIZ];
        !           132:     int msgLen;
        !           133:     snprintf(msg, MSGBUFSIZ, "%c%d %d %d %s\n", code, reqnum, geteuid(),
        !           134:                              groups.groups[0], filename);
        !           135:     msgLen = strlen(msg) + 1;  // include terminating \0 in msg
        !           136:     if(groups.ngroups > 1)
        !           137:     {
        !           138:         msgLen += groups.groupString(msg + msgLen, MSGBUFSIZ - msgLen);
        !           139:         ++msgLen;  //  include terminating \0
        !           140:     }
        !           141:
        !           142:     // Send to FAM
        !           143:     client->writeToServer(msg, msgLen);
        !           144:     return(0);
        !           145: }
        !           146: int FAMMonitorDirectory(FAMConnection *fc,
        !           147: 			const char *filename,
        !           148: 			FAMRequest* fr,
        !           149: 			void* userData)
        !           150: {
        !           151:     if(checkRequest(fr, filename) != 0) return -1;
        !           152:
        !           153: #ifdef DEBUG
        !           154: printf("FAMMonitorDirectory filename:%s, reqnum:%d, ud:%d\n", filename, fr->reqnum, (int) userData);
        !           155: #endif
        !           156:     return FAMMonitor(fc, filename, fr, userData, 'M');
        !           157: }
        !           158: int FAMMonitorDirectory2(FAMConnection *fc,
        !           159: 			 const char *filename,
        !           160: 			 FAMRequest* fr)
        !           161: {
        !           162:     return FAMMonitor(fc, filename, fr, NULL, 'M');
        !           163: }
        !           164:
        !           165: int FAMMonitorFile(FAMConnection *fc,
        !           166: 		   const char *filename,
        !           167: 		   FAMRequest* fr,
        !           168: 		   void* userData)
        !           169: {
        !           170:     if(checkRequest(fr, filename) != 0) return -1;
        !           171:
        !           172: #ifdef DEBUG
        !           173: printf("FAMMonitorFile filename:%s, reqnum:%d, ud:%d\n", filename, fr->reqnum, (int) userData);
        !           174: #endif
        !           175:     return FAMMonitor(fc, filename, fr, userData, 'W');
        !           176: }
        !           177: int FAMMonitorFile2(FAMConnection *fc,
        !           178: 		    const char *filename,
        !           179: 		    FAMRequest* fr)
        !           180: {
        !           181:     return FAMMonitor(fc, filename, fr, NULL, 'W');
        !           182: }
        !           183:
        !           184:
        !           185: int
        !           186: FAMMonitorCollection(FAMConnection* fc,
        !           187: 		     const char* filename,
        !           188: 		     FAMRequest* fr,
        !           189: 		     void* userData,
        !           190: 		     int depth,
        !           191: 		     const char* mask)
        !           192: {
        !           193:     if(checkRequest(fr, filename) != 0) return -1;
        !           194:
        !           195:     Client *client = (Client *)fc->client;
        !           196:
        !           197:     // store user data if necessary
        !           198:     if (userData) client->storeUserData(fr->reqnum, userData);
        !           199:
        !           200:     GroupStuff groups;
        !           201:     char msg[MSGBUFSIZ];
        !           202:     int msgLen;
        !           203:     snprintf(msg, MSGBUFSIZ, "F%d %d %d %s\n", fr->reqnum, geteuid(),
        !           204:                              groups.groups[0], filename);
        !           205:     msgLen = strlen(msg) + 1;  // include terminating \0 in msg
        !           206:
        !           207:     if(groups.ngroups > 1)
        !           208:     {
        !           209:         msgLen += groups.groupString(msg + msgLen, MSGBUFSIZ - msgLen);
        !           210:     }
        !           211:
        !           212:     snprintf(msg + msgLen, MSGBUFSIZ - msgLen, "0 %d %s\n", depth, mask);
        !           213:     ++msgLen;  //  include terminating \0
        !           214:
        !           215:     // Send to FAM
        !           216:     client->writeToServer(msg, msgLen);
        !           217:     return(0);
        !           218: }
        !           219:
        !           220:
        !           221: /**************************************************************************
        !           222: * FAMSuspendMonitor, FAMResumeMonitor - suspend FAM monitoring
        !           223: **************************************************************************/
        !           224:
        !           225: int FAMSuspendMonitor(FAMConnection *fc, const FAMRequest *fr)
        !           226: {
        !           227:     return sendSimpleMessage('S', fc, fr);
        !           228: }
        !           229:
        !           230: int FAMResumeMonitor(FAMConnection *fc, const FAMRequest *fr)
        !           231: {
        !           232:     return sendSimpleMessage('U', fc, fr);
        !           233: }
        !           234:
        !           235:
        !           236:
        !           237: /**************************************************************************
        !           238: * FAMCancelMonitor - cancel FAM monitoring
        !           239: **************************************************************************/
        !           240:
        !           241: int FAMCancelMonitor(FAMConnection *fc, const FAMRequest* fr)
        !           242: {
        !           243: #ifdef DEBUG
        !           244: printf("FAMCancelMonitor reqnum:%d\n", fr->reqnum);
        !           245: #endif
        !           246:     // Remove from user Data array
        !           247:     // Actually, we will do this when we receive the ack back from fam
        !           248:     // FAMFreeRequest(fr->reqnum);
        !           249:
        !           250:     return sendSimpleMessage('C', fc, fr);
        !           251: }
        !           252:
        !           253:
        !           254: /**************************************************************************
        !           255: * FAMNextEvent() - find the next fam event
        !           256: * FAMPending() - return if events are ready yet
        !           257: **************************************************************************/
        !           258:
        !           259: //  FAMNextEvent tries to read one complete message into the input buffer.
        !           260: //  If it's successful, it parses the message and returns 1.
        !           261: //  Otherwise (EOF or errors), it returns -1.
        !           262:
        !           263: int FAMNextEvent(FAMConnection* fc, FAMEvent* fe)
        !           264: {
        !           265:     fe->fc = fc;
        !           266:     return ((Client *)fc->client)->nextEvent(fe);
        !           267: }
        !           268:
        !           269: //  FAMPending tries to read one complete message into the input buffer.
        !           270: //  If it's successful, then it returns true.  Also, if it reads EOF, it
        !           271: //  returns true.
        !           272:
        !           273: int FAMPending(FAMConnection* fc)
        !           274: {
        !           275:     return ((Client *)fc->client)->eventPending();
        !           276: }
        !           277:
        !           278:
        !           279:
        !           280: /**************************************************************************
        !           281: * FAMDebugLevel() - doesn't do anything
        !           282: **************************************************************************/
        !           283: int FAMDebugLevel(FAMConnection*, int)
        !           284: {
        !           285:     return(1);
        !           286: }
        !           287:
        !           288:
        !           289:
        !           290: /**************************************************************************
        !           291: * Support Functions
        !           292: **************************************************************************/
        !           293:
        !           294: static int
        !           295: findFreeReqnum()
        !           296: {
        !           297:     static int reqnum=1;
        !           298:     return(reqnum++);
        !           299: }
        !           300:
        !           301: static int
        !           302: checkRequest(FAMRequest *fr, const char *filename)
        !           303: {
        !           304:     // Fill out request structure
        !           305:     int reqnum;
        !           306:     if ((reqnum = findFreeReqnum()) == ILLEGAL_REQUEST) {
        !           307: 	return(-1);
        !           308:     }
        !           309:     fr->reqnum = reqnum;
        !           310:
        !           311:     // Check path length of file
        !           312:     if (strlen(filename) > MAXPATHLEN) {
        !           313: 	syslog(LOG_ALERT, "path too long\n");
        !           314: 	errno = ENAMETOOLONG;
        !           315: 	return (-1);
        !           316:     }
        !           317:     return 0;
        !           318: }
        !           319:
        !           320: static int
        !           321: sendSimpleMessage(char code, FAMConnection *fc, const FAMRequest *fr)
        !           322: {
        !           323:     // Create FAM String
        !           324:     char msg[MSGBUFSIZ];
        !           325:     snprintf(msg, MSGBUFSIZ, "%c%d %d %d\n", code, fr->reqnum, geteuid(), getegid());
        !           326:
        !           327:     // Send to FAM
        !           328:     ((Client *)fc->client)->writeToServer(msg, strlen(msg)+1);
        !           329:     return(0);
        !           330: }
        !           331:
        !           332: GroupStuff::GroupStuff()
        !           333: {
        !           334:     ngroups = sysconf(_SC_NGROUPS_MAX);
        !           335:     groups = new gid_t[ngroups];
        !           336:     ngroups = getgroups(ngroups, groups);
        !           337: }
        !           338:
        !           339: int
        !           340: GroupStuff::groupString(char *buf, int buflen)
        !           341: {
        !           342:     if(ngroups < 2) return 0;
        !           343:     const int GROUP_STRLEN = 8;  // max length of " %d" output, we hope
        !           344:     if(buflen < (ngroups * GROUP_STRLEN)) return 0;
        !           345:     //XXX that should create some error condition
        !           346:
        !           347:     char *p = buf;
        !           348:     snprintf(p, GROUP_STRLEN, "%d", ngroups - 1);
        !           349:     p += strlen(p);
        !           350:     for(int i = 1; i < ngroups; ++i)  //  group[0] doesn't go in string
        !           351:     {
        !           352:         snprintf(p, GROUP_STRLEN, " %d", groups[i]);
        !           353:         p += strlen(p);
        !           354:     }
        !           355:     *p = '\0';
        !           356:
        !           357:     return p - buf;
        !           358: }
        !           359:

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>