da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * test expression
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * [ expression ]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _lib_setregid */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define isapipe(f,p) (test_stat(f,p)>=0&&S_ISFIFO((p)->st_mode)||S_ISSOCK((p)->st_mode)&&(p)->st_ino&&((p)->st_mode&(S_IRUSR|S_IWUSR))!=(S_IRUSR|S_IWUSR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define isapipe(f,p) (test_stat(f,p)>=0&&S_ISFIFO((p)->st_mode)||S_ISSOCK((p)->st_mode)&&(p)->st_ino)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define isapipe(f,p) (test_stat(f,p)>=0&&S_ISFIFO((p)->st_mode)||S_ISSOCK((p)->st_mode)&&(p)->st_ino)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define isasock(f,p) (test_stat(f,p)>=0&&S_ISSOCK((p)->st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define isapipe(f,p) (test_stat(f,p)>=0&&S_ISFIFO((p)->st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int test_mode(const char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* single char string compare */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* two character string compare */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define c2_eq(a,c1,c2) (*a==c1 && *(a+1)==c2 && *(a+2)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int test_strmatch(const char *str, const char *pat)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c, m=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c = *cp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='(')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = strgrpmatch(str, pat, match, m, STR_MAXIMAL|STR_LEFT|STR_RIGHT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(m==0 && n==1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c_eq(cp,'(') && argc<=6 && c_eq(argv[argc-1],')'))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* special case ( binop ) to conform with standard */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(argc==4 && (not=sh_lookup(cp=argv[2],shtab_testops))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* posix portion for test */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* fall through */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(*cp==0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * evaluate a test expression.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * flag is 0 on outer level
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * flag is 1 when in parenthesis
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * flag is 2 when evaluating -a
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for -o and -a */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*++p == 'o')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(*p == 'a')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* test -t with no arguments */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* for backward compatibility with new flags */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(*arg!=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* add trailing / */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FS_3D */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(test_stat(arg,&statb)>=0 && S_ISDIR(statb.st_mode));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(test_stat(arg,&statb)>=0 && S_ISCHR(statb.st_mode));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(test_stat(arg,&statb)>=0 && S_ISBLK(statb.st_mode));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(test_stat(arg,&statb)>=0 && S_ISREG(statb.st_mode));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* S_ISVTX */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'h': /* undocumented, and hopefully will disappear */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*arg==0 || arg[strlen(arg)-1]=='/' || lstat(arg,&statb)<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(test_stat(arg,&statb)>=0 && S_ISCTG(statb.st_mode));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* S_ISCTG */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(test_stat(arg,&statb)>=0 && S_ISCDF(statb.st_mode));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* S_ISCDF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(test_stat(arg,&statb)>=0 && tmxgetmtime(&statb) > tmxgetatime(&statb));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(*arg != 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(*arg == 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!(np = nv_open(arg,sh.var_tree,NV_VARNAME|NV_NOFAIL|NV_NOADD|NV_NOREF)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return(!nv_isnull(np) || nv_isattr(np,NV_INTEGER));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* NOTREACHED */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint test_binop(register int op,const char *left,const char *right)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* op must be one of the following values */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(*left!=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* NOTREACHED */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns the modification time of f1 - modification time of f2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic time_t test_time(const char *file1,const char *file2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r<0?0:-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return true if inode of two files are the same
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(test_stat(file1,&stat1)>=0 && test_stat(file2,&stat2)>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(stat1.st_dev == stat2.st_dev && stat1.st_ino == stat2.st_ino)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This version of access checks against effective uid/gid
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The static buffer statb is shared with test_mode.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sh_access(register const char *name, register int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sh_ioaccess((int)strtol(name+8, (char**)0, 10),mode));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* can't use access function for execute permission with root */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* swap the real uid to effective, check access then restore */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* first swap real and effective gid, if different */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.groupid==sh.euserid || setregid(sh.egroupid,sh.groupid)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* next swap real and effective uid, if needed */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.userid==sh.euserid || setreuid(sh.euserid,sh.userid)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* restore ids */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _lib_setreuid */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* root needs execute permission for someone */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* on some systems you can be in several groups */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* first time */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* pre-POSIX system */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin groups = (gid_t*)stakalloc((maxgroups+1)*sizeof(gid_t));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(--n >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* _lib_getgroups */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Return the mode bits of file <file>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <file> is null, then the previous stat buffer is used.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The mode bits are zero if the file doesn't exist.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * do an fstat() for /dev/fd/n, otherwise stat()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int test_stat(const char *name,struct stat *buff)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);