Annotation of researchv9/ipc/src/libipc/ipccreat.c, revision 1.1

1.1     ! root        1: #include <sys/types.h>
        !             2: #include <sys/ioctl.h>
        !             3: #include <stdio.h>
        !             4: #include <ipc.h>
        !             5: #include "defs.h"
        !             6: 
        !             7: /* imports */
        !             8: extern int conn_ld;
        !             9: extern struct passwd *pwsearch();
        !            10: extern char *strncpy();
        !            11: 
        !            12: /* global to this file */
        !            13: #define ROOTUID 0
        !            14: 
        !            15: /* plug into the name space */
        !            16: int
        !            17: ipccreat(name, param)
        !            18:        char *name;     /* name being dialed */
        !            19:        char *param;    /* parameters for creation */
        !            20: {
        !            21:        int pfd[2];
        !            22:        char *path=name;
        !            23:        ipcinfo info;
        !            24: 
        !            25:        if (path==NULL)
        !            26:                return ABORT(EINVAL, "name too long", (ipcinfo*)NULL);
        !            27: 
        !            28:        /* make a node to mount onto */
        !            29:        if (strchr(path, '!')!=NULL || (access(path,0)<0 && creat(path, 0666)<0)) {
        !            30:                /* remote creat */
        !            31:                info.rfd = info.cfd = -1;
        !            32:                info.myname = info.user = info.machine = NULL;
        !            33:                info.uid = info.gid = -1;
        !            34:                info.name = name;
        !            35:                info.param = param;
        !            36:                info.flags = IPC_CREAT;
        !            37:                return ipcdial(&info);
        !            38:        }
        !            39: 
        !            40:        /* get the stream to mount */
        !            41:        if (pipe(pfd) < 0)
        !            42:                return ABORT(errno, "out of pipes", (ipcinfo*)NULL);
        !            43:        if (ioctl(pfd[1], FIOPUSHLD, &conn_ld) < 0) {
        !            44:                close(pfd[0]);  
        !            45:                close(pfd[1]);
        !            46:                return ABORT(errno, "pushing line discipline", (ipcinfo*)NULL);
        !            47:        }
        !            48: 
        !            49:        /* mount */
        !            50:        if (fmount(3, pfd[1], path, 0) < 0) {
        !            51:                close(pfd[0]);
        !            52:                close(pfd[1]);
        !            53:                return ABORT(errno, "can't mount", (ipcinfo*)NULL);
        !            54:        }
        !            55:        close(pfd[1]);
        !            56:        return pfd[0];
        !            57: }
        !            58: 
        !            59: /* listen for a connection */
        !            60: ipcinfo *
        !            61: ipclisten(fd)
        !            62:        int fd;
        !            63: {
        !            64:        struct passfd pass;
        !            65:        int pfd[2];
        !            66:        static ipcinfo info;
        !            67:        static char buf[BUFSIZE];
        !            68:        static char user[32];
        !            69:        int fd1= -1, fd2= -1;
        !            70: 
        !            71:        /* get a unique stream to the caller */
        !            72: restart:
        !            73:        if (_fd_read(fd, &pass)<0) {
        !            74:                close(fd);
        !            75:                return NULL;    /* nothing there */
        !            76:        }
        !            77:        info.uid = pass.uid;
        !            78:        info.gid = pass.gid;
        !            79:        info.rfd = pass.fd;
        !            80:        strncpy(user, pass.logname, sizeof(pass.logname));
        !            81:        user[sizeof(pass.logname)] = '\0';
        !            82:        info.user = user;
        !            83:        (void)ioctl(info.rfd, FIOACCEPT, &pass);
        !            84: 
        !            85:        /* get possible passed fds */
        !            86:        if (_fd_read(info.rfd, &pass)>=0) {
        !            87:                fd1 = pass.fd;
        !            88:                if (_fd_read(info.rfd, &pass)>=0)
        !            89:                        fd2 = pass.fd;
        !            90:        }
        !            91: 
        !            92:        /* get the request */
        !            93:        if (_info_read(info.rfd, &info)<0) {
        !            94:                /* requestor gave up */
        !            95:                close(info.rfd);
        !            96:                if(fd1>=0)
        !            97:                        close(fd1);
        !            98:                if(fd2>=0)
        !            99:                        close(fd2);
        !           100:                goto restart;
        !           101:        }
        !           102: 
        !           103:        /* decode the request */
        !           104:        if (info.flags & IPC_HANDOFF) {
        !           105:                close(info.rfd);
        !           106:                info.rfd = fd1;
        !           107:                info.cfd = fd2;
        !           108:                info.flags &= ~IPC_HANDOFF;
        !           109:        } else {
        !           110:                info.cfd = fd1;
        !           111:                if (fd2>=0)
        !           112:                        close(fd2);
        !           113:        }
        !           114:        return &info;
        !           115: }
        !           116: 
        !           117: /*
        !           118:  *  Accept a connection.  Close all except ip->cfd.
        !           119:  */
        !           120: int
        !           121: ipcaccept(ip)
        !           122:        ipcinfo *ip;
        !           123: {
        !           124:        ipcdaccept(ip, -1, "who_cares");
        !           125: }
        !           126: /*
        !           127:  *  Accept a connection, and supply a source address and communications fd
        !           128:  */
        !           129: int
        !           130: ipcdaccept(ip, commfd, source)
        !           131:        ipcinfo *ip;
        !           132:        int commfd;
        !           133:        char *source;
        !           134: {
        !           135:        if (commfd >= 0) {
        !           136: 
        !           137:                /* supply our own channel for communications */
        !           138:                if (_fd_write(ip->rfd, commfd) < 0) {
        !           139:                        close(commfd);
        !           140:                        return ABORT(errno, "can't pass conection", ip);
        !           141:                }
        !           142:                _reply_write(ip->rfd, 0, source);
        !           143:                ABORT(0, "", ip);
        !           144:                ip->cfd = commfd;
        !           145:        } else if (ip->cfd >= 0) {
        !           146: 
        !           147:                /* use client supplied channel for communications */
        !           148:                _reply_write(ip->rfd, 0, "");
        !           149:                close(ip->rfd);
        !           150:                ip->rfd = -1;
        !           151:        } else {
        !           152: 
        !           153:                /* use reply channel for communications */
        !           154:                _reply_write(ip->rfd, 0, "");
        !           155:                ip->cfd = ip->rfd;
        !           156:                ip->rfd = -1;
        !           157:        }
        !           158:        return(ip->cfd);
        !           159: }
        !           160: 
        !           161: /*  Reject a connection.
        !           162:  */
        !           163: int
        !           164: ipcreject(ip, no, str)
        !           165:        ipcinfo *ip;
        !           166:        int no;         /* error number */
        !           167:        char *str;      /* error string */
        !           168: {
        !           169:        _reply_write(ip->rfd, no, str);
        !           170:        ABORT(no, str, ip);
        !           171:        return 0;
        !           172: }

unix.superglobalmegacorp.com

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