/* Sat 8 Feb 1997: changes by Adam M. Costello : * ANSI-ized and fixed the declarations. * Fixed calls to doaline(). * Closed files when done with them. */ /* This program was originally posted on usenet by wiegley@acsu.buffalo.edu (Jeffrey A Wiegley), and then modified by neil@uninet.cpd.com (Neil Gorsuch) to add a little security checking so that uuencoded file names can't include . as the first character, and can't include the / character in them. Here is the description of the program in the original usenet posting: 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.) */ #include #include #define TRUE 1 #define FALSE 0 #define DEC(c) (((c) - ' ') & 077) #define LENGTH 150 static void uuread(FILE *infile); static void doaline(char s[]); static void outdec(char *p, int n); static FILE *out = NULL; int main(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); if (out) fclose(out); fclose(infile); } return 0; } static void uuread(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 (strchr(dest, '/') != NULL) { fputs("/ character not allowed in destination file name\n", stderr); exit(4); } if (dest[0] == '.') { fputs(". not allowed as first char of destination file name", stderr); exit(4); } if (out) fclose(out); 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); doaline(s1); 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), 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. */ static void doaline(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. */ static void outdec(char *p, int n) { 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); }