Annotation of researchv10dc/ipc/libipc/ipccreat.c, revision 1.1

1.1     ! root        1: #include <sys/types.h>
        !             2: #include <sys/filio.h>
        !             3: #include <ipc.h>
        !             4: #include "defs.h"
        !             5: 
        !             6: /* imports */
        !             7: extern int conn_ld;
        !             8: extern struct passwd *pwsearch();
        !             9: extern char *strncpy();
        !            10: 
        !            11: /* global to this file */
        !            12: #define ROOTUID 0
        !            13: 
        !            14: /*
        !            15:  *  Attach to a name space.  If the path is a single element,
        !            16:  *  just mount into the file system.  Otherwise, pass the request
        !            17:  *  to a network dialer.
        !            18:  */
        !            19: int
        !            20: ipccreat(name, param)
        !            21:        char *name;     /* name being dialed */
        !            22:        char *param;    /* parameters for creation */
        !            23: {
        !            24:        int pfd[2];
        !            25:        char *path=name;
        !            26:        ipcinfo info;
        !            27:        int nfd;
        !            28: 
        !            29:        if (path==NULL)
        !            30:                return ABORT(EINVAL, "name too long", (ipcinfo*)NULL);
        !            31: 
        !            32:        /*
        !            33:         *  if a path is specified, pass the request through a dialer
        !            34:         */
        !            35:        if (strchr(path, '!')!=NULL) {
        !            36:                info.rfd = info.cfd = -1;
        !            37:                info.myname = info.user = info.machine = NULL;
        !            38:                info.uid = info.gid = -1;
        !            39:                info.name = name;
        !            40:                info.param = param;
        !            41:                info.flags = IPC_CREAT;
        !            42:                return ipcdial(&info);
        !            43:        }
        !            44: 
        !            45:        /*
        !            46:         *  Try creating a file to mount on
        !            47:         */
        !            48:        if(access(path, 0) < 0){
        !            49:                nfd = creat(path, 0666);
        !            50:                if(nfd < 0)
        !            51:                        return ABORT(errno, "can't mount", (ipcinfo*)NULL);
        !            52:                close(nfd);
        !            53:        }
        !            54: 
        !            55:        /*
        !            56:         *  make a pipe to mount into the file system and push the
        !            57:         *  connection line discipline.  Conn_ld ensures that all
        !            58:         *  opens of the pipe will spawn a unique connection.
        !            59:         */
        !            60:        if (pipe(pfd) < 0)
        !            61:                return ABORT(errno, "out of pipes", (ipcinfo*)NULL);
        !            62:        if (ioctl(pfd[1], FIOPUSHLD, &conn_ld) < 0) {
        !            63:                close(pfd[0]);  
        !            64:                close(pfd[1]);
        !            65:                return ABORT(errno, "pushing line discipline", (ipcinfo*)NULL);
        !            66:        }
        !            67: 
        !            68:        /* mount */
        !            69:        if (fmount(3, pfd[1], path, 0) < 0) {
        !            70:                close(pfd[0]);
        !            71:                close(pfd[1]);
        !            72:                return ABORT(errno, "can't mount", (ipcinfo*)NULL);
        !            73:        }
        !            74:        close(pfd[1]);
        !            75:        return pfd[0];
        !            76: }
        !            77: 
        !            78: /*
        !            79:  *  listen for a connection
        !            80:  */
        !            81: ipcinfo *
        !            82: ipclisten(fd)
        !            83:        int fd;
        !            84: {
        !            85:        struct passfd pass;
        !            86:        int pfd[2];
        !            87:        static ipcinfo info;
        !            88:        static char user[32];
        !            89:        int fd1=-1, fd2=-1;
        !            90: 
        !            91:        /* 
        !            92:         *  Get a unique stream to a caller, or reuse this one if none is passed.
        !            93:         *  The reuse is typical of the arpa! gateway.
        !            94:         */
        !            95:        if(_fd_read(fd, &pass) < 0) {
        !            96:                if(errno==EINTR)
        !            97:                        return NULL;
        !            98:                info.uid = -1;
        !            99:                info.gid = -1;
        !           100:                info.rfd = dup(fd);
        !           101:                close(fd);
        !           102:        } else {
        !           103:                info.uid = pass.uid;
        !           104:                info.gid = pass.gid;
        !           105:                info.rfd = pass.fd;
        !           106:        }
        !           107:        strncpy(user, pass.logname, sizeof(pass.logname));
        !           108:        user[sizeof(pass.logname)] = '\0';
        !           109:        info.user = user;
        !           110:        (void)ioctl(info.rfd, FIOACCEPT, &pass);
        !           111: 
        !           112:        /*
        !           113:         *  Get possible passed fds.  Up to two can be passed, i.e.
        !           114:         *  the fd to reply to and the one to use for communication.
        !           115:         */
        !           116:        if (_fd_read(info.rfd, &pass)>=0) {
        !           117:                fd1 = pass.fd;
        !           118:                if (_fd_read(info.rfd, &pass)>=0) {
        !           119:                        fd2 = pass.fd;
        !           120:                } else if(errno==EINTR){
        !           121:                        close(info.rfd);
        !           122:                        close(fd1);
        !           123:                        return NULL;
        !           124:                }
        !           125:        } else if(errno==EINTR){
        !           126:                close(info.rfd);
        !           127:                return NULL;
        !           128:        }
        !           129: 
        !           130:        /*
        !           131:         *  get the request
        !           132:         */
        !           133:        if (_info_read(info.rfd, &info)<0) {
        !           134:                /* requestor gave up */
        !           135:                close(info.rfd);
        !           136:                if(fd1>=0)
        !           137:                        close(fd1);
        !           138:                if(fd2>=0)
        !           139:                        close(fd2);
        !           140:                return NULL;
        !           141:        }
        !           142: 
        !           143:        if (info.flags & IPC_HANDOFF) {
        !           144:                /*
        !           145:                 *  This is a call passed to us
        !           146:                 *  by someone else.
        !           147:                 */
        !           148:                close(info.rfd);
        !           149:                info.rfd = fd1;
        !           150:                info.cfd = fd2;
        !           151:                info.flags &= ~IPC_HANDOFF;
        !           152:        } else {
        !           153:                /*
        !           154:                 *  By default the fd on which the
        !           155:                 *  request was received will be used
        !           156:                 *  both for replies and communication
        !           157:                 */
        !           158:                info.cfd = fd1;
        !           159:                if (fd2>=0)
        !           160:                        close(fd2);
        !           161:        }
        !           162:        return &info;
        !           163: }
        !           164: 
        !           165: /*
        !           166:  *  Accept a connection.
        !           167:  *  Close all fd's except ip->cfd.
        !           168:  */
        !           169: int
        !           170: ipcaccept(ip)
        !           171:        ipcinfo *ip;
        !           172: {
        !           173:        return ipcdaccept(ip, -1, "who_cares");
        !           174: }
        !           175: 
        !           176: /*
        !           177:  *  Accept a connection, and supply a source address and communications fd
        !           178:  */
        !           179: int
        !           180: ipcdaccept(ip, commfd, source)
        !           181:        ipcinfo *ip;
        !           182:        int commfd;
        !           183:        char *source;
        !           184: {
        !           185:        if (commfd >= 0) {
        !           186:                /*
        !           187:                 *  supply our own channel for communications
        !           188:                 */
        !           189:                if (_fd_write(ip->rfd, commfd) < 0) {
        !           190:                        close(commfd);
        !           191:                        return ABORT(errno, "can't pass conection", ip);
        !           192:                }
        !           193:                _reply_write(ip->rfd, 0, source);
        !           194:                ABORT(0, "", ip);
        !           195:                ip->cfd = commfd;
        !           196:        } else if (ip->cfd >= 0) {
        !           197:                /*
        !           198:                 *  use client supplied channel for communications
        !           199:                 */
        !           200:                _reply_write(ip->rfd, 0, "");
        !           201:                close(ip->rfd);
        !           202:                ip->rfd = -1;
        !           203:        } else {
        !           204:                /*
        !           205:                 *  use reply channel for communications
        !           206:                 */
        !           207:                _reply_write(ip->rfd, 0, "");
        !           208:                ip->cfd = ip->rfd;
        !           209:                ip->rfd = -1;
        !           210:        }
        !           211:        return(ip->cfd);
        !           212: }
        !           213: 
        !           214: /*
        !           215:  *  Reject a connection.
        !           216:  */
        !           217: int
        !           218: ipcreject(ip, no, str)
        !           219:        ipcinfo *ip;
        !           220:        int no;         /* error number */
        !           221:        char *str;      /* error string */
        !           222: {
        !           223:        _reply_write(ip->rfd, no, str);
        !           224:        ABORT(no, str, ip);
        !           225:        return 0;
        !           226: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.