108 lines
2.1 KiB
C++
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);
|
|
}
|