#include #include #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); }