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