Files
Work/uudecode/UUDECODE.CPP
2024-08-07 09:16:27 -04:00

108 lines
2.1 KiB
C++

static int decode()
{
extern int errno;
struct passwd *pw;
register int n;
register char ch, *p;
int mode, n1;
char buf[MAXPATHLEN];
/* search for header line */
do{
if(!fgets(buf,sizeof(buf),stdin))
{
(void)fprintf(stderr,"uudecode: %s: no \"begin\" line\n", filename);
return(1);
}
}while(strncmp(buf,"begin ",6));
(void)sscanf(buf,"begin %o %s",&mode,buf);
/* handle ~user/file format */
if(buf[0]=='~')
{
if(!(p=index(buf,'/')))
{
(void)fprintf(stderr, "uudecode: %s: illegal ~user.\n",filename);
return(1);
}
*p++=NULL;
if(!(pw=getpwnam(buf+1)))
{
(void)fprintf(stderr,"uudecode: %s: no user %s.\n",filename,buf);
return(1);
}
n=strlen(pw->pw_dir);
n1=strlen(p);
if(n+n1+2>MAXPATHLEN)
{
(void)fprintf(stderr, "uudecode: %s: path too long.\n",filename);
return(1);
}
bcopy(p,buf+n+1,n1+1);
bcopy(pw->pw_dir,buf,n);
buf[n]='/';
}
/* create output file, set mode */
if(!freopen(buf,"w",stdout)||fchmod(fileno(stdout),mode&0666))
{
(void)fprintf(stderr,"uudecode: %s: %s: %s\n", buf,filename,strerror(errno));
return(1);
}
// for each input line
for(;;)
{
if(!fgets(p=buf,sizeof(buf),stdin))
{
(void)fprintf(stderr,"uudecode: %s: short file.\n",filename);
return(1);
}
#define DEC(c) (((c) - ' ') & 077) /* single character decode */
// '`n' is used to avoid writing out all the characters at the end of the file.
if((n=DEC(*p))<=0)break;
for(++p;n>0;p+=4,n-=3)
if(n>=3)
{
ch=DEC(p[0])<<2|DEC(p[1])>>4;
putchar(ch);
ch=DEC(p[1])<<4|DEC(p[2])>>2;
putchar(ch);
ch=DEC(p[2])<<6|DEC(p[3]);
putchar(ch);
}
else
{
if(n>=1)
{
ch=DEC(p[0])<<2|DEC(p[1])>>4;
putchar(ch);
}
if(n>=2)
{
ch=DEC(p[1])<<4|DEC(p[2])>>2;
putchar(ch);
}
if(n>=3)
{
ch=DEC(p[2])<<6|DEC(p[3]);
putchar(ch);
}
}
}
if(!fgets(buf,sizeof(buf),stdin)||strcmp(buf,"end\n"))
{
(void)fprintf(stderr, "uudecode: %s: no \"end\" line.\n",filename);
return(1);
}
return(0);
}
static void
usage()
{
(void)fprintf(stderr, "usage: uudecode [file ...]\n");
exit(1);
}