OSSP CVS Repository

ossp - Difference in ossp-pkg/sa/sa.c versions 1.3 and 1.4
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/sa/sa.c 1.3 -> 1.4

--- sa.c 2001/10/04 11:25:44     1.3
+++ sa.c 2001/10/05 11:40:22     1.4
@@ -55,14 +55,14 @@
 
 /* socket address abstraction object */
 struct sa_addr_st {
+    int              nFamily;
     struct sockaddr *saBuf;
     socklen_t        slBuf;
-    int              nFamily;
-    int              nProto;
 };
 
 /* socket abstraction object */
 struct sa_st {
+    sa_type_t        eType;
     int              sSocket;
     int              bTimeout;
     struct timeval   tvTimeout;
@@ -199,7 +199,6 @@
     (*saa)->saBuf   = NULL;
     (*saa)->slBuf   = 0;
     (*saa)->nFamily = 0;
-    (*saa)->nProto   = 0;
     return SA_OK;
 }
 
@@ -219,19 +218,20 @@
     int nPort;
     socklen_t sl;
     struct sockaddr *sa;
+    struct sockaddr_un un;
     struct sockaddr_in sa4;
 #ifdef AF_INET6
     struct sockaddr_in6 sa6;
 #endif
     struct hostent *he;
     struct servent *se;
-    struct protoent *pe;
     int bNumeric;
     int i;
+    int n;
     char *cpProto;
-    int   nProto;
     char *cpHost;
     char *cpPort;
+    char *cpPath;
     char uribuf[1024];
     char *cp;
     int sf;
@@ -245,42 +245,52 @@
     sa_mvsnprintf(uribuf, sizeof(uribuf), uri, ap);
     va_end(ap);
 
-    /* parse URI into protocol, host and port parts */
+    /* parse URI into parts */
     uri = uribuf;
-    cpProto = "tcp";
-    if ((cp = strstr(uri, "://")) != NULL) {
+    cpProto = "unix";
+    if ((cp = strchr(uri, ':')) != NULL) {
         cpProto = (char *)uri;
         *cp = '\0';
-        uri = cp+3;
+        uri = cp+1;
     }
-    cpHost = (char *)uri;
-    if ((cp = strchr(uri, ':')) == NULL)
-        return SA_ERR_ARG;
-    *cp++ = '\0';
-    cpPort = cp;
-
-    /* resolve protocol */
-    if ((pe = getprotobyname(cpProto)) == NULL)
-        return SA_ERR_SYS;
-    nProto = pe->p_proto;
+    cpHost = "";
+    cpPort = "";
+    if (strncmp(uri, "//", 2) == 0) {
+        uri += 2;
+        cpHost = (char *)uri;
+        if ((cp = strchr(uri, ':')) == NULL)
+            return SA_ERR_ARG;
+        *cp++ = '\0';
+        cpPort = cp;
+        uri = cp;
+        if ((cp = strchr(uri, '/')) != NULL)
+            uri = cp;
+        else
+            uri = strchr(uri, '\0');
+    }
+    cpPath = (char *)uri;
 
     /* resolve port */
-    bNumeric = 1;
-    for (i = 0; cpPort[i] != '\0'; i++) {
-        if (!isdigit((int)cpPort[i])) {
-            bNumeric = 0;
-            break;
+    nPort = 0;
+    if (strcmp(cpProto, "inet") == 0) {
+        bNumeric = 1;
+        for (i = 0; cpPort[i] != '\0'; i++) {
+            if (!isdigit((int)cpPort[i])) {
+                bNumeric = 0;
+                break;
+            }
+        }
+        if (bNumeric)
+            nPort = atoi(cpPort);
+        else {
+            if ((se = getservbyname(cpPort, cpProto)) == NULL)
+                return SA_ERR_SYS;
+            nPort = ntohs(se->s_port);
         }
-    }
-    if (bNumeric)
-        nPort = atoi(cpPort);
-    else {
-        if ((se = getservbyname(cpPort, cpProto)) == NULL)
-            return SA_ERR_SYS;
-        nPort = ntohs(se->s_port);
     }
 
     /* mandatory(!) socket address structure initialization */
+    memset(&un,  0, sizeof(un));
     memset(&sa4, 0, sizeof(sa4));
 #ifdef AF_INET6
     memset(&sa6, 0, sizeof(sa6));
@@ -291,41 +301,55 @@
     sa = NULL;
     sl = 0;
     sf = 0;
-    if (inet_pton(AF_INET, cpHost, &sa4.sin_addr.s_addr) == 1) {
-        sa4.sin_family = AF_INET;
-        sa4.sin_port = htons(nPort);
-        sa = (struct sockaddr *)&sa4;
-        sl = sizeof(sa4);
-        sf = AF_INET;
-    }
-#ifdef AF_INET6
-    else if (inet_pton(AF_INET6, cpHost, &sa6.sin6_addr.s6_addr) == 1) {
-        sa6.sin6_family = AF_INET6;
-        sa6.sin6_port = htons(nPort);
-        sa = (struct sockaddr *)&sa6;
-        sl = sizeof(sa6);
-        sf = AF_INET6;
+    if (strcmp(cpProto, "unix") == 0) {
+        if (cpProto[0] != '/')
+            return SA_ERR_ARG;
+        n = strlen(cpProto);
+        if ((n+1) > sizeof(un.sun_path))
+            return SA_ERR_MEM;
+        memcpy(un.sun_path, cpPath, n+1);
+        un.sun_family = AF_LOCAL;
+        sa = (struct sockaddr *)&un;
+        sl = sizeof(un);
+        sf = AF_LOCAL;
     }
-#endif
-    else if ((he = gethostbyname(cpHost)) != NULL) {
-        if (he->h_addrtype == AF_INET) {
+    else if (strcmp(cpProto, "inet") == 0) {
+        if (inet_pton(AF_INET, cpHost, &sa4.sin_addr.s_addr) == 1) {
             sa4.sin_family = AF_INET;
             sa4.sin_port = htons(nPort);
-            memcpy(&sa4.sin_addr.s_addr, he->h_addr_list[0], sizeof(sa4.sin_addr.s_addr));
             sa = (struct sockaddr *)&sa4;
             sl = sizeof(sa4);
             sf = AF_INET;
         }
 #ifdef AF_INET6
-        else if (he->h_addrtype == AF_INET6) {
+        else if (inet_pton(AF_INET6, cpHost, &sa6.sin6_addr.s6_addr) == 1) {
             sa6.sin6_family = AF_INET6;
             sa6.sin6_port = htons(nPort);
-            memcpy(&sa6.sin6_addr.s6_addr, he->h_addr_list[0], sizeof(sa6.sin6_addr.s6_addr));
             sa = (struct sockaddr *)&sa6;
             sl = sizeof(sa6);
             sf = AF_INET6;
         }
 #endif
+        else if ((he = gethostbyname(cpHost)) != NULL) {
+            if (he->h_addrtype == AF_INET) {
+                sa4.sin_family = AF_INET;
+                sa4.sin_port = htons(nPort);
+                memcpy(&sa4.sin_addr.s_addr, he->h_addr_list[0], sizeof(sa4.sin_addr.s_addr));
+                sa = (struct sockaddr *)&sa4;
+                sl = sizeof(sa4);
+                sf = AF_INET;
+            }
+#ifdef AF_INET6
+            else if (he->h_addrtype == AF_INET6) {
+                sa6.sin6_family = AF_INET6;
+                sa6.sin6_port = htons(nPort);
+                memcpy(&sa6.sin6_addr.s6_addr, he->h_addr_list[0], sizeof(sa6.sin6_addr.s6_addr));
+                sa = (struct sockaddr *)&sa6;
+                sl = sizeof(sa6);
+                sf = AF_INET6;
+            }
+#endif
+        }
     }
     if (sa == NULL)
         return SA_ERR_ARG;
@@ -336,17 +360,16 @@
     memcpy(saa->saBuf, sa, sl);
     saa->slBuf = sl;
     saa->nFamily = sf;
-    saa->nProto = nProto;
     return SA_OK;
 }
 
 sa_rc_t sa_addr_s2a(sa_addr_t *saa, const struct sockaddr *sabuf, socklen_t salen)
 {
+    struct sockaddr_un *un;
     struct sockaddr_in *sa4;
 #ifdef AF_INET6
     struct sockaddr_in6 *sa6;
 #endif
-    struct protoent *pe;
     int sf;
 
     if (saa == NULL || sabuf == NULL || salen == 0)
@@ -360,32 +383,34 @@
 
     /* fill in family */
     sf = 0;
-    if (sizeof(struct sockaddr_in) == salen) {
+    if (sizeof(struct sockaddr_un) == salen) {
+        un = (struct sockaddr_un *)((void *)sabuf);
+        if (un->sun_family == AF_LOCAL)
+            sf = AF_LOCAL;
+    }
+    if (sf == 0 && sizeof(struct sockaddr_in) == salen) {
         sa4 = (struct sockaddr_in *)((void *)sabuf);
         if (sa4->sin_family == AF_INET)
             sf = AF_INET;
     }
 #ifdef AF_INET6
-    else if (sizeof(struct sockaddr_in6) == salen) {
+    if (sf == 0 && sizeof(struct sockaddr_in6) == salen) {
         sa6 = (struct sockaddr_in6 *)((void *)sabuf);
         if (sa6->sin6_family == AF_INET6)
             sf = AF_INET6;
     }
 #endif
+    if (sf == 0)
+        return SA_ERR_ARG;
     saa->nFamily = sf;
 
-    /* fill in protocol */
-    if ((pe = getprotobyname("tcp")) != NULL)
-        saa->nProto = pe->p_proto;
-    else
-        saa->nProto = 0;
     return SA_OK;
 }
 
 sa_rc_t sa_addr_a2u(sa_addr_t *saa, char **uri)
 {
     char uribuf[1024];
-    struct protoent *pe;
+    struct sockaddr_un *un;
     struct sockaddr_in *sa4;
 #ifdef AF_INET6
     struct sockaddr_in6 *sa6;
@@ -395,23 +420,27 @@
 
     if (saa == NULL || uri == NULL)
         return SA_ERR_ARG;
-    if ((pe = getprotobynumber(saa->nProto)) == NULL)
-        return SA_ERR_SYS;
-    if (saa->nFamily == AF_INET) {
-        sa4 = (struct sockaddr_in *)((void *)saa->saBuf);
-        inet_ntop(AF_INET, &sa4->sin_addr.s_addr, caHost, sizeof(caHost));
-        nPort = ntohs(sa4->sin_port);
+    if (saa->nFamily == AF_LOCAL) {
+        un = (struct sockaddr_un *)((void *)saa->saBuf);
+        sa_msnprintf(uribuf, sizeof(uribuf), "unix:%s", un->sun_path);
     }
+    else {
+        if (saa->nFamily == AF_INET) {
+            sa4 = (struct sockaddr_in *)((void *)saa->saBuf);
+            inet_ntop(AF_INET, &sa4->sin_addr.s_addr, caHost, sizeof(caHost));
+            nPort = ntohs(sa4->sin_port);
+        }
 #ifdef AF_INET6
-    else if (saa->nFamily == AF_INET6) {
-        sa6 = (struct sockaddr_in6 *)((void *)saa->saBuf);
-        inet_ntop(AF_INET6, &sa6->sin6_addr.s6_addr, caHost, sizeof(caHost));
-        nPort = ntohs(sa6->sin6_port);
-    }
+        else if (saa->nFamily == AF_INET6) {
+            sa6 = (struct sockaddr_in6 *)((void *)saa->saBuf);
+            inet_ntop(AF_INET6, &sa6->sin6_addr.s6_addr, caHost, sizeof(caHost));
+            nPort = ntohs(sa6->sin6_port);
+        }
 #endif
-    else
-        return SA_ERR_ARG;
-    sa_msnprintf(uribuf, sizeof(uribuf), "%s://%s:%d", pe->p_name, caHost, nPort);
+        else
+            return SA_ERR_ARG;
+        sa_msnprintf(uribuf, sizeof(uribuf), "inet://%s:%d", caHost, nPort);
+    }
     *uri = strdup(uribuf);
     return SA_OK;
 }
@@ -428,22 +457,53 @@
     return SA_OK;
 }
 
-static sa_rc_t sa_socket_init(sa_t *sa, int family, int proto)
+static sa_rc_t sa_socket_init(sa_t *sa, int nFamily)
 {
-    int type;
+    int nType;
+    int nProto;
+    struct protoent *pe;
+    char *cpProto;
 
     if (sa == NULL)
         return SA_ERR_ARG;
-    if (proto == IPPROTO_TCP)
-        type = SOCK_STREAM;
-    else if (proto == IPPROTO_UDP)
-        type = SOCK_DGRAM;
-    else
-        return SA_ERR_ARG;
+
+    /* only perform operation if socket still do not exists */
     if (sa->sSocket != -1)
         return SA_ERR_USE;
-    if ((sa->sSocket = socket(family, type, proto)) == -1)
+
+    /* determine socket type */
+    if (sa->eType == SA_TYPE_STREAM)
+        nType = SOCK_STREAM;
+    else if (sa->eType == SA_TYPE_DATAGRAM)
+        nType = SOCK_DGRAM;
+    else
+        return SA_ERR_ARG;
+
+    /* determine socket protocol */
+    if (nFamily == AF_LOCAL) 
+        nProto = 0;
+#ifdef AF_INET6
+    else if (nFamily == AF_INET || nFamily == AF_INET6) {
+#else
+    else if (nFamily == AF_INET) {
+#endif
+        if (nType == SOCK_STREAM)
+            cpProto = "tcp";
+        else if (nType == SOCK_DGRAM)
+            cpProto = "udp";
+        else
+            return SA_ERR_INT;
+        if ((pe = getprotobyname(cpProto)) == NULL)
+            return SA_ERR_SYS;
+        nProto = pe->p_proto;
+    }
+    else
+        return SA_ERR_ARG;
+
+    /* create the socket */
+    if ((sa->sSocket = socket(nFamily, nType, nProto)) == -1)
         return SA_ERR_SYS;
+
     return SA_OK;
 }
 
@@ -464,6 +524,7 @@
 
     if ((sa = (sa_t *)malloc(sizeof(sa_t))) == NULL)
         return SA_ERR_MEM;
+    sa->eType      = SA_TYPE_STREAM;
     sa->sSocket    = -1;
     sa->bTimeout   = 0;
     sa->nReadLen   = 0;
@@ -496,6 +557,16 @@
     return SA_OK;
 }
 
+sa_rc_t sa_type(sa_t *sa, sa_type_t type)
+{
+    if (sa == NULL)
+        return SA_ERR_ARG;
+    if (type != SA_TYPE_STREAM && type != SA_TYPE_DATAGRAM)
+        return SA_ERR_ARG;
+    sa->eType = type;
+    return SA_OK;
+}
+
 sa_rc_t sa_timeout(sa_t *sa, long sec, long usec)
 {
     if (sa == NULL)
@@ -557,12 +628,17 @@
 sa_rc_t sa_bind(sa_t *sa, sa_addr_t *laddr)
 {
     sa_rc_t rv;
+    struct sockaddr_un *un;
 
     if (sa == NULL || laddr == NULL)
         return SA_ERR_ARG;
     if (sa->sSocket == -1)
-        if ((rv = sa_socket_init(sa, laddr->nFamily, laddr->nProto)) != SA_OK)
+        if ((rv = sa_socket_init(sa, laddr->nFamily)) != SA_OK)
             return rv;
+    if (laddr->nFamily == AF_LOCAL) {
+        un = (struct sockaddr_un *)((void *)laddr->saBuf);
+        unlink(un->sun_path);
+    }
     if (bind(sa->sSocket, laddr->saBuf, laddr->slBuf) == -1)
         return SA_ERR_SYS;
     return SA_OK;
@@ -577,9 +653,10 @@
 
     if (sa == NULL)
         return SA_ERR_ARG;
-
+    if (sa->eType != SA_TYPE_STREAM)
+        return SA_ERR_USE;
     if (sa->sSocket == -1)
-        if ((rv = sa_socket_init(sa, raddr->nFamily, raddr->nProto)) != SA_OK)
+        if ((rv = sa_socket_init(sa, raddr->nFamily)) != SA_OK)
             return rv;
 
     if (!sa->bTimeout)
@@ -648,6 +725,8 @@
 {
     if (sa == NULL)
         return SA_ERR_ARG;
+    if (sa->eType != SA_TYPE_STREAM)
+        return SA_ERR_USE;
     if (sa->sSocket == -1)
         /* at least sa_bind() has to be already performed */
         return SA_ERR_USE;
@@ -672,6 +751,8 @@
 
     if (sa == NULL)
         return SA_ERR_ARG;
+    if (sa->eType != SA_TYPE_STREAM)
+        return SA_ERR_USE;
     if (sa->sSocket == -1)
         /* at least sa_listen() has to be already performed */
         return SA_ERR_USE;
@@ -717,6 +798,8 @@
     if (sa == NULL)
         return SA_ERR_ARG;
     sa_len = sizeof(sa_buf);
+    if (sa->sSocket == -1)
+        return SA_ERR_USE;
     if (getpeername(sa->sSocket, (struct sockaddr *)&sa_buf, &sa_len) < 0)
         return SA_ERR_SYS;
     if ((rv = sa_addr_create(raddr)) != SA_OK)
@@ -741,6 +824,8 @@
 
     if (sa == NULL)
         return SA_ERR_ARG;
+    if (sa->sSocket == -1)
+        return SA_ERR_USE;
     sa_len = sizeof(sa_buf);
     if (getsockname(sa->sSocket, (struct sockaddr *)&sa_buf, &sa_len) < 0)
         return SA_ERR_SYS;
@@ -757,6 +842,8 @@
 {
     if (sa == NULL || fd == NULL)
         return SA_ERR_ARG;
+    if (sa->sSocket == -1)
+        return SA_ERR_USE;
     *fd = sa->sSocket;
     return SA_OK;
 }
@@ -790,8 +877,12 @@
     size_t res;
 
     if (sa == NULL || cpBuf == NULL || nBufReq == 0)
-        return 0;
-    
+        return SA_ERR_ARG;
+    if (sa->eType != SA_TYPE_STREAM)
+        return SA_ERR_USE;
+    if (sa->sSocket == -1)
+        return SA_ERR_USE;
+
     /* flush write buffer */
     if (sa->nWriteLen > 0)
         sa_flush(sa);
@@ -855,6 +946,10 @@
 
     if (sa == NULL || buf == NULL || buflen == 0 || raddr == NULL)
         return SA_ERR_ARG;
+    if (sa->eType != SA_TYPE_DATAGRAM)
+        return SA_ERR_USE;
+    if (sa->sSocket == -1)
+        return SA_ERR_USE;
     if (sa->bTimeout) {
         FD_ZERO(&fds);
         FD_SET(sa->sSocket, &fds);
@@ -888,6 +983,10 @@
 
     if (sa == NULL)
         return SA_ERR_ARG;
+    if (sa->eType != SA_TYPE_STREAM)
+        return SA_ERR_USE;
+    if (sa->sSocket == -1)
+        return SA_ERR_USE;
     res = 0;
     while (res < (nBufReq-1)) {
         sa_read(sa, &c, 1, &n);
@@ -932,6 +1031,10 @@
 
     if (sa == NULL)
         return SA_ERR_ARG;
+    if (sa->eType != SA_TYPE_STREAM)
+        return SA_ERR_USE;
+    if (sa->sSocket == -1)
+        return SA_ERR_USE;
 
     if (nBufReq > (sa->nWriteSize - sa->nWriteLen)) {
         /* not enough space in buffer, so flush buffer */
@@ -964,9 +1067,17 @@
 {
     size_t n;
     fd_set fds;
+    sa_rc_t rv;
 
     if (sa == NULL || buf == NULL || buflen == 0 || raddr == NULL)
         return SA_ERR_ARG;
+    if (sa->eType != SA_TYPE_DATAGRAM)
+        return SA_ERR_USE;
+    if (sa->sSocket == -1)
+        if ((rv = sa_socket_init(sa, raddr->nFamily)) != SA_OK)
+            return rv;
+    if (sa->sSocket == -1)
+        return SA_ERR_USE;
     if (sa->bTimeout) {
         FD_ZERO(&fds);
         FD_SET(sa->sSocket, &fds);
@@ -1006,6 +1117,10 @@
 
     if (sa == NULL)
         return SA_ERR_ARG;
+    if (sa->eType != SA_TYPE_STREAM)
+        return SA_ERR_USE;
+    if (sa->sSocket == -1)
+        return SA_ERR_USE;
     while (sa->nWriteLen > 0) {
         n = sa_write_raw(sa, sa->cpWriteBuf, sa->nWriteLen);
         if (n <= 0)
@@ -1023,6 +1138,10 @@
 
     if (sa == NULL || flags == NULL)
         return SA_ERR_ARG;
+    if (sa->eType != SA_TYPE_STREAM)
+        return SA_ERR_USE;
+    if (sa->sSocket == -1)
+        return SA_ERR_USE;
     how = 0;
     if (strcmp(flags, "r") == 0)
         how = SHUT_RD;

CVSTrac 2.0.1