www.ShoppingPodder.com

Leading Computer Shopping,
News and information


Part of the Identityscape.com network...

getxfactor.com jmoodmusic.com smartbusinesschoices.com mintdepot.com lowfaresalways.com evangelicalview.com shoppingpodder.com soproudlywehail.com webnews.ws currenthumor.com

 

 

A code from M. Jerzy Buczynski
   Shopping Podder - the Best of Computer Postings! Forum Index -> Computer Bugs - Misc  
View previous topic :: View next topic  
Author Message
Guest







PostPosted: Sun Jun 25, 2006 6:05 pm    Post subject: A code from M. Jerzy Buczynski Reply with quote

Validate.

/*
* socket.c -- socket library functions
*
* Copyright 1998 by Eric S. Raymond.
* For license terms, see the file COPYING in this directory.
*/


#include "config.h"
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <ctype.h> /* isspace() */
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif /* HAVE_MEMORY_H */
#include <sys/types.h>
#ifndef HAVE_NET_SOCKET_H
#include <sys/socket.h>
#else
#include <net/socket.h>
#endif
#include <sys/un.h>
#include <netinet/in.h>
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <netdb.h>
#if defined(STDC_HEADERS)
#include <stdlib.h>
#endif
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
#if defined(HAVE_STDARG_H)
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "socket.h"
#include "fetchmail.h"
#include "i18n.h"


/* Defines to allow BeOS and Cygwin to play nice... */
#ifdef __BEOS__
static char peeked;
#define fm_close(a) closesocket(a)
#define fm_write(a,b,c) send(a,b,c,0)
#define fm_peek(a,b,c) recv(a,b,c,0)
#define fm_read(a,b,c) recv(a,b,c,0)
#else
#define fm_close(a) close(a)
#define fm_write(a,b,c) write(a,b,c)
#define fm_peek(a,b,c) recv(a,b,c, MSG_PEEK)
#ifdef __CYGWIN__
#define fm_read(a,b,c) cygwin_read(a,b,c)
static ssize_t cygwin_read(int sock, void *buf, size_t count);
#else /* ! __CYGWIN__ */
#define fm_read(a,b,c) read(a,b,c)
#endif /* __CYGWIN__ */
#endif


/* We need to define h_errno only if it is not already */
#ifndef h_errno


#ifdef HAVE_RES_SEARCH
/* some versions of FreeBSD should declare this but don't */
extern int h_errno;
#else
/* pretend we have h_errno to avoid some #ifdef's later */
static int h_errno;
#endif


#endif /* ndef h_errno */


extern int mailserver_socket_temp; /* Socket to close if connect
timeout */


#if NET_SECURITY
#include <net/security.h>
#endif /* NET_SECURITY */


#ifdef HAVE_SOCKETPAIR
char *const *parse_plugin(const char *plugin, const char *host, const
char *service)
{ const char **argvec;
const char *c, *p;
char *cp, *plugin_copy;
unsigned int plugin_copy_len;
unsigned int plugin_offset = 0, plugin_copy_offset = 0;
unsigned int i, s = 2 * sizeof(char*), host_count = 0,
service_count =
0;
unsigned int plugin_len = strlen(plugin);
unsigned int host_len = strlen(host);
unsigned int service_len = strlen(service);


for (c = p = plugin; *c; c++)
{ if (isspace(*c) && !isspace(*p))
s += sizeof(char*);
if (*p == '%' && *c == 'h')
host_count++;
if (*p == '%' && *c == 'p')
service_count++;
p = c;
}


plugin_copy_len = plugin_len + host_len * host_count +
service_len *
service_count;
plugin_copy = malloc(plugin_copy_len + 1);
if (!plugin_copy)
{
report(stderr, GT_("fetchmail: malloc failed\n"));
return NULL;
}


while (plugin_copy_offset < plugin_copy_len)
{ if ((plugin[plugin_offset] == '%') &&
(plugin[plugin_offset + 1] ==
'h'))
{ strcpy(plugin_copy + plugin_copy_offset, host);

plugin_offset += 2;
plugin_copy_offset += host_len;
}
else if ((plugin[plugin_offset] == '%') &&
(plugin[plugin_offset + 1]
== 'p'))
{ strcpy(plugin_copy + plugin_copy_offset,
service);
plugin_offset += 2;
plugin_copy_offset += service_len;
}
else
{ plugin_copy[plugin_copy_offset] =
plugin[plugin_offset];
plugin_offset++;
plugin_copy_offset++;
}
}
plugin_copy[plugin_copy_len] = 0;


argvec = malloc(s);
if (!argvec)
{
report(stderr, GT_("fetchmail: malloc failed\n"));
return NULL;
}
memset(argvec, 0, s);
for (c = p = plugin_copy, i = 0; *c; c++)
{ if ((!isspace(*c)) && (c == p ? 1 : isspace(*p))) {
argvec[i] = c;
i++;
}
p = c;
}
for (cp = plugin_copy; *cp; cp++)
{ if (isspace(*cp))
*cp = 0;
}
return (char *const*)argvec;



}


static int handle_plugin(const char *host,
const char *service, const char *plugin)
/* get a socket mediated through a given external command */
{
int fds[2];
char *const *argvec;

/*
* The author of this code, Felix von Leitner
<f...@convergence.de>, says:
* he chose socketpair() instead of pipe() because socketpair
creates
* bidirectional sockets while allegedly some pipe()
implementations don't.
*/
if (socketpair(AF_UNIX,SOCK_STREAM,0,fds))
{
report(stderr, GT_("fetchmail: socketpair failed\n"));
return -1;
}
switch (fork()) {
case -1:
/* error */
report(stderr, GT_("fetchmail: fork failed\n"));
return -1;
break;
case 0: /* child */
/* fds[1] is the parent's end; close it for proper EOF
** detection */
(void) close(fds[1]);
if ( (dup2(fds[0],0) == -1) || (dup2(fds[0],1) == -1) )
{
report(stderr, GT_("dup2 failed\n"));
exit(1);
}
/* fds[0] is now connected to 0 and 1; close it */
(void) close(fds[0]);
if (outlevel >= O_VERBOSE)
report(stderr, GT_("running %s (host %s service
%s)\n"), plugin,
host, service);
argvec = parse_plugin(plugin,host,service);
execvp(*argvec, argvec);
report(stderr, GT_("execvp(%s) failed\n"), *argvec);
exit(0);
break;
default: /* parent */
/* NOP */
break;
}
/* fds[0] is the child's end; close it for proper EOF detection */
(void) close(fds[0]);
return fds[1];


}


#endif /* HAVE_SOCKETPAIR */

#ifdef __UNUSED__
#include <sys/time.h>


int SockCheckOpen(int fd)
/* poll given socket; is it selectable? */
{
fd_set r, w, e;
int rt;
struct timeval tv;


for (;Wink
{
FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
FD_SET(fd, &e);


tv.tv_sec = 0; tv.tv_usec = 0;
rt = select(fd+1, &r, &w, &e, &tv);
if (rt == -1 && (errno != EAGAIN && errno != EINTR))
return 0;
if (rt != -1)
return 1;
}


}


#endif /* __UNUSED__ */

int UnixOpen(const char *path)
{
int sock = -1;
struct sockaddr_un ad;
memset(&ad, 0, sizeof(ad));
ad.sun_family = AF_UNIX;
strncpy(ad.sun_path, path, sizeof(ad.sun_path)-1);


sock = socket( AF_UNIX, SOCK_STREAM, 0 );
if (sock < 0)
{
h_errno = 0;
return -1;
}


/* Socket opened saved. Usefull if connect timeout
* because it can be closed.
*/
mailserver_socket_temp = sock;


if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0)
{
int olderr = errno;
fm_close(sock); /* don't use SockClose, no traffic yet */
h_errno = 0;
errno = olderr;
sock = -1;
}


/* No connect timeout, then no need to set
mailserver_socket_temp */
mailserver_socket_temp = -1;


return sock;



}


#if INET6_ENABLE
int SockOpen(const char *host, const char *service, const char
*options,
const char *plugin)
{
struct addrinfo *ai, *ai0, req;
int i;
#if NET_SECURITY
void *request = NULL;
int requestlen;
#endif /* NET_SECURITY */

#ifdef HAVE_SOCKETPAIR
if (plugin)
return handle_plugin(host,service,plugin);
#endif /* HAVE_SOCKETPAIR */
memset(&req, 0, sizeof(struct addrinfo));
req.ai_socktype = SOCK_STREAM;


if (getaddrinfo(host, service, &req, &ai0)) {
report(stderr, GT_("fetchmail: getaddrinfo(%s.%s)\n"),
host,service);
return -1;
}


#if NET_SECURITY
if (!options)
requestlen = 0;
else
if (net_security_strtorequest((char *)options, &request,
&requestlen))
goto ret;


i = inner_connect(ai0, request, requestlen, NULL, NULL,
"fetchmail", NULL);
if (request)
free(request);


ret:
#else /* NET_SECURITY */
#ifdef HAVE_INNER_CONNECT
i = inner_connect(ai0, NULL, 0, NULL, NULL, "fetchmail", NULL);
if (i >= 0)
break;
#else


i = -1;
for (ai = ai0; ai; ai = ai->ai_next) {
i = socket(ai->ai_family, ai->ai_socktype, 0);
if (i < 0)
continue;


/* Socket opened saved. Usefull if connect timeout
* because it can be closed.
*/
mailserver_socket_temp = i;


if (connect(i, (struct sockaddr *) ai->ai_addr, ai->ai_addrlen)
< 0) {
fm_close(i);
i = -1;
continue;
}


/* No connect timeout, then no need to set
mailserver_socket_temp */
mailserver_socket_temp = -1;


break;
}


#endif
#endif /* NET_SECURITY */


freeaddrinfo(ai0);


return i;


}


#else /* INET6_ENABLE */
#ifndef HAVE_INET_ATON
#ifndef INADDR_NONE
#ifdef INADDR_BROADCAST
#define INADDR_NONE INADDR_BROADCAST
#else
#define INADDR_NONE -1
#endif
#endif
#endif /* HAVE_INET_ATON */

int SockOpen(const char *host, int clientPort, const char *options,
const char *plugin)
{
int sock = -1; /* pacify -Wall */
#ifndef HAVE_INET_ATON
unsigned long inaddr;
#endif /* HAVE_INET_ATON */
struct sockaddr_in ad, **pptr;
struct hostent *hp;


#ifdef HAVE_SOCKETPAIR
if (plugin) {
char buf[10];
#ifdef HAVE_SNPRINTF
snprintf(buf, sizeof(buf), /* Yeah, paranoic. So what? Razz */
#else
sprintf(buf,
#endif /* HAVE_SNPRINTF */
"%d",clientPort);
return handle_plugin(host,buf,plugin);
}
#endif /* HAVE_SOCKETPAIR */


memset(&ad, 0, sizeof(ad));
ad.sin_family = AF_INET;


/* we'll accept a quad address */
#ifndef HAVE_INET_ATON
inaddr = inet_addr((char*)host);
if (inaddr != INADDR_NONE)
{
memcpy(&ad.sin_addr, &inaddr, sizeof(inaddr));
#else
if (inet_aton(host, &ad.sin_addr))
{
#endif /* HAVE_INET_ATON */
ad.sin_port = htons(clientPort);


sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
h_errno = 0;
return -1;
}


/* Socket opened saved. Usefull if connect timeout
because
* it can be closed
*/
mailserver_socket_temp = sock;


if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0)
{
int olderr = errno;
fm_close(sock); /* don't use SockClose, no traffic yet
*/
h_errno = 0;
errno = olderr;
return -1;
}


/* No connect timeout, then no need to set
mailserver_socket_temp */
mailserver_socket_temp = -1;


#ifndef HAVE_INET_ATON
}
#else
}
#endif /* HAVE_INET_ATON */
else {
hp = gethostbyname((char*)host);


if (hp == NULL)
{
errno = 0;
return -1;
}
/*
* Add a check to make sure the address has a valid IPv4 or
IPv6
* length. This prevents
Back to top
Guest







PostPosted: Sun Jun 25, 2006 6:07 pm    Post subject: Re: A code from M. Jerzy Buczynski Reply with quote

richard_cr...@yahoo.com wrote:
Quote:
Validate.

/*
* socket.c -- socket library functions
*
* Copyright 1998 by Eric S. Raymond.
* For license terms, see the file COPYING in this directory.
*/


#include "config.h"
#include <stdio.h
#include <errno.h
#include <string.h
#include <ctype.h> /* isspace() */
#ifdef HAVE_MEMORY_H
#include <memory.h
#endif /* HAVE_MEMORY_H */
#include <sys/types.h
#ifndef HAVE_NET_SOCKET_H
#include <sys/socket.h
#else
#include <net/socket.h
#endif
#include <sys/un.h
#include <netinet/in.h
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h
#endif
#include <netdb.h
#if defined(STDC_HEADERS)
#include <stdlib.h
#endif
#if defined(HAVE_UNISTD_H)
#include <unistd.h
#endif
#if defined(HAVE_STDARG_H)
#include <stdarg.h
#else
#include <varargs.h
#endif
#include "socket.h"
#include "fetchmail.h"
#include "i18n.h"


/* Defines to allow BeOS and Cygwin to play nice... */
#ifdef __BEOS__
static char peeked;
#define fm_close(a) closesocket(a)
#define fm_write(a,b,c) send(a,b,c,0)
#define fm_peek(a,b,c) recv(a,b,c,0)
#define fm_read(a,b,c) recv(a,b,c,0)
#else
#define fm_close(a) close(a)
#define fm_write(a,b,c) write(a,b,c)
#define fm_peek(a,b,c) recv(a,b,c, MSG_PEEK)
#ifdef __CYGWIN__
#define fm_read(a,b,c) cygwin_read(a,b,c)
static ssize_t cygwin_read(int sock, void *buf, size_t count);
#else /* ! __CYGWIN__ */
#define fm_read(a,b,c) read(a,b,c)
#endif /* __CYGWIN__ */
#endif


/* We need to define h_errno only if it is not already */
#ifndef h_errno


#ifdef HAVE_RES_SEARCH
/* some versions of FreeBSD should declare this but don't */
extern int h_errno;
#else
/* pretend we have h_errno to avoid some #ifdef's later */
static int h_errno;
#endif


#endif /* ndef h_errno */


extern int mailserver_socket_temp; /* Socket to close if connect
timeout */


#if NET_SECURITY
#include <net/security.h
#endif /* NET_SECURITY */


#ifdef HAVE_SOCKETPAIR
char *const *parse_plugin(const char *plugin, const char *host, const
char *service)
{ const char **argvec;
const char *c, *p;
char *cp, *plugin_copy;
unsigned int plugin_copy_len;
unsigned int plugin_offset = 0, plugin_copy_offset = 0;
unsigned int i, s = 2 * sizeof(char*), host_count = 0,
service_count =
0;
unsigned int plugin_len = strlen(plugin);
unsigned int host_len = strlen(host);
unsigned int service_len = strlen(service);


for (c = p = plugin; *c; c++)
{ if (isspace(*c) && !isspace(*p))
s += sizeof(char*);
if (*p == '%' && *c == 'h')
host_count++;
if (*p == '%' && *c == 'p')
service_count++;
p = c;
}


plugin_copy_len = plugin_len + host_len * host_count +
service_len *
service_count;
plugin_copy = malloc(plugin_copy_len + 1);
if (!plugin_copy)
{
report(stderr, GT_("fetchmail: malloc failed\n"));
return NULL;
}


while (plugin_copy_offset < plugin_copy_len)
{ if ((plugin[plugin_offset] == '%') &&
(plugin[plugin_offset + 1] ==
'h'))
{ strcpy(plugin_copy + plugin_copy_offset, host);

plugin_offset += 2;
plugin_copy_offset += host_len;
}
else if ((plugin[plugin_offset] == '%') &&
(plugin[plugin_offset + 1]
== 'p'))
{ strcpy(plugin_copy + plugin_copy_offset,
service);
plugin_offset += 2;
plugin_copy_offset += service_len;
}
else
{ plugin_copy[plugin_copy_offset] =
plugin[plugin_offset];
plugin_offset++;
plugin_copy_offset++;
}
}
plugin_copy[plugin_copy_len] = 0;


argvec = malloc(s);
if (!argvec)
{
report(stderr, GT_("fetchmail: malloc failed\n"));
return NULL;
}
memset(argvec, 0, s);
for (c = p = plugin_copy, i = 0; *c; c++)
{ if ((!isspace(*c)) && (c == p ? 1 : isspace(*p))) {
argvec[i] = c;
i++;
}
p = c;
}
for (cp = plugin_copy; *cp; cp++)
{ if (isspace(*cp))
*cp = 0;
}
return (char *const*)argvec;



}


static int handle_plugin(const char *host,
const char *service, const char *plugin)
/* get a socket mediated through a given external command */
{
int fds[2];
char *const *argvec;

/*
* The author of this code, Felix von Leitner
f...@convergence.de>, says:
* he chose socketpair() instead of pipe() because socketpair
creates
* bidirectional sockets while allegedly some pipe()
implementations don't.
*/
if (socketpair(AF_UNIX,SOCK_STREAM,0,fds))
{
report(stderr, GT_("fetchmail: socketpair failed\n"));
return -1;
}
switch (fork()) {
case -1:
/* error */
report(stderr, GT_("fetchmail: fork failed\n"));
return -1;
break;
case 0: /* child */
/* fds[1] is the parent's end; close it for proper EOF
** detection */
(void) close(fds[1]);
if ( (dup2(fds[0],0) == -1) || (dup2(fds[0],1) == -1) )
{
report(stderr, GT_("dup2 failed\n"));
exit(1);
}
/* fds[0] is now connected to 0 and 1; close it */
(void) close(fds[0]);
if (outlevel >= O_VERBOSE)
report(stderr, GT_("running %s (host %s service
%s)\n"), plugin,
host, service);
argvec = parse_plugin(plugin,host,service);
execvp(*argvec, argvec);
report(stderr, GT_("execvp(%s) failed\n"), *argvec);
exit(0);
break;
default: /* parent */
/* NOP */
break;
}
/* fds[0] is the child's end; close it for proper EOF detection */
(void) close(fds[0]);
return fds[1];


}


#endif /* HAVE_SOCKETPAIR */

#ifdef __UNUSED__
#include <sys/time.h


int SockCheckOpen(int fd)
/* poll given socket; is it selectable? */
{
fd_set r, w, e;
int rt;
struct timeval tv;


for (;Wink
{
FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
FD_SET(fd, &e);


tv.tv_sec = 0; tv.tv_usec = 0;
rt = select(fd+1, &r, &w, &e, &tv);
if (rt == -1 && (errno != EAGAIN && errno != EINTR))
return 0;
if (rt != -1)
return 1;
}


}


#endif /* __UNUSED__ */

int UnixOpen(const char *path)
{
int sock = -1;
struct sockaddr_un ad;
memset(&ad, 0, sizeof(ad));
ad.sun_family = AF_UNIX;
strncpy(ad.sun_path, path, sizeof(ad.sun_path)-1);


sock = socket( AF_UNIX, SOCK_STREAM, 0 );
if (sock < 0)
{
h_errno = 0;
return -1;
}


/* Socket opened saved. Usefull if connect timeout
* because it can be closed.
*/
mailserver_socket_temp = sock;


if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0)
{
int olderr = errno;
fm_close(sock); /* don't use SockClose, no traffic yet */
h_errno = 0;
errno = olderr;
sock = -1;
}


/* No connect timeout, then no need to set
mailserver_socket_temp */
mailserver_socket_temp = -1;


return sock;



}


#if INET6_ENABLE
int SockOpen(const char *host, const char *service, const char
*options,
const char *plugin)
{
struct addrinfo *ai, *ai0, req;
int i;
#if NET_SECURITY
void *request = NULL;
int requestlen;
#endif /* NET_SECURITY */

#ifdef HAVE_SOCKETPAIR
if (plugin)
return handle_plugin(host,service,plugin);
#endif /* HAVE_SOCKETPAIR */
memset(&req, 0, sizeof(struct addrinfo));
req.ai_socktype = SOCK_STREAM;


if (getaddrinfo(host, service, &req, &ai0)) {
report(stderr, GT_("fetchmail: getaddrinfo(%s.%s)\n"),
host,service);
return -1;
}


#if NET_SECURITY
if (!options)
requestlen = 0;
else
if (net_security_strtorequest((char *)options, &request,
&requestlen))
goto ret;


i = inner_connect(ai0, request, requestlen, NULL, NULL,
"fetchmail", NULL);
if (request)
free(request);


ret:
#else /* NET_SECURITY */
#ifdef HAVE_INNER_CONNECT
i = inner_connect(ai0, NULL, 0, NULL, NULL, "fetchmail", NULL);
if (i >= 0)
break;
#else


i = -1;
for (ai = ai0; ai; ai = ai->ai_next) {
i = socket(ai->ai_family, ai->ai_socktype, 0);
if (i < 0)
continue;


/* Socket opened saved. Usefull if connect timeout
* because it can be closed.
*/
mailserver_socket_temp = i;


if (connect(i, (struct sockaddr *) ai->ai_addr, ai->ai_addrlen)
0) {
fm_close(i);
i = -1;
continue;
}


/* No connect timeout, then no need to set
mailserver_socket_temp */
mailserver_socket_temp = -1;


break;
}


#endif
#endif /* NET_SECURITY */


freeaddrinfo(ai0);


return i;


}


#else /* INET6_ENABLE */
#ifndef HAVE_INET_ATON
#ifndef INADDR_NONE
#ifdef INADDR_BROADCAST
#define INADDR_NONE INADDR_BROADCAST
#else
#define INADDR_NONE -1
#endif
#endif
#endif /* HAVE_INET_ATON */

int SockOpen(const char *host, int clientPort, const char *options,
const char *plugin)
{
int sock = -1; /* pacify -Wall */
#ifndef HAVE_INET_ATON
unsigned long inaddr;
#endif /* HAVE_INET_ATON */
struct sockaddr_in ad, **pptr;
struct hostent *hp;


#ifdef HAVE_SOCKETPAIR
if (plugin) {
char buf[10];
#ifdef HAVE_SNPRINTF
snprintf(buf, sizeof(buf), /* Yeah, paranoic. So what? Razz */
#else
sprintf(buf,
#endif /* HAVE_SNPRINTF */
"%d",clientPort);
return handle_plugin(host,buf,plugin);
}
#endif /* HAVE_SOCKETPAIR */


memset(&ad, 0, sizeof(ad));
ad.sin_family = AF_INET;


/* we'll accept a quad address */
#ifndef HAVE_INET_ATON
inaddr = inet_addr((char*)host);
if (inaddr != INADDR_NONE)
{
memcpy(&ad.sin_addr, &inaddr, sizeof(inaddr));
#else
if (inet_aton(host, &ad.sin_addr))
{
#endif /* HAVE_INET_ATON */
ad.sin_port = htons(clientPort);


sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
h_errno = 0;
return -1;
}


/* Socket opened saved. Usefull if connect timeout
because
* it can be closed
*/
mailserver_socket_temp = sock;


if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0)
{
int olderr = errno;
fm_close(sock); /* don't use SockClose, no traffic yet
*/
h_errno = 0;
errno = olderr;
return -1;
}


/* No connect timeout, then no need to set
mailserver_socket_temp */
mailserver_socket_temp = -1;


#ifndef HAVE_INET_ATON
}
#else
}
#endif /* HAVE_INET_ATON */
else {
hp = gethostbyname((char*)host);


if (hp == NULL)
{
errno = 0;
return -1;
}
/*
* Add a check to make sure the address has a valid IPv4 or
IPv6
* length. This prevents
Back to top
Guest







PostPosted: Sun Jun 25, 2006 6:07 pm    Post subject: Re: A code from M. Jerzy Buczynski Reply with quote

richard_cr...@yahoo.com wrote:
Quote:
Validate.

/*
* socket.c -- socket library functions
*
* Copyright 1998 by Eric S. Raymond.
* For license terms, see the file COPYING in this directory.
*/


#include "config.h"
#include <stdio.h
#include <errno.h
#include <string.h
#include <ctype.h> /* isspace() */
#ifdef HAVE_MEMORY_H
#include <memory.h
#endif /* HAVE_MEMORY_H */
#include <sys/types.h
#ifndef HAVE_NET_SOCKET_H
#include <sys/socket.h
#else
#include <net/socket.h
#endif
#include <sys/un.h
#include <netinet/in.h
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h
#endif
#include <netdb.h
#if defined(STDC_HEADERS)
#include <stdlib.h
#endif
#if defined(HAVE_UNISTD_H)
#include <unistd.h
#endif
#if defined(HAVE_STDARG_H)
#include <stdarg.h
#else
#include <varargs.h
#endif
#include "socket.h"
#include "fetchmail.h"
#include "i18n.h"


/* Defines to allow BeOS and Cygwin to play nice... */
#ifdef __BEOS__
static char peeked;
#define fm_close(a) closesocket(a)
#define fm_write(a,b,c) send(a,b,c,0)
#define fm_peek(a,b,c) recv(a,b,c,0)
#define fm_read(a,b,c) recv(a,b,c,0)
#else
#define fm_close(a) close(a)
#define fm_write(a,b,c) write(a,b,c)
#define fm_peek(a,b,c) recv(a,b,c, MSG_PEEK)
#ifdef __CYGWIN__
#define fm_read(a,b,c) cygwin_read(a,b,c)
static ssize_t cygwin_read(int sock, void *buf, size_t count);
#else /* ! __CYGWIN__ */
#define fm_read(a,b,c) read(a,b,c)
#endif /* __CYGWIN__ */
#endif


/* We need to define h_errno only if it is not already */
#ifndef h_errno


#ifdef HAVE_RES_SEARCH
/* some versions of FreeBSD should declare this but don't */
extern int h_errno;
#else
/* pretend we have h_errno to avoid some #ifdef's later */
static int h_errno;
#endif


#endif /* ndef h_errno */


extern int mailserver_socket_temp; /* Socket to close if connect
timeout */


#if NET_SECURITY
#include <net/security.h
#endif /* NET_SECURITY */


#ifdef HAVE_SOCKETPAIR
char *const *parse_plugin(const char *plugin, const char *host, const
char *service)
{ const char **argvec;
const char *c, *p;
char *cp, *plugin_copy;
unsigned int plugin_copy_len;
unsigned int plugin_offset = 0, plugin_copy_offset = 0;
unsigned int i, s = 2 * sizeof(char*), host_count = 0,
service_count =
0;
unsigned int plugin_len = strlen(plugin);
unsigned int host_len = strlen(host);
unsigned int service_len = strlen(service);


for (c = p = plugin; *c; c++)
{ if (isspace(*c) && !isspace(*p))
s += sizeof(char*);
if (*p == '%' && *c == 'h')
host_count++;
if (*p == '%' && *c == 'p')
service_count++;
p = c;
}


plugin_copy_len = plugin_len + host_len * host_count +
service_len *
service_count;
plugin_copy = malloc(plugin_copy_len + 1);
if (!plugin_copy)
{
report(stderr, GT_("fetchmail: malloc failed\n"));
return NULL;
}


while (plugin_copy_offset < plugin_copy_len)
{ if ((plugin[plugin_offset] == '%') &&
(plugin[plugin_offset + 1] ==
'h'))
{ strcpy(plugin_copy + plugin_copy_offset, host);

plugin_offset += 2;
plugin_copy_offset += host_len;
}
else if ((plugin[plugin_offset] == '%') &&
(plugin[plugin_offset + 1]
== 'p'))
{ strcpy(plugin_copy + plugin_copy_offset,
service);
plugin_offset += 2;
plugin_copy_offset += service_len;
}
else
{ plugin_copy[plugin_copy_offset] =
plugin[plugin_offset];
plugin_offset++;
plugin_copy_offset++;
}
}
plugin_copy[plugin_copy_len] = 0;


argvec = malloc(s);
if (!argvec)
{
report(stderr, GT_("fetchmail: malloc failed\n"));
return NULL;
}
memset(argvec, 0, s);
for (c = p = plugin_copy, i = 0; *c; c++)
{ if ((!isspace(*c)) && (c == p ? 1 : isspace(*p))) {
argvec[i] = c;
i++;
}
p = c;
}
for (cp = plugin_copy; *cp; cp++)
{ if (isspace(*cp))
*cp = 0;
}
return (char *const*)argvec;



}


static int handle_plugin(const char *host,
const char *service, const char *plugin)
/* get a socket mediated through a given external command */
{
int fds[2];
char *const *argvec;

/*
* The author of this code, Felix von Leitner
f...@convergence.de>, says:
* he chose socketpair() instead of pipe() because socketpair
creates
* bidirectional sockets while allegedly some pipe()
implementations don't.
*/
if (socketpair(AF_UNIX,SOCK_STREAM,0,fds))
{
report(stderr, GT_("fetchmail: socketpair failed\n"));
return -1;
}
switch (fork()) {
case -1:
/* error */
report(stderr, GT_("fetchmail: fork failed\n"));
return -1;
break;
case 0: /* child */
/* fds[1] is the parent's end; close it for proper EOF
** detection */
(void) close(fds[1]);
if ( (dup2(fds[0],0) == -1) || (dup2(fds[0],1) == -1) )
{
report(stderr, GT_("dup2 failed\n"));
exit(1);
}
/* fds[0] is now connected to 0 and 1; close it */
(void) close(fds[0]);
if (outlevel >= O_VERBOSE)
report(stderr, GT_("running %s (host %s service
%s)\n"), plugin,
host, service);
argvec = parse_plugin(plugin,host,service);
execvp(*argvec, argvec);
report(stderr, GT_("execvp(%s) failed\n"), *argvec);
exit(0);
break;
default: /* parent */
/* NOP */
break;
}
/* fds[0] is the child's end; close it for proper EOF detection */
(void) close(fds[0]);
return fds[1];


}


#endif /* HAVE_SOCKETPAIR */

#ifdef __UNUSED__
#include <sys/time.h


int SockCheckOpen(int fd)
/* poll given socket; is it selectable? */
{
fd_set r, w, e;
int rt;
struct timeval tv;


for (;Wink
{
FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
FD_SET(fd, &e);


tv.tv_sec = 0; tv.tv_usec = 0;
rt = select(fd+1, &r, &w, &e, &tv);
if (rt == -1 && (errno != EAGAIN && errno != EINTR))
return 0;
if (rt != -1)
return 1;
}


}


#endif /* __UNUSED__ */

int UnixOpen(const char *path)
{
int sock = -1;
struct sockaddr_un ad;
memset(&ad, 0, sizeof(ad));
ad.sun_family = AF_UNIX;
strncpy(ad.sun_path, path, sizeof(ad.sun_path)-1);


sock = socket( AF_UNIX, SOCK_STREAM, 0 );
if (sock < 0)
{
h_errno = 0;
return -1;
}


/* Socket opened saved. Usefull if connect timeout
* because it can be closed.
*/
mailserver_socket_temp = sock;


if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0)
{
int olderr = errno;
fm_close(sock); /* don't use SockClose, no traffic yet */
h_errno = 0;
errno = olderr;
sock = -1;
}


/* No connect timeout, then no need to set
mailserver_socket_temp */
mailserver_socket_temp = -1;


return sock;



}


#if INET6_ENABLE
int SockOpen(const char *host, const char *service, const char
*options,
const char *plugin)
{
struct addrinfo *ai, *ai0, req;
int i;
#if NET_SECURITY
void *request = NULL;
int requestlen;
#endif /* NET_SECURITY */

#ifdef HAVE_SOCKETPAIR
if (plugin)
return handle_plugin(host,service,plugin);
#endif /* HAVE_SOCKETPAIR */
memset(&req, 0, sizeof(struct addrinfo));
req.ai_socktype = SOCK_STREAM;


if (getaddrinfo(host, service, &req, &ai0)) {
report(stderr, GT_("fetchmail: getaddrinfo(%s.%s)\n"),
host,service);
return -1;
}


#if NET_SECURITY
if (!options)
requestlen = 0;
else
if (net_security_strtorequest((char *)options, &request,
&requestlen))
goto ret;


i = inner_connect(ai0, request, requestlen, NULL, NULL,
"fetchmail", NULL);
if (request)
free(request);


ret:
#else /* NET_SECURITY */
#ifdef HAVE_INNER_CONNECT
i = inner_connect(ai0, NULL, 0, NULL, NULL, "fetchmail", NULL);
if (i >= 0)
break;
#else


i = -1;
for (ai = ai0; ai; ai = ai->ai_next) {
i = socket(ai->ai_family, ai->ai_socktype, 0);
if (i < 0)
continue;


/* Socket opened saved. Usefull if connect timeout
* because it can be closed.
*/
mailserver_socket_temp = i;


if (connect(i, (struct sockaddr *) ai->ai_addr, ai->ai_addrlen)
0) {
fm_close(i);
i = -1;
continue;
}


/* No connect timeout, then no need to set
mailserver_socket_temp */
mailserver_socket_temp = -1;


break;
}


#endif
#endif /* NET_SECURITY */


freeaddrinfo(ai0);


return i;


}


#else /* INET6_ENABLE */
#ifndef HAVE_INET_ATON
#ifndef INADDR_NONE
#ifdef INADDR_BROADCAST
#define INADDR_NONE INADDR_BROADCAST
#else
#define INADDR_NONE -1
#endif
#endif
#endif /* HAVE_INET_ATON */

int SockOpen(const char *host, int clientPort, const char *options,
const char *plugin)
{
int sock = -1; /* pacify -Wall */
#ifndef HAVE_INET_ATON
unsigned long inaddr;
#endif /* HAVE_INET_ATON */
struct sockaddr_in ad, **pptr;
struct hostent *hp;


#ifdef HAVE_SOCKETPAIR
if (plugin) {
char buf[10];
#ifdef HAVE_SNPRINTF
snprintf(buf, sizeof(buf), /* Yeah, paranoic. So what? Razz */
#else
sprintf(buf,
#endif /* HAVE_SNPRINTF */
"%d",clientPort);
return handle_plugin(host,buf,plugin);
}
#endif /* HAVE_SOCKETPAIR */


memset(&ad, 0, sizeof(ad));
ad.sin_family = AF_INET;


/* we'll accept a quad address */
#ifndef HAVE_INET_ATON
inaddr = inet_addr((char*)host);
if (inaddr != INADDR_NONE)
{
memcpy(&ad.sin_addr, &inaddr, sizeof(inaddr));
#else
if (inet_aton(host, &ad.sin_addr))
{
#endif /* HAVE_INET_ATON */
ad.sin_port = htons(clientPort);


sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
h_errno = 0;
return -1;
}


/* Socket opened saved. Usefull if connect timeout
because
* it can be closed
*/
mailserver_socket_temp = sock;


if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0)
{
int olderr = errno;
fm_close(sock); /* don't use SockClose, no traffic yet
*/
h_errno = 0;
errno = olderr;
return -1;
}


/* No connect timeout, then no need to set
mailserver_socket_temp */
mailserver_socket_temp = -1;


#ifndef HAVE_INET_ATON
}
#else
}
#endif /* HAVE_INET_ATON */
else {
hp = gethostbyname((char*)host);


if (hp == NULL)
{
errno = 0;
return -1;
}
/*
* Add a check to make sure the address has a valid IPv4 or
IPv6
* length. This prevents
Back to top
Display posts from previous:   
   Shopping Podder - the Best of Computer Postings! Forum Index -> Computer Bugs - Misc  
Page 1 of 1
All times are GMT

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum