/*
** This file was written by Daniel Stenberg.
** Parts of it were stolen from the BSD uudecode command.
*/
/*
** Copyright (c) 1983 Regents of the University of California.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. All advertising materials mentioning features or use of this software
** must display the following acknowledgement:
** This product includes software developed by the University of
** California, Berkeley and its contributors.
** 4. Neither the name of the University nor the names of its contributors
** may be used to endorse or promote products derived from this software
** without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE.
*/
#include <sys/param.h>
#include "main.h"
#define DEC(c) (((c) - ' ') & 077) /* single character decode */
#define IS_DEC(c) ( (((c) - ' ') >= 0) && (((c) - ' ') <= 077 + 1) )
/*
** uudecode returns non-zero on error
*/
int uudecode(FILE *input, /* get file data from (if needed) */
char *iptr, /* input string from where we are right now */
char *output, /* write result to, needs to fit at least 80 bytes */
int *length, /* output size */
char init) /* set to non-zero when initing */
{
register int n;
register char ch, *p;
int mode;
char buf[MAXPATHLEN];
int outlen=0;
if (length)
*length=0; /* in case we abort early */
if (init) {
/* search for header line */
while (2 != sscanf(iptr, "begin %o %s", &mode, buf)) {
if (!fgets(buf, MAXPATHLEN, input)) {
return 2;
}
iptr = buf;
}
#if 0
fprintf(stderr, "FIRST %s", iptr);
#endif
/* ignore file mode */
/* ignore file name too for now */
}
else {
/* for each input line */
p = iptr;
/* first, just make sure this isn't the end line: */
if (!strcmp(buf, "end") || !strcmp(buf, "end\n") ||
!strcmp(buf, "end\r\n")) {
/* muu->state = UU_HASENDED; */
if (length)
*length = 0;
return 0;
}
n = DEC(*p);
for (++p; n > 0; p += 4, n -= 3) {
if (n >= 3) {
if (!(IS_DEC(*p) && IS_DEC(*(p + 1)) &&
IS_DEC(*(p + 2)) && IS_DEC(*(p + 3))))
return 33;
ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4;
output[outlen++]=ch;
ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
output[outlen++]=ch;
ch = DEC(p[2]) << 6 | DEC(p[3]);
output[outlen++]=ch;
}
else {
if (n >= 1) {
if (!(IS_DEC(*p) && IS_DEC(*(p + 1))))
return 34;
ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4;
output[outlen++]=ch;
}
if (n >= 2) {
if (!(IS_DEC(*(p + 1)) && IS_DEC(*(p + 2))))
return 35;
ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
output[outlen++]=ch;
}
if (n >= 3) {
if (!(IS_DEC(*(p + 2)) && IS_DEC(*(p + 3))))
return 36;
ch = DEC(p[2]) << 6 | DEC(p[3]);
output[outlen++]=ch;
}
}
}
}
if (output)
output[outlen]=0; /* zero terminate */
if (length)
*length = outlen; /* send back size */
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1