@From: wiegley@acsu.buffalo.edu (jeffrey a wiegley)
Newsgroups: alt.sex.pictures
Subject: a conversion program to decode posted images.
Date: 16 Nov 90 01:50:55 GMT
Distribution: na
Organization: SUNY Buffalo

Hey,  A while back ago somebody posted the source code for a program named
uucat which had the ability to strip headers from the uuencoded files that
are posted to various newsgroups.  Then a couple of months later another
person posted the source codes for uudecode and uuencode.  Then I said hey!
I`m a computer Scientist, why do I have to use two utilies to get the job
done?  So I combined the two programs into one, cleaned up the code (or made
it more cryptic, it's 'c' I'll let you decide)  Now this program will strip
headers and tailers from files and uudecode the contents at the same time.

(I'm sorry about the fact that this program is compatible only with unix, as I
stripped out the #ifndef's for compiling on other machines.  But I don't
think it would be very hard to change the few things that cause portability
problem.  try it as is, it may work for you.)

To use the program once it is compiled simply use it like-

cat file1 file2 file*... | uuconvert
or
uuconvert file1 file2 file* ...  for as many files as you have.

(it doesn't need to be named uuconvert, you can name it what ever you wish.)
so this is extreemly handy. it will also uudecode files that do not
have headers or tailers.  I DO NOT MAKE ANY PROMISES AS TO HOW WELL
IT WORKS!!  I only worked on it a couple of hours.  But I have
decoded several of the .gif files from this newsgroup and it worked
fine for all of them, I.E. no SHORT FILEs.  If something does go wrong
however it's up to you to fix it.

Now it is sooo easy to use things like -

What Next [nNq]   2578-2562 S tempfile       /* from news */

and then from the local machine to just say

uuconvert tempfile

and it will change the muliple article file 'tempfile' into it's
corresponding .gif file or whatever type was uuencoded.  So copy
this down remove this explanation, compile and enjoy.
oh yea, it does not remove the 'tempfile' so you have to remember to
do that yourself if you don't want it hanging around.

If you have any questions about it's use please send mail to
wiegley@sun.acsu.buffalo.edu
(no complaints please I didn't write it entirely,  and I give thanks to
those who did the majority of code research and development, sorry guys,
I forgot your names.)
#endif

#include <stdio.h>
#include <string.h>

#define TRUE	1
#define FALSE	0
#define DEC(c)	(((c) - ' ') & 077)
#define LENGTH	150

extern void uuread();
FILE *out = NULL;
char *Outname = NULL;

void main(argc, argv)
int argc;
char *argv[];
{
  int error=FALSE;
  FILE *infile;
  char *Progname = argv[0];

  if (argv[1][0] == '-' && argv[1][1] == 'o') {
    ++argv;
    --argc;
    if (argv[0][2] == '\0') {
      if ((Outname = *++argv) == NULL) {
	fprintf(stderr, "Usage: %s [-o outputfile] [inputfile ...]\n", Progname);
	exit(1);
      }
      else --argc;
    }
    else Outname = argv[0] + 2;
  }
  if (argc <= 1)
    uuread(stdin);
  else
    while (--argc > 0 && !error)
      if (error = ((infile = fopen(*++argv, "r")) == NULL))
	fprintf(stderr, "%s: Can't open '%s' for input.\n", Progname, *argv);
      else
	uuread(infile),	fclose(infile);
  exit(error);
}


void uuread(infile)
FILE *infile;
{
  char *s2, *s1, *s0, *tmp_s;
  int length;
  static char s[3 * (LENGTH + 1)];
  static int echo_on = FALSE, started = FALSE, just_finished = FALSE;
  static int line_length = 0, lines_to_go = 0, firstline=FALSE;

  s0 = s;
  s1 = s0 + (LENGTH + 1);
  s2 = s1 + (LENGTH + 1);

  s0[0] = s1[0] = s2[0] = '\0';  /* Clear strings */

  while (fgets(s0, LENGTH, infile) != NULL)
  {
    s0[LENGTH] = '\0';  /* Make sure string is terminated */

    if (just_finished)
      just_finished = FALSE; /* yea I don't why either */

    if (!started)
      {
	if (strncmp(s0, "begin ", 6) == 0)
	  {
	    int mode;
	    char dest[128];
	    firstline=TRUE;
	    started = echo_on = TRUE, line_length = 0, lines_to_go = 0;
	    sscanf(s0, "begin %o %s", &mode, dest);
	    if (Outname == NULL) Outname = dest;
	    if ((out = fopen(Outname, "w")) == NULL) perror(Outname), exit(4);
	  }
      }
    else  /* started */
    {
      length = strlen(s0);
      if (line_length == 0)
	line_length = length;

      if (echo_on)
      {
	lines_to_go = 0;
	if (s0[0] != 'M' || length != line_length)
	{
	  echo_on = FALSE;
	  lines_to_go = 2;  /* Lines to go before 'end' is expected */
	  if (s0[0] == ' ' || s0[0] == '`')
	    lines_to_go = 1;
	}
      }
      else  /* !echo_on */
	if (s0[0] == 'M' && length == line_length
	  /* Simple check for non-uuencoded line */
	  && strncmp(s0+1, "essage-ID: ", 11)) /* (a3@rivm.nl) 9 jul 1992 */
	    echo_on = TRUE;
	else if (lines_to_go > 0)
	  if (lines_to_go == 2)
	    if (s0[0] == ' ' || s0[0] == '`')
	      lines_to_go = 1;
	    else
	      lines_to_go = 0;  /* Unexpected line, so break off */
	  else if (lines_to_go == 1)
	    if (strcmp(s0, "end\n") == 0)
	    {
	      doaline(s2);
	      doaline(s1);
	      lines_to_go = 0;  /* Done. Break off */
	      just_finished = TRUE;
	      started = FALSE;
	      fclose(out);
	    }
	    else
	      lines_to_go = 0;  /* Unexpected line, so break off */
    }

    if (firstline)
      firstline=FALSE;
    else if (echo_on)
      doaline(s0), s0[0] = '\0';
    
    tmp_s = s2, s2 = s1, s1 = s0, s0 = tmp_s;
  }
}

/*
 * copy from in to out, decoding as you go along.
 */
doaline(s)
     char s[];
{
  char *bp;
  int n;
  if ((n=DEC(s[0])) > 0)
    {
      bp = &s[1];
      while (n > 0)
	outdec(bp, n), bp += 4, n -= 3;
    }
}

/*
 * output a group of 3 bytes (4 input characters).
 * the input chars are pointed to by p, they are to
 * be output to file f.  n is used to tell us not to
 * output all of them at the end of the file.
 */
outdec(p, n)
     char *p;
{
  int c1, c2, c3;
  
  c1 = DEC(*p) << 2 | DEC(p[1]) >> 4;
  c2 = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
  c3 = DEC(p[2]) << 6 | DEC(p[3]);
  if (n >= 1) putc(c1, out);
  if (n >= 2) putc(c2, out);
  if (n >= 3) putc(c3, out);
}
#if 0

enjoy!

Jeff Wiegley : wiegley@sun.acsu.buffalo.edu

#endif
@EOF

chmod 644 uuconvert.c

exit 0
-- 
* Slade Mailing List:  slade-request@rivm.nl                |       ,==.
* European top 20               : a3@rivm.nl                |      /U  |
* Nederlandse songfragmentenquiz: a3@rivm.nl (Adri Verhoef) |     /_  <
* Dutch Artists Lyrics Quiz     : a3@rivm.nl                |    =" `g'
Newsgroups: alt.supermodels