*** /dev/null Sat Nov 23 01:08:19 2024
--- - Sat Nov 23 01:08:19 2024
***************
*** 0 ****
--- 1,182 ----
+ /*
+ * sa.c: Socket Address library (implementation)
+ *
+ * Copyright (c) 2001 The OSSP Project (http://www.ossp.org/)
+ * Copyright (c) 2001 Cable & Wireless Deutschland (http://www.cw.com/de/)
+ *
+ * This file is part of OSSP lmtp2nntp, an LMTP speaking local
+ * mailer which forwards mails as Usenet news articles via NNTP.
+ * It can be found at http://www.ossp.com/pkg/lmtp2nntp/.
+ *
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose with or without fee is hereby granted, provided that
+ * the above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <stdarg.h>
+ #include <string.h>
+ #include <unistd.h>
+ #include <ctype.h>
+ #include <errno.h>
+ #include <netdb.h>
+ #include <sys/types.h>
+ #include <sys/un.h>
+ #include <netinet/in.h>
+ #include <sys/socket.h>
+ #include <arpa/inet.h>
+
+ #include "sa.h"
+
+ sa_t *sa_create(int sa_type, ...)
+ {
+ va_list ap;
+ sa_t *rc;
+ int nPort;
+ socklen_t sl;
+ struct sockaddr *sa;
+ struct sockaddr_in sa4;
+ struct sockaddr_in6 sa6;
+ struct sockaddr_un sau;
+ struct hostent *he;
+ struct servent *se;
+ struct protoent *pe;
+ int bNumeric;
+ int i;
+ char *cpPath;
+ int nPath;
+ char *cpProto;
+ int nProto;
+ char *cpHost;
+ char *cpPort;
+
+ va_start(ap, sa_type);
+ sa = NULL;
+ sl = 0;
+ if (sa_type == SA_UNIX) {
+ if ((cpPath = va_arg(ap, char *)) == NULL)
+ return NULL;
+ if ((nPath = strlen(cpPath)) >= (sizeof(sau.sun_path)-1))
+ return NULL;
+ nProto = 0;
+ sau.sun_family = AF_LOCAL;
+ memcpy(sau.sun_path, cpPath, nPath + 1);
+ sa = (struct sockaddr *)&sau;
+ sl = sizeof(sau);
+ }
+ else if (sa_type == SA_IP) {
+ if ((cpProto = va_arg(ap, char *)) == NULL)
+ return NULL;
+ if ((cpHost = va_arg(ap, char *)) == NULL)
+ return NULL;
+ if ((cpPort = va_arg(ap, char *)) == NULL)
+ return NULL;
+
+ /* resolve protocol */
+ if ((pe = getprotobyname(cpProto)) == NULL)
+ return NULL;
+ nProto = pe->p_proto;
+
+ /* resolve port */
+ bNumeric = 1;
+ for (i = 0; cpPort[i] != '\0'; i++) {
+ if (!isdigit(cpPort[i])) {
+ bNumeric = 0;
+ break;
+ }
+ }
+ if (bNumeric)
+ nPort = atoi(cpPort);
+ else {
+ if ((se = getservbyname(cpPort, cpProto)) == NULL)
+ return NULL;
+ nPort = ntohs(se->s_port);
+ }
+
+ /* resolve host */
+ 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);
+ }
+ 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);
+ }
+ 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);
+ }
+ 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);
+ }
+ }
+ }
+ else
+ return NULL;
+ va_end(ap);
+
+ if (sa == NULL)
+ return NULL;
+
+ if ((rc = (sa_t *)malloc(sizeof(sa_t))) == NULL)
+ return NULL;
+ if ((rc->sa_buf = (struct sockaddr *)malloc(sl)) == NULL) {
+ free(rc);
+ return NULL;
+ }
+ memcpy(rc->sa_buf, sa, sl);
+ rc->sa_len = sl;
+ rc->sa_proto = nProto;
+
+ /* create socket
+ * if ((s = socket(rc->sa_buf->sa_family, SOCK_STREAM, rc->sa_proto)) == -1)
+ * return NULL;
+ */
+
+ /* connect socket to remote host/port
+ *
+ * if (connect(s, rc->sa_buf, rc->sa_len) < 0)
+ * return -1;
+ */
+ return rc;
+ }
+
+ void sa_destroy(sa_t *sa)
+ {
+ if (sa == NULL)
+ return;
+
+ if (sa->sa_buf != NULL)
+ free(sa->sa_buf);
+
+ free(sa);
+ return;
+ }
+
|