aboutsummaryrefslogtreecommitdiffstats
path: root/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'socket.c')
-rw-r--r--socket.c85
1 files changed, 61 insertions, 24 deletions
diff --git a/socket.c b/socket.c
index 94d3e56b..5710796c 100644
--- a/socket.c
+++ b/socket.c
@@ -42,43 +42,73 @@ static int h_errno;
#include <net/security.h>
#endif /* NET_SECURITY */
+static int handle_plugin(const char *host,
+ const char *service, const char *plugin)
+/* get a socket mediated through a given external command */
+{
+ if (plugin)
+ {
+ int fds[2];
+ if (socketpair(AF_UNIX,SOCK_STREAM,0,fds))
+ {
+ error(0, 0, "fetchmail: socketpair failed: %s(%d)",strerror(errno),errno);
+ return -1;
+ }
+ if (!fork())
+ {
+ dup2(fds[0],0);
+ dup2(fds[0],1);
+ if (outlevel >= O_VERBOSE)
+ error(0, 0, "running %s %s %s", plugin, host, service);
+ execlp(plugin,plugin,host,service,0);
+ error(0, 0, "execl(%s) failed: %s (%d)",
+ plugin, strerror(errno), errno);
+ exit(0);
+ }
+ return fds[1];
+ }
+}
+
#if INET6
-int SockOpen(const char *host, const char *service, const char *options)
+int SockOpen(const char *host, const char *service, const char *options,
+ const char *plugin)
{
- int i;
- struct addrinfo *ai, req;
+ int i;
+ struct addrinfo *ai, req;
#if NET_SECURITY
- void *request = NULL;
- int requestlen;
+ void *request = NULL;
+ int requestlen;
#endif /* NET_SECURITY */
- memset(&req, 0, sizeof(struct addrinfo));
- req.ai_socktype = SOCK_STREAM;
+ if (plugin)
+ return handle_plugin(host,service,plugin);
+ memset(&req, 0, sizeof(struct addrinfo));
+ req.ai_socktype = SOCK_STREAM;
- if (i = getaddrinfo(host, service, &req, &ai)) {
- error(0, 0, "fetchmail: getaddrinfo(%s.%s): %s(%d)", host, service, gai_strerror(i), i);
- return -1;
- };
+ if (i = getaddrinfo(host, service, &req, &ai)) {
+ error(0, 0, "fetchmail: getaddrinfo(%s.%s): %s(%d)", host, service, gai_strerror(i), i);
+ return -1;
+ };
#if NET_SECURITY
- if (!options)
- requestlen = 0;
- else
- if (net_security_strtorequest((char *)options, &request, &requestlen))
- goto ret;
+ if (!options)
+ requestlen = 0;
+ else
+ if (net_security_strtorequest((char *)options, &request, &requestlen))
+ goto ret;
- i = inner_connect(ai, request, requestlen, NULL, NULL, "fetchmail", NULL);
- if (request)
- free(request);
+ i = inner_connect(ai, request, requestlen, NULL, NULL, "fetchmail", NULL);
+ if (request)
+ free(request);
-ret:
+ ret:
#else /* NET_SECURITY */
- i = inner_connect(ai, NULL, 0, NULL, NULL, "fetchmail", NULL);
+ i = inner_connect(ai, NULL, 0, NULL, NULL, "fetchmail", NULL);
#endif /* NET_SECURITY */
- freeaddrinfo(ai);
+ freeaddrinfo(ai);
- return i;
+ return i;
};
#else /* INET6 */
#ifndef HAVE_INET_ATON
@@ -91,7 +121,8 @@ ret:
#endif
#endif /* HAVE_INET_ATON */
-int SockOpen(const char *host, int clientPort, const char *options)
+int SockOpen(const char *host, int clientPort, const char *options,
+ const char *plugin)
{
int sock;
#ifndef HAVE_INET_ATON
@@ -100,6 +131,12 @@ int SockOpen(const char *host, int clientPort, const char *options)
struct sockaddr_in ad;
struct hostent *hp;
+ if (plugin) {
+ char buf[10];
+ sprintf(buf,"%d",clientPort);
+ return handle_plugin(host,buf,plugin);
+ }
+
memset(&ad, 0, sizeof(ad));
ad.sin_family = AF_INET;