pathchk.c revision da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1992-2007 AT&T Knowledge Ventures *
* and is licensed under the *
* Common Public License, Version 1.0 *
* by AT&T Knowledge Ventures *
* *
* A copy of the License is available at *
* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* pathchk
*
* Written by David Korn
*/
static const char usage[] =
"[-?\n@(#)$Id: pathchk (AT&T Research) 2006-09-19 $\n]"
"[+NAME?pathchk - check pathnames for portability]"
"[+DESCRIPTION?\bpathchk\b checks each \apathname\a to see if it "
"can be used to access or create a file without causing syntax "
"errors. A file is portable, if no truncation will result on "
"any conforming POSIX.1 implementation.]"
"[+?By default \bpathchk\b checks each component of each \apathname\a "
"based on the underlying file system. A diagnostic is written "
"to standard error for each pathname that:]{"
"[+-?Is longer than \b$(getconf PATH_MAX)\b bytes.]"
"[+-?Contains any component longer than \b$(getconf NAME_MAX)\b bytes.]"
"[+-?Contains any directory component in a directory that is "
"not searchable.]"
"[+-?Contains any character in any component that is not valid in "
"its containing directory.]"
"[+-?Is empty.]"
"}"
"[p:portability?Instead of performing length checks on the underlying "
"file system, write a diagnostic for each pathname operand that:]{"
"[+-?Is longer than \b$(getconf _POSIX_PATH_MAX)\b bytes.]"
"[+-?Contains any component longer than "
"\b$(getconf _POSIX_NAME_MAX)\b bytes.]"
"[+-?Contains any character in any component that is not in the "
"portable filename character set.]"
#if 0
"[+-?Contains any component with \b-\b as the first character.]"
#endif
"[+-?Is empty.]"
"}"
"\n"
"\npathname ...\n"
"\n"
"[+EXIT STATUS?]{"
"[+0?All \apathname\a operands passed all of the checks.]"
"[+>0?An error occurred.]"
"}"
"[+SEE ALSO?\bgetconf\b(1), \bcreat\b(2), \bpathchk\b(2)]"
;
#include <cmd.h>
#include <ls.h>
#define isport(c) (((c)>='a' && (c)<='z') || ((c)>='A' && (c)<='Z') || ((c)>='0' && (c)<='9') || (strchr("._-",(c))!=0) )
/*
* call pathconf and handle unlimited sizes
*/
{
register long r;
errno=0;
return(LONG_MAX);
return(r);
}
/*
* returns 1 if <path> passes test
*/
{
register int c;
char buf[2];
if(!*path)
{
return(0);
}
if(mode)
{
}
else
{
char tmp[2];
tmp[1] = 0;
name_max = r;
path_max = r;
if(*cp!='/')
{
{
if(!(cpold = getcwd((char*)0, 0)) && errno == EINVAL && (cpold = newof(0, char, PATH_MAX, 0)) && !getcwd(cpold, PATH_MAX))
{
cpold = 0;
}
if(cpold)
{
{
*++cp = 0;
name_max = r;
path_max=r;
{
break;
}
while(*cp!='/')
cp--;
}
}
}
while(*cp=='/')
cp++;
}
if(name_max==0)
if(path_max==0)
{
while((c= *cp++) && c!='/');
goto err;
errno=0;
cp[-1] = 0;
r = mypathconf(path, 0);
if((cp[-1]=c)==0)
cp--;
else while(*cp=='/')
cp++;
if(r>=0)
continue;
#ifdef ENAMETOOLONG
else if(errno==ENAMETOOLONG)
{
return(0);
}
#endif /*ENAMETOOLONG*/
else
break;
}
}
{
{
return(0);
}
while((c= *cp++) && c!='/')
{
buf[0] = c;
buf[1] = 0;
return(0);
}
goto err;
if(c==0)
break;
while(*cp=='/')
cp++;
}
{
return(0);
}
return(1);
err:
return(0);
}
int
{
register int n, mode=0;
register char *cp;
{
case 'p':
mode = 1;
break;
case ':':
break;
case '?':
break;
}
{
}
return(error_info.errors);
}