/*
From: olsonkk@ucsu.Colorado.EDU          Article 9960 of alt.binaries.pictures.erotica
Article: 9960 of alt.binaries.pictures.erotica
Path: bloom-picayune.mit.edu!mintaka.lcs.mit.edu!olivea!uunet!boulder!ucsu!olsonkk
From: olsonkk@ucsu.Colorado.EDU (OLSON KIRK)
Newsgroups: alt.binaries.pictures.erotica
Subject: uuconvert.c & instructions
Message-ID: <1992Jul24.092406.20681@ucsu.Colorado.EDU>
Date: 24 Jul 92 09:24:06 GMT
Organization: University of Colorado, Boulder
Lines: 165


This is the source code for a program that removes headers, trailers.
It also cats parts together, and uudecodes.  It does all of these things
in one step.  So, if you down load a .gif that has 5 parts.... It will
strip the headers, trailers, cat, and uudecode.  When I save files from
this group my nn server puts the parts in /News/alt/binaries/pictures,
and makes a file called erotica.  I save all the parts of the gifs I
want in order to this file.  Then all I type is uuconvert erotica and it
spits out all the gifs.  It's really slick...  Remember to remove my
signature at the end of this file before you compile it.
When you compile this call it uuconvert.
-----------cut here----delete this line and everything above it-------
*/
#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;

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

  if (argc < 2)
    uuread(stdin);
  else
    for (argno = 1; !error && argno < argc; argno++)
      if (error = ((infile = fopen(argv[argno], "r")) == NULL))
	fprintf(stderr, "uucat: Can't open '%s' for input.\n", argv[argno]);
      else
	uuread(infile),	fclose(infile);
  exit(0);
}


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);
	    out = fopen(dest, "w");
	    if (out == NULL) perror(dest), 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)
	  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, stdout);
	      doaline(s1, stdout);
	      lines_to_go = 0;  /* Done. Break off */
	      just_finished = TRUE;
	      started = FALSE;
	    }
	    else
	      lines_to_go = 0;  /* Unexpected line, so break off */
    }
    
    if (echo_on&&(!firstline))
      doaline(s0, stdout), s0[0] = '\0';
    else if (firstline)
      firstline=FALSE;
    
    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);
}
/*
--------cut here----delete this line and everything below it------
-- 
Kirk Olson

olsonkk@ucsu.colorado.edu
olsonkir@luther.uni.edu
*/
