diff options
author | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2010-04-09 16:13:32 -0700 |
---|---|---|
committer | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2010-04-09 16:15:01 -0700 |
commit | 2d698b6e42d8dca191ac795ef5dba3bf62496eec (patch) | |
tree | ac5e0b67043c50f49160e9fe407435706cf30444 /test.c | |
parent | f1250933e4a2ac09a3d0b25b3877068e12f44da5 (diff) | |
download | vyatta-bash-2d698b6e42d8dca191ac795ef5dba3bf62496eec.tar.gz vyatta-bash-2d698b6e42d8dca191ac795ef5dba3bf62496eec.zip |
Integrate bash 3.2 version
This is merge of current Debian stable (Lenny) version of Bash
with Vyatta changes.
Diffstat (limited to 'test.c')
-rw-r--r-- | test.c | 139 |
1 files changed, 20 insertions, 119 deletions
@@ -101,14 +101,7 @@ static int test_error_return; #define test_exit(val) \ do { test_error_return = val; longjmp (test_exit_buf, 1); } while (0) -/* We have to use access(2) for machines running AFS, because it's - not a Unix file system. This may produce incorrect answers for - non-AFS files. I hate AFS. */ -#if defined (AFS) -# define EACCESS(path, mode) access(path, mode) -#else -# define EACCESS(path, mode) test_eaccess(path, mode) -#endif /* AFS */ +extern int sh_stat __P((const char *, struct stat *)); static int pos; /* The offset of the current argument in ARGV. */ static int argc; /* The number of arguments present in ARGV. */ @@ -119,8 +112,6 @@ static void test_syntax_error __P((char *, char *)) __attribute__((__noreturn__) static void beyond __P((void)) __attribute__((__noreturn__)); static void integer_expected_error __P((char *)) __attribute__((__noreturn__)); -static int test_stat __P((char *, struct stat *)); - static int unary_operator __P((void)); static int binary_operator __P((void)); static int two_arguments __P((void)); @@ -163,96 +154,6 @@ integer_expected_error (pch) test_syntax_error (_("%s: integer expression expected"), pch); } -/* A wrapper for stat () which disallows pathnames that are empty strings - and handles /dev/fd emulation on systems that don't have it. */ -static int -test_stat (path, finfo) - char *path; - struct stat *finfo; -{ - if (*path == '\0') - { - errno = ENOENT; - return (-1); - } - if (path[0] == '/' && path[1] == 'd' && strncmp (path, "/dev/fd/", 8) == 0) - { -#if !defined (HAVE_DEV_FD) - intmax_t fd; - int r; - - if (legal_number (path + 8, &fd) && fd == (int)fd) - { - r = fstat ((int)fd, finfo); - if (r == 0 || errno != EBADF) - return (r); - } - errno = ENOENT; - return (-1); -#else - /* If HAVE_DEV_FD is defined, DEV_FD_PREFIX is defined also, and has a - trailing slash. Make sure /dev/fd/xx really uses DEV_FD_PREFIX/xx. - On most systems, with the notable exception of linux, this is - effectively a no-op. */ - char pbuf[32]; - strcpy (pbuf, DEV_FD_PREFIX); - strcat (pbuf, path + 8); - return (stat (pbuf, finfo)); -#endif /* !HAVE_DEV_FD */ - } -#if !defined (HAVE_DEV_STDIN) - else if (STREQN (path, "/dev/std", 8)) - { - if (STREQ (path+8, "in")) - return (fstat (0, finfo)); - else if (STREQ (path+8, "out")) - return (fstat (1, finfo)); - else if (STREQ (path+8, "err")) - return (fstat (2, finfo)); - else - return (stat (path, finfo)); - } -#endif /* !HAVE_DEV_STDIN */ - return (stat (path, finfo)); -} - -/* Do the same thing access(2) does, but use the effective uid and gid, - and don't make the mistake of telling root that any file is - executable. */ -int -test_eaccess (path, mode) - char *path; - int mode; -{ - struct stat st; - - if (test_stat (path, &st) < 0) - return (-1); - - if (current_user.euid == 0) - { - /* Root can read or write any file. */ - if (mode != X_OK) - return (0); - - /* Root can execute any file that has any one of the execute - bits set. */ - if (st.st_mode & S_IXUGO) - return (0); - } - - if (st.st_uid == current_user.euid) /* owner */ - mode <<= 6; - else if (group_member (st.st_gid)) - mode <<= 3; - - if (st.st_mode & mode) - return (0); - - errno = EACCES; - return (-1); -} - /* Increment our position in the argument list. Check that we're not past the end of the argument list. This check is supressed if the argument is FALSE. Made a macro for efficiency. */ @@ -394,12 +295,12 @@ filecomp (s, t, op) struct stat st1, st2; int r1, r2; - if ((r1 = test_stat (s, &st1)) < 0) + if ((r1 = sh_stat (s, &st1)) < 0) { if (op == EF) return (FALSE); } - if ((r2 = test_stat (t, &st2)) < 0) + if ((r2 = sh_stat (t, &st2)) < 0) { if (op == EF) return (FALSE); @@ -597,31 +498,31 @@ unary_test (op, arg) { case 'a': /* file exists in the file system? */ case 'e': - return (test_stat (arg, &stat_buf) == 0); + return (sh_stat (arg, &stat_buf) == 0); case 'r': /* file is readable? */ - return (EACCESS (arg, R_OK) == 0); + return (sh_eaccess (arg, R_OK) == 0); case 'w': /* File is writeable? */ - return (EACCESS (arg, W_OK) == 0); + return (sh_eaccess (arg, W_OK) == 0); case 'x': /* File is executable? */ - return (EACCESS (arg, X_OK) == 0); + return (sh_eaccess (arg, X_OK) == 0); case 'O': /* File is owned by you? */ - return (test_stat (arg, &stat_buf) == 0 && + return (sh_stat (arg, &stat_buf) == 0 && (uid_t) current_user.euid == (uid_t) stat_buf.st_uid); case 'G': /* File is owned by your group? */ - return (test_stat (arg, &stat_buf) == 0 && + return (sh_stat (arg, &stat_buf) == 0 && (gid_t) current_user.egid == (gid_t) stat_buf.st_gid); case 'N': - return (test_stat (arg, &stat_buf) == 0 && + return (sh_stat (arg, &stat_buf) == 0 && stat_buf.st_atime <= stat_buf.st_mtime); case 'f': /* File is a file? */ - if (test_stat (arg, &stat_buf) < 0) + if (sh_stat (arg, &stat_buf) < 0) return (FALSE); /* -f is true if the given file exists and is a regular file. */ @@ -632,29 +533,29 @@ unary_test (op, arg) #endif /* !S_IFMT */ case 'd': /* File is a directory? */ - return (test_stat (arg, &stat_buf) == 0 && (S_ISDIR (stat_buf.st_mode))); + return (sh_stat (arg, &stat_buf) == 0 && (S_ISDIR (stat_buf.st_mode))); case 's': /* File has something in it? */ - return (test_stat (arg, &stat_buf) == 0 && stat_buf.st_size > (off_t) 0); + return (sh_stat (arg, &stat_buf) == 0 && stat_buf.st_size > (off_t) 0); case 'S': /* File is a socket? */ #if !defined (S_ISSOCK) return (FALSE); #else - return (test_stat (arg, &stat_buf) == 0 && S_ISSOCK (stat_buf.st_mode)); + return (sh_stat (arg, &stat_buf) == 0 && S_ISSOCK (stat_buf.st_mode)); #endif /* S_ISSOCK */ case 'c': /* File is character special? */ - return (test_stat (arg, &stat_buf) == 0 && S_ISCHR (stat_buf.st_mode)); + return (sh_stat (arg, &stat_buf) == 0 && S_ISCHR (stat_buf.st_mode)); case 'b': /* File is block special? */ - return (test_stat (arg, &stat_buf) == 0 && S_ISBLK (stat_buf.st_mode)); + return (sh_stat (arg, &stat_buf) == 0 && S_ISBLK (stat_buf.st_mode)); case 'p': /* File is a named pipe? */ #ifndef S_ISFIFO return (FALSE); #else - return (test_stat (arg, &stat_buf) == 0 && S_ISFIFO (stat_buf.st_mode)); + return (sh_stat (arg, &stat_buf) == 0 && S_ISFIFO (stat_buf.st_mode)); #endif /* S_ISFIFO */ case 'L': /* Same as -h */ @@ -667,17 +568,17 @@ unary_test (op, arg) #endif /* S_IFLNK && HAVE_LSTAT */ case 'u': /* File is setuid? */ - return (test_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISUID) != 0); + return (sh_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISUID) != 0); case 'g': /* File is setgid? */ - return (test_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISGID) != 0); + return (sh_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISGID) != 0); case 'k': /* File has sticky bit set? */ #if !defined (S_ISVTX) /* This is not Posix, and is not defined on some Posix systems. */ return (FALSE); #else - return (test_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISVTX) != 0); + return (sh_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISVTX) != 0); #endif case 't': /* File fd is a terminal? */ |