Index: ossp-pkg/sa/Makefile.in RCS File: /v/ossp/cvs/ossp-pkg/sa/Makefile.in,v rcsdiff -q -kk '-r1.2' '-r1.3' -u '/v/ossp/cvs/ossp-pkg/sa/Makefile.in,v' 2>/dev/null --- Makefile.in 2001/10/02 18:37:19 1.2 +++ Makefile.in 2001/10/05 11:40:22 1.3 @@ -67,7 +67,7 @@ @$(LIBTOOL) --mode=link $(CC) -o $(LIB_NAME) $(LIB_OBJS) -rpath $(libdir) \ -version-info `$(SHTOOL) version -l txt -d libtool VERSION` -$(TST_NAME): $(TST_OBJS) +$(TST_NAME): $(TST_OBJS) $(LIB_NAME) @$(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $(TST_NAME) $(TST_OBJS) $(LIB_NAME) $(LIBS) check: $(TST_NAME) Index: ossp-pkg/sa/TODO RCS File: /v/ossp/cvs/ossp-pkg/sa/TODO,v rcsdiff -q -kk '-r1.2' '-r1.3' -u '/v/ossp/cvs/ossp-pkg/sa/TODO,v' 2>/dev/null --- TODO 2001/10/04 11:25:44 1.2 +++ TODO 2001/10/05 11:40:22 1.3 @@ -10,7 +10,3 @@ buffer == 0 -> fully unbuffered timeout == 0 -> fully blocking -- Unix domain sockets support -- aufpassen dasz fuer read/write STREAM socket ist -- aufpassen dasz fuer readfrom/writeto DGRAM socket ist - Index: ossp-pkg/sa/sa.c RCS File: /v/ossp/cvs/ossp-pkg/sa/sa.c,v rcsdiff -q -kk '-r1.3' '-r1.4' -u '/v/ossp/cvs/ossp-pkg/sa/sa.c,v' 2>/dev/null --- 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; Index: ossp-pkg/sa/sa.h RCS File: /v/ossp/cvs/ossp-pkg/sa/sa.h,v rcsdiff -q -kk '-r1.4' '-r1.5' -u '/v/ossp/cvs/ossp-pkg/sa/sa.h,v' 2>/dev/null --- sa.h 2001/10/04 11:25:44 1.4 +++ sa.h 2001/10/05 11:40:22 1.5 @@ -82,6 +82,12 @@ struct sa_st; typedef struct sa_st sa_t; +/* socket connection types */ +typedef enum { + SA_TYPE_STREAM, + SA_TYPE_DATAGRAM +} sa_type_t; + /* return codes */ typedef enum { SA_OK, @@ -107,6 +113,7 @@ sa_rc_t sa_destroy (sa_t *sa); /* socket parameter operations */ +sa_rc_t sa_type (sa_t *sa, sa_type_t type); sa_rc_t sa_timeout (sa_t *sa, long sec, long usec); sa_rc_t sa_buffers (sa_t *sa, size_t rsize, size_t wsize); sa_rc_t sa_getoption (sa_t *sa, int optname, void *optval, socklen_t *optlen); Index: ossp-pkg/sa/sa_test.c RCS File: /v/ossp/cvs/ossp-pkg/sa/sa_test.c,v rcsdiff -q -kk '-r1.2' '-r1.3' -u '/v/ossp/cvs/ossp-pkg/sa/sa_test.c,v' 2>/dev/null --- sa_test.c 2001/10/04 11:04:59 1.2 +++ sa_test.c 2001/10/05 11:40:22 1.3 @@ -8,8 +8,6 @@ #include "sa.h" -/* see RFC3164 */ - static void die(char *fmt, ...) { va_list ap; @@ -38,21 +36,32 @@ char *cpHost; int n; - if (sa_u2a(&ra, "udp://%s:514", argv[1]) != SA_OK) - die("sa_u2a ra"); - if (sa_u2a(&la, "udp://0.0.0.0:0") != SA_OK) - die("sa_u2a la"); + /* create remote address */ + if (sa_addr_create(&ra) != SA_OK) + die("sa_addr_create (ra)"); + if (sa_addr_u2a(ra, "inet://141.1.129.1:514") != SA_OK) + die("sa_addr_u2a (ra)"); + + /* create local address */ + if (sa_addr_create(&la) != SA_OK) + die("sa_addr_create (la)"); + if (sa_addr_u2a(la, "inet://0.0.0.0:0") != SA_OK) + die("sa_addr_u2a (la)"); + + /* create datagram socket */ if (sa_create(&sa) != SA_OK) die("sa_create"); + if (sa_type(sa, SA_TYPE_DATAGRAM) != SA_OK) + die("sa_type"); + + /* bind socket to local address */ if (sa_bind(sa, la) != SA_OK) die("sa_bind"); /* RFC3164: The BSD syslog Protocol; C. Lonvick; August 2001. */ - now = time(NULL); tm = localtime(&now); strftime(caTime, sizeof(caTime), "%b %e %H:%M:%S", tm); - if (uname(&uts) == 0) { cpHost = strdup(uts.nodename); if ((cp = strchr(cpHost, '.')) != NULL) @@ -60,20 +69,23 @@ } else cpHost = strdup("0.0.0.0"); /* FIXME */ - strcpy(caTag, "progname[12]: "); if (strlen(caTag) > 32) caTag[32] = '\0'; - - sprintf(caBuf, "<%d>%s %s %s%s", LOG_MAIL|LOG_EMERG, caTime, cpHost, caTag, argv[2]); + sprintf(caBuf, "<%d>%s %s %s%s", LOG_MAIL|LOG_EMERG, caTime, cpHost, caTag, "test"); fprintf(stderr, "%s\n", caBuf); nBuf = strlen(caBuf); if (sa_writeto(sa, caBuf, nBuf, (size_t *)&n, ra) != SA_OK) die("sa_writeto"); + + /* destroy socket and address objects */ if (sa_destroy(sa) != SA_OK) die("sa_destroy"); - free(ra); - free(la); + if (sa_addr_destroy(la) != SA_OK) + die("sa_addr_destroy (la)"); + if (sa_addr_destroy(ra) != SA_OK) + die("sa_addr_destroy (ra)"); + return 0; }