Annotation of researchv9/ipc/src/libipc/ipcopen.c, revision 1.1.1.1

1.1       root        1: #include <sys/types.h>
                      2: #include <sys/ioctl.h>
                      3: #include <sys/stat.h>
                      4: #include <ipc.h>
                      5: #include "defs.h"
                      6: 
                      7: /* exported */
                      8: char *errstr;
                      9: 
                     10: /* imports */
                     11: extern int atoi();
                     12: extern char *memchr();
                     13: 
                     14: /* dial a name and return an fd to the connection */
                     15: int
                     16: ipcopen(name, param)
                     17:        char *name;     /* name being dialed */
                     18:        char *param;    /* parameters for dialer */
                     19: {
                     20:        ipcinfo info;
                     21: 
                     22:        info.rfd = info.cfd = -1;
                     23:        info.myname = info.user = info.machine = NULL;
                     24:        info.uid = info.gid = -1;
                     25:        info.name = name;
                     26:        info.param = param;
                     27:        info.flags = IPC_OPEN;
                     28:        return ipcdial(&info);
                     29: }
                     30: 
                     31: /*
                     32:  *  Open a mounted steam.  ip->name points to a string of the form
                     33:  *  path!address.  Path must be a file system path to a mounted stream.
                     34:  */ 
                     35: _ipcopen(ip)
                     36:        ipcinfo *ip;
                     37: {
                     38:        static stretch path;
                     39:        char *np;
                     40:        int fd;
                     41:        struct stat sbuf;
                     42: 
                     43:        /* split into path and network address */
                     44:        _strcat(&path, ip->name, (char *)NULL, (char *)NULL);
                     45:        np = strchr(path.ptr, '!');
                     46:        if (np) {
                     47:                *np = '\0';
                     48:                ip->name += np - path.ptr + 1;
                     49:        }
                     50:        if (ip->flags&IPC_CAREFUL) {
                     51:                if (stat(path.ptr, &sbuf)<0)
                     52:                        return ABORT(ENOENT, "destination nonexistent", NULLINFO);
                     53:                if (sbuf.st_mode&6 != 6)
                     54:                        return ABORT(EACCES, "permission denied", NULLINFO);
                     55:        }
                     56:        if ((fd = open(path.ptr, 2))<0) {
                     57:                if (errno==EACCES){
                     58:                        if (*(ip->name))
                     59:                            return ABORT(EACCES, "can't access dialer", NULLINFO);
                     60:                        else
                     61:                            return ABORT(EACCES, "permission denied", NULLINFO);
                     62:                } else
                     63:                        return ABORT(ENOENT, "destination nonexistent", NULLINFO);
                     64:        }
                     65: 
                     66:        /* update the translated part of the name */
                     67:        if(ip->myname)
                     68:                _strcat(&path, ip->myname, "!", path.ptr);
                     69:        ip->myname = path.ptr;
                     70:        return fd;
                     71: }
                     72: 
                     73: /* dial a name and return an fd to the connection */
                     74: int
                     75: ipcdial(ip)
                     76:        ipcinfo *ip;
                     77: {
                     78:        struct passfd pass;
                     79:        int fd;
                     80: 
                     81:        if ((fd = _ipcopen(ip))<0)
                     82:                return -1;
                     83: 
                     84:        /* pass reply channel */
                     85:        if (ip->rfd >= 0) {
                     86:                if (_fd_write(fd, ip->rfd)<0) {
                     87:                        close(fd);
                     88:                        return ABORT(EIO, "protocol botch", ip);
                     89:                }
                     90:                close(ip->rfd);
                     91:                ip->rfd = -1;
                     92:        }
                     93: 
                     94:        /* pass communications channel (if not same as reply channel) */
                     95:        if (ip->cfd >= 0) {
                     96:                if (_fd_write(fd, ip->cfd)<0) {
                     97:                        close(fd);
                     98:                        return ABORT(EIO, "protocol botch", ip);
                     99:                }
                    100:                close(ip->cfd);
                    101:                ip->cfd = -1;
                    102:        }
                    103: 
                    104:        /* pass the info on */
                    105:        if (_info_write(fd, ip) < 0) {
                    106:                close(fd);
                    107:                return ABORT(errno, errstr, ip);
                    108:        }
                    109:        if (ip->flags&IPC_HANDOFF)
                    110:                return fd;
                    111: 
                    112:        /* get the reply  */
                    113:        if (_fd_read(fd, &pass)>=0) {
                    114:                _reply_read(fd);
                    115:                if (errno != 0) {
                    116:                        close(fd);
                    117:                        close(pass.fd);
                    118:                        return ABORT(errno, errstr, NULLINFO);
                    119:                }
                    120:                return pass.fd;
                    121:        } else {
                    122:                _reply_read(fd);
                    123:                if (errno != 0) {
                    124:                        close(fd);
                    125:                        return ABORT(errno, errstr, NULLINFO);
                    126:                }
                    127:                return fd;
                    128:        }
                    129: }
                    130: 
                    131: /*
                    132:  *  Pass a request to someone else to handle.
                    133:  */
                    134: ipcpass(ip)
                    135:        ipcinfo *ip;
                    136: {
                    137:        ip->flags |= IPC_HANDOFF;
                    138:        return ipcdial(ip);
                    139: }
                    140: 
                    141: /* set error number and string and return -1 */
                    142: int
                    143: _ipcabort(no, err, ip)
                    144:        int no;
                    145:        char *err;
                    146:        ipcinfo *ip;
                    147: {
                    148:        if (ip!=NULLINFO) {
                    149:                if (ip->cfd>0) {
                    150:                        close(ip->cfd);
                    151:                        ip->cfd = -1;
                    152:                }
                    153:                if (ip->rfd>0) {
                    154:                        close(ip->rfd);
                    155:                        ip->rfd = -1;
                    156:                }
                    157:        }
                    158:        errstr = err;
                    159:        errno = no;
                    160:        return -1;
                    161: }

unix.superglobalmegacorp.com

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