🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.emacs.vm.bug
Article #972

Re: IMAP access problem

#972
From: Austin Donnelly
Date: Sat, 22 Dec 2001 15:04
196 lines
5331 bytes
In article <u27pr5jcq6lo57@corp.supernews.com>,
Kyle Jones <kyle_jones@wonderworks.com> wrote:
>I recommend using at least the version of stunnel I tested with,
>version 3.20.  I see serious bugs addressed in the change log for
>previous versions.  I also had a user who could not get SSL
>function until he upgraded from 3.14 to 3.20.

Yes, I discovered this problem too.  For those who aren't able to
upgrade their stunnel for whatever reason, I've written a little
wrapper called "Y" which re-plumbs stdin and stdout appropriately.

I've inserted the code for it below this posting.  It works for me under
Linux, but I expect it to be reasonably portable.

Austin

/*
 * Y.c: Sick little program to do this:
 * 
 *    ---> fd 0
 *               >  Y   <---fd 0--->  PROGRAM
 *    <--- fd 1
 *
 * IE give PROGRAM a bi-directional fd 0, and break it out into the
 * more usual fd 0 (stdin) for input, and fd 1 (stdout) for output.
 * Stderr is ignored.
 *
 * (c) Austin Donnelly 2001
 * Public Domain, use as you like.  No warranty.
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <signal.h>


void
die (const char *m)
{
    fprintf (stderr, "%s: %s\n", m, strerror (errno));
    exit (1);
}


#define BS 1024

void
shuffle_data (int iofd)
{
    int    ret;
    fd_set readset, writeset;
    int    inch  = 0;   /* chars just read from iofd */
    int    outch = 0;   /* chars needing written to iofd */
    char   inbuf[BS];
    char   outbuf[BS];
    char   *inp  = inbuf;
    char   *outp = outbuf;

    while (1)
    {
	FD_ZERO (&readset);
	FD_ZERO (&writeset);

	FD_SET (iofd, &readset);
	FD_SET (0, &readset);

	/* only care about writing if we have buffered data */
	if (inch  > 0)
	    FD_SET (1, &writeset);
	if (outch > 0)
	    FD_SET (iofd, &writeset);

	ret = select (iofd+1, &readset, &writeset, NULL, NULL);
	if (ret < 0)
	    die ("select");

	/* first of all see if we can get rid of any buffered data */
	if (inch > 0 && FD_ISSET (1, &writeset))
	{
	    ret = write (1, inp, inch);
	    if (ret < 0)
		die ("write stdout");
	    if (ret == 0)
		die ("write stdout == 0");
	    inch -= ret;
	    inp  += ret;
	}

	if (outch > 0 && FD_ISSET (iofd, &writeset))
	{
	    ret = write (iofd, outp, outch);
	    if (ret < 1)
		die ("write iofd");
	    if (ret == 0)
		die ("write iofd == 0");
	    outch -= ret;
	    outp  += ret;
	}

	/* any data ready for reading? */
	if (FD_ISSET (iofd, &readset) && inch == 0)
	{
	    ret = read (iofd, inbuf, BS);
	    if (ret < 0)
		die ("read iofd");
	    if (ret == 0)
		return;  /* EOF on remote */
	    inch = ret;
	    inp  = inbuf;
	}

	if (FD_ISSET (0, &readset) && outch == 0)
	{
	    ret = read (0, outbuf, BS);
	    if (ret < 0)
		die ("read stdin");
	    if (ret == 0)
		return;  /* EOF on stdin */
	    outch = ret;
	    outp  = outbuf;
	}
    }
}


void
child_dead (int signum)
{
    /* we callously don't care about our children - we die when they do */
    exit(0);
}


int
main (int argc, char **argv)
{
    int ret;
    int fds[2];

    if (argc < 2)
    {
	fprintf (stderr,
		 "usage: %s PROGRAM [ ARGS ]\n"
		 "\tRun PROGRAM (with ARGS), and set up a bi-directional\n"
		 "\tsocket to PROGRAM on fd 0.  Reads and writes by PROGRAM on\n"
		 "\tthis socket get turned onto reads on stdin and write on stdout\n\n"
		 "\tThis adaptor is useful for running programs which expect to\n"
		 "\tbe run from inetd and do all their I/O on fd 0\n",
		 
		 argv[0]);
	exit (1);
    }

    ret = socketpair (PF_UNIX, SOCK_STREAM, 0, fds);
    if (ret < 0)
	die ("socketpair");

    /* shift args ready for exec */
    argc--;
    argv++;

    /* setup parent's CHLD signal handler: we die when the child dies */
    {
	struct sigaction sa;

	sa.sa_handler = child_dead;
	sa.sa_flags   = SA_NOCLDSTOP;
	ret = sigaction (SIGCHLD, &sa, NULL);
	if (ret < 0)
	    die ("sigaction");
    }
    

    switch (fork ()) {
    case -1: /* error */
	die ("fork");
	break;

    case 0: /* child */
	dup2 (fds[1], 0);  /* socket is our fd 0 */
	execvp (argv[0], argv);
	die ("execvp");
	break;

    default: /* parent */
	shuffle_data (fds[0]);
    }

    return 0;
}
Technical Details
Message-ID: <a027d7$1l2$1@pegasus.csx.cam.ac.uk>
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!newsfeed00.sul.t-online.de!t-online.de!skynet.be!skynet.be!peer.news.eu-x.com!server2.netnews.ja.net!pegasus.csx.cam.ac.uk!not-for-mail
References: <qfvk7vg1mvb.fsf@narino.cs.washington.edu> <u279jm4makede0@corp.supernews.com> <qfvello1bo1.fsf@narino.cs.washington.edu> <u27pr5jcq6lo57@corp.supernews.com>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f6829,cda1074aa444c08b
X-Google-Attributes: gidf6829,public
X-Google-ArrivalTime: 2001-12-22 07:04:11 PST
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!newsfeed00.sul.t-online.de!t-online.de!skynet.be!skynet.be!peer.news.eu-x.com!server2.netnews.ja.net!pegasus.csx.cam.ac.uk!not-for-mail
From: Austin Donnelly <and1000@cam.ac.uk>
Newsgroups: gnu.emacs.vm.bug
Subject: Re: IMAP access problem
Date: 22 Dec 2001 15:04:07 GMT
Organization: University of Cambridge Computer Laboratory
Lines: 196
Message-ID: <a027d7$1l2$1@pegasus.csx.cam.ac.uk>
References: <qfvk7vg1mvb.fsf@narino.cs.washington.edu> <u279jm4makede0@corp.supernews.com> <qfvello1bo1.fsf@narino.cs.washington.edu> <u27pr5jcq6lo57@corp.supernews.com>
NNTP-Posting-Host: revs.nem.cl.cam.ac.uk