Annotation of researchv9/ipc/src/libipc/ipccreat.c, revision 1.1.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.