minix/test/test17.c
Thomas Veerman a209c3ae12 Fix a ton of compiler warnings
This patch fixes most of current reasons to generate compiler warnings.
The changes consist of:
 - adding missing casts
 - hiding or unhiding function declarations
 - including headers where missing
 - add __UNCONST when assigning a const char * to a char *
 - adding missing return statements
 - changing some types from unsigned to signed, as the code seems to want
   signed ints
 - converting old-style function definitions to current style (i.e.,
   void func(param1, param2) short param1, param2; {...} to
   void func (short param1, short param2) {...})
 - making the compiler silent about signed vs unsigned comparisons. We
   have too many of those in the new libc to fix.

A number of bugs in the test set were fixed. These bugs were never
triggered with our old libc. Consequently, these tests are now forced to
link with the new libc or they will generate errors (in particular tests 43
and 55).

Most changes in NetBSD libc are limited to moving aroudn "#ifndef __minix"
or stuff related to Minix-specific things (code in sys-minix or gen/minix).
2011-11-14 10:07:49 +00:00

1175 lines
31 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Comment on usage and program: ark!/mnt/rene/prac/os/unix/comment.changes */
/* "const.h", created by Rene Montsma and Menno Wilcke */
#include <sys/types.h> /* type defs */
#include <sys/stat.h> /* struct stat */
#include <sys/wait.h>
#include <errno.h> /* the error-numbers */
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <utime.h>
#include <stdio.h>
#include <limits.h>
#include <assert.h>
#define NOCRASH 1 /* test11(), 2nd pipe */
#define PDPNOHANG 1 /* test03(), write_standards() */
#define MAXERR 2
#define USER_ID 12
#define GROUP_ID 1
#define FF 3 /* first free filedes. */
#define USER 1 /* uid */
#define GROUP 0 /* gid */
#define ARSIZE 256 /* array size */
#define PIPESIZE 3584 /* max number of bytes to be written on pipe */
#define MAXOPEN (OPEN_MAX-3) /* maximum number of extra open files */
#define MAXLINK 0177 /* maximum number of links per file */
#define LINKCOUNT 5
#define MASK 0777 /* selects lower nine bits */
#define END_FILE 0 /* returned by read-call at eof */
#define OK 0
#define FAIL -1
#define R 0 /* read (open-call) */
#define W 1 /* write (open-call) */
#define RW 2 /* read & write (open-call) */
#define RWX 7 /* read & write & execute (mode) */
#define NIL ""
#define UMASK "umask"
#define CREAT "creat"
#define WRITE "write"
#define READ "read"
#define OPEN "open"
#define CLOSE "close"
#define LSEEK "lseek"
#define ACCESS "access"
#define CHDIR "chdir"
#define CHMOD "chmod"
#define LINK "link"
#define UNLINK "unlink"
#define PIPE "pipe"
#define STAT "stat"
#define FSTAT "fstat"
#define DUP "dup"
#define UTIME "utime"
int errct;
/* "decl.c", created by Rene Montsma and Menno Wilcke */
/* Used in open_alot, close_alot */
char *filenames[MAXOPEN];
#define MODES 8
char *mode_fnames[MODES] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"},
*mode_dir[MODES] = {"d---", "d--x", "d-w-", "d-wx", "dr--", "dr-x", "drw-", "drwx"};
/* Needed for easy creating and deleting of directories */
/* "test.c", created by Rene Montsma and Menno Wilcke */
_PROTOTYPE(int main, (int argc, char *argv []));
_PROTOTYPE(void test, (int mask));
_PROTOTYPE(void test01, (void));
_PROTOTYPE(void test02, (void));
_PROTOTYPE(void test08, (void));
_PROTOTYPE(void test09, (void));
_PROTOTYPE(void test10, (void));
_PROTOTYPE(int link_alot, (char *bigboss));
_PROTOTYPE(int unlink_alot, (int number));
_PROTOTYPE(void get_new, (char name []));
_PROTOTYPE(void test11, (void));
_PROTOTYPE(void comp_stats, (struct stat *stbf1, struct stat *stbf2));
_PROTOTYPE(void comp_inodes, (int m, int m1));
_PROTOTYPE(void e, (char *string));
_PROTOTYPE(void nlcr, (void));
_PROTOTYPE(void str, (char *s));
_PROTOTYPE(void err, (int number, char *scall, char *name));
_PROTOTYPE(void make_and_fill_dirs, (void));
_PROTOTYPE(void put_file_in_dir, (char *dirname, int mode));
_PROTOTYPE(void init_array, (char *a));
_PROTOTYPE(void clear_array, (char *b));
_PROTOTYPE(int comp_array, (char *a, char *b, int range));
_PROTOTYPE(void try_close, (int filedes, char *name));
_PROTOTYPE(void try_unlink, (char *fname));
_PROTOTYPE(void Remove, (int fdes, char *fname));
_PROTOTYPE(int get_mode, (char *name));
_PROTOTYPE(void check, (char *scall, int number));
_PROTOTYPE(void put, (int nr));
_PROTOTYPE(int open_alot, (void));
_PROTOTYPE(int close_alot, (int number));
_PROTOTYPE(void clean_up_the_mess, (void));
_PROTOTYPE(void chmod_8_dirs, (int sw));
_PROTOTYPE(void quit, (void));
/*****************************************************************************
* TEST *
****************************************************************************/
int main(argc, argv)
int argc;
char *argv[];
{
int n, mask, i;
/* Create filenames for MAXOPEN files, the *filenames[] array. */
for(i = 0; i < MAXOPEN; i++) {
if(asprintf(&filenames[i], "file%d", i) == -1) {
fprintf(stderr, "asprintf failed\n");
return 1;
}
}
sync();
#define DIR "DIR17"
system("rm -rf " DIR);
if(mkdir(DIR, 0755) != 0) {
perror("mkdir");
return 1;
}
if(chdir(DIR) < 0) {
perror("chdir");
return 1;
}
mask = (argc == 2 ? atoi(argv[1]) : 0xFFFF);
if (fork()) {
printf("Test 17 ");
fflush(stdout);
wait(&n);
clean_up_the_mess();
quit();
} else {
test(mask);
exit(0);
}
return(-1); /* impossible */
}
void test(mask)
int mask;
{
umask(0); /* not honest, but i always forget */
if (mask & 00001) test01();
if (mask & 00002) make_and_fill_dirs();
if (mask & 00004) test02();
if (mask & 00010) test08();
if (mask & 00020) test09();
if (mask & 00040) test10();
if (mask & 00100) test11();
umask(022);
} /* test */
/* "t1.c" created by Rene Montsma and Menno Wilcke */
/*****************************************************************************
* test UMASK *
****************************************************************************/
void test01()
{
int oldvalue, newvalue, tempvalue;
int nr;
if ((oldvalue = umask(0777)) != 0) err(0, UMASK, NIL);
/* Special test: only the lower 9 bits (protection bits) may part- *
* icipate. ~0777 means: 111 000 000 000. Giving this to umask must*
* not change any value. */
if ((newvalue = umask(~0777)) != 0777) err(1, UMASK, "illegal");
if (oldvalue == newvalue) err(11, UMASK, "not change mask");
if ((tempvalue = umask(0)) != 0) err(2, UMASK, "values");
/* Now test all possible modes of umask on a file */
for (newvalue = MASK; newvalue >= 0; newvalue -= 0111) {
tempvalue = umask(newvalue);
if (tempvalue != oldvalue) {
err(1, UMASK, "illegal");
break; /* no use trying more */
} else if ((nr = creat("file01", 0777)) < 0)
err(5, CREAT, "'file01'");
else {
try_close(nr, "'file01'");
if (get_mode("file01") != (MASK & ~newvalue))
err(7, UMASK, "mode computed");
try_unlink("file01");
}
oldvalue = newvalue;
}
/* The loop has terminated with umask(0) */
if ((tempvalue = umask(0)) != 0)
err(7, UMASK, "umask may influence rest of tests!");
} /* test01 */
/*****************************************************************************
* test CREAT *
****************************************************************************/
void test02()
{
int n, n1, mode;
char a[ARSIZE], b[ARSIZE];
struct stat stbf1;
mode = 0;
/* Create twenty files, check filedes */
for (n = 0; n < MAXOPEN; n++) {
if (creat(filenames[n], mode) != FF + n)
err(13, CREAT, filenames[n]);
else {
if (get_mode(filenames[n]) != mode)
err(7, CREAT, "mode set while creating many files");
/* Change mode of file to standard mode, we want to *
* use a lot (20) of files to be opened later, see *
* open_alot(), close_alot(). */
if (chmod(filenames[n], 0700) != OK) err(5, CHMOD, filenames[n]);
}
mode = (mode + 0100) % 01000;
}
/* Already twenty files opened; opening another has to fail */
if (creat("file02", 0777) != FAIL)
err(9, CREAT, "created");
else
check(CREAT, EMFILE);
/* Close all files: seems blunt, but it isn't because we've *
* checked all fd's already */
if ((n = close_alot(MAXOPEN)) < MAXOPEN) err(5, CLOSE, "MAXOPEN files");
/* Creat 1 file twice; check */
if ((n = creat("file02", 0777)) < 0)
err(5, CREAT, "'file02'");
else {
init_array(a);
if (write(n, a, ARSIZE) != ARSIZE) err(1, WRITE, "bad");
if ((n1 = creat("file02", 0755)) < 0) /* receate 'file02' */
err(5, CREAT, "'file02' (2nd time)");
else {
/* Fd should be at the top after recreation */
if (lseek(n1, 0L, SEEK_END) != 0)
err(11, CREAT, "not truncate file by recreation");
else {
/* Try to write on recreated file */
clear_array(b);
if (lseek(n1, 0L, SEEK_SET) != 0)
err(5, LSEEK, "to top of 2nd fd 'file02'");
if (write(n1, a, ARSIZE) != ARSIZE)
err(1, WRITE, "(2) bad");
/* In order to read we've to close and open again */
try_close(n1, "'file02' (2nd creation)");
if ((n1 = open("file02", RW)) < 0)
err(5, OPEN, "'file02' (2nd recreation)");
/* Continue */
if (lseek(n1, 0L, SEEK_SET) != 0)
err(5, LSEEK, "to top 'file02'(2nd fd) (2)");
if (read(n1, b, ARSIZE) != ARSIZE)
err(1, READ, "wrong");
if (comp_array(a, b, ARSIZE) != OK) err(11, CREAT,
"not really truncate file by recreation");
}
if (get_mode("file02") != 0777)
err(11, CREAT, "not maintain mode by recreation");
try_close(n1, "recreated 'file02'");
}
Remove(n, "file02");
}
/* Give 'creat' wrong input: dir not searchable */
if (creat("drw-/file02", 0777) != FAIL)
err(4, CREAT, "'drw-'");
else
check(CREAT, EACCES);
/* Dir not writable */
if (creat("dr-x/file02", 0777) != FAIL)
err(12, CREAT, "'dr-x/file02'");
else
check(CREAT, EACCES);
/* File not writable */
if (creat("drwx/r-x", 0777) != FAIL)
err(11, CREAT, "recreate non-writable file");
else
check(CREAT, EACCES);
/* Try to creat a dir */
if ((n = creat("dir", 040777)) != FAIL) {
if (fstat(n, &stbf1) != OK)
err(5, FSTAT, "'dir'");
else if (stbf1.st_mode != (mode_t) 0100777)
/* cast because mode is negative :-( */
err(11, CREAT, "'creat' a new directory");
Remove(n, "dir");
}
/* We don't consider it to be a bug when creat * does not accept
* tricky modes */
/* File is an existing dir */
if (creat("drwx", 0777) != FAIL)
err(11, CREAT, "create an existing dir!");
else
check(CREAT, EISDIR);
} /* test02 */
void test08()
{
/* Test chdir to searchable dir */
if (chdir("drwx") != OK)
err(5, CHDIR, "to accessible dir");
else if (chdir("..") != OK)
err(11, CHDIR, "not return to '..'");
/* Check the chdir(".") and chdir("..") mechanism */
if (chdir("drwx") != OK)
err(5, CHDIR, "to 'drwx'");
else {
if (chdir(".") != OK) err(5, CHDIR, "to working dir (.)");
/* If we still are in 'drwx' , we should be able to access *
* file 'rwx'. */
if (access("rwx", 0) != OK) err(5, CHDIR, "rightly to '.'");
/* Try to return to previous dir ('/' !!) */
if (chdir("././../././d--x/../d--x/././..") != OK)
err(5, CHDIR, "to motherdir (..)");
/* Check whether we are back in '/' */
if (chdir("d--x") != OK) err(5, CHDIR, "rightly to a '..'");
}
/* Return to '..' */
if (chdir("..") != OK) err(5, CHDIR, "to '..'");
if (chdir("././././drwx") != OK)
err(11, CHDIR, "not follow a path");
else if (chdir("././././..") != OK)
err(11, CHDIR, "not return to path");
/* Try giving chdir wrong parameters */
if (chdir("drwx/rwx") != FAIL)
err(11, CHDIR, "chdir to a file");
else
check(CHDIR, ENOTDIR);
if (chdir("drw-") != FAIL)
err(4, CHDIR, "'/drw-'");
else
check(CHDIR, EACCES);
/* To be sure: return to root */
/* If (chdir("/") != OK) err(5, CHDIR, "to '/' (2nd time)"); */
} /* test08 */
/* New page */
/*****************************************************************************
* test CHMOD *
****************************************************************************/
void test09()
{
int n;
/* Prepare file09 */
if ((n = creat("drwx/file09", 0644)) != FF) err(5, CREAT, "'drwx/file09'");
try_close(n, "'file09'");
/* Try to chmod a file, check and restore old values, check */
if (chmod("drwx/file09", 0700) != OK)
err(5, CHMOD, "'drwx/file09'"); /* set rwx */
else {
/* Check protection */
if (get_mode("drwx/file09") != 0700) err(7, CHMOD, "mode");
/* Test if chmod accepts just filenames too */
if (chdir("drwx") != OK)
err(5, CHDIR, "to '/drwx'");
else if (chmod("file09", 0177) != OK) /* restore oldies */
err(5, CHMOD, "'h1'");
else
/* Check if value has been restored */
if (get_mode("../drwx/file09") != 0177)
err(7, CHMOD, "restored mode");
}
/* Try setuid and setgid */
if ((chmod("file09", 04777) != OK) || (get_mode("file09") != 04777))
err(11, CHMOD, "not set uid-bit");
if ((chmod("file09", 02777) != OK) || (get_mode("file09") != 02777))
err(11, CHMOD, "not set gid-bit");
/* Remove testfile */
try_unlink("file09");
if (chdir("..") != OK) err(5, CHDIR, "to '..'");
/* Try to chmod directory */
if (chmod("d---", 0777) != OK)
err(5, CHMOD, "dir 'd---'");
else {
if (get_mode("d---") != 0777) err(7, CHMOD, "protection value");
if (chmod("d---", 0000) != OK) err(5, CHMOD, "dir 'a' 2nd time");
/* Check if old value has been restored */
if (get_mode("d---") != 0000)
err(7, CHMOD, "restored protection value");
}
/* Try to make chmod failures */
/* We still are in dir root */
/* Wrong filename */
if (chmod("non-file", 0777) != FAIL)
err(3, CHMOD, NIL);
else
check(CHMOD, ENOENT);
} /* test 09 */
/* New page */
/* "t4.c", created by Rene Montsma and Menno Wilcke */
/*****************************************************************************
* test LINK/UNLINK *
****************************************************************************/
void test10()
{
int n, n1;
char a[ARSIZE], b[ARSIZE], *f, *lf;
f = "anotherfile10";
lf = "linkfile10";
if ((n = creat(f, 0702)) != FF) /* no other open files */
err(13, CREAT, f);
else {
/* Now link correctly */
if (link(f, lf) != OK)
err(5, LINK, lf);
else if ((n1 = open(lf, RW)) < 0)
err(5, OPEN, "'linkfile10'");
else {
init_array(a);
clear_array(b);
/* Write on 'file10' means being able to * read
* through linked filedescriptor */
if (write(n, a, ARSIZE) != ARSIZE) err(1, WRITE, "bad");
if (read(n1, b, ARSIZE) != ARSIZE) err(1, READ, "bad");
if (comp_array(a, b, ARSIZE) != OK) err(8, "r/w", NIL);
/* Clean up: unlink and close (twice): */
Remove(n, f);
try_close(n1, "'linkfile10'");
/* Check if "linkfile" exists and the info * on it
* is correct ('file' has been deleted) */
if ((n1 = open(lf, R)) < 0)
err(5, OPEN, "'linkfile10'");
else {
/* See if 'linkfile' still contains 0..511 ? */
clear_array(b);
if (read(n1, b, ARSIZE) != ARSIZE)
err(1, READ, "bad");
if (comp_array(a, b, ARSIZE) != OK)
err(8, "r/w", NIL);
try_close(n1, "'linkfile10' 2nd time");
try_unlink(lf);
}
}
}
/* Try if unlink fails with incorrect parameters */
/* File does not exist: */
if (unlink("non-file") != FAIL)
err(2, UNLINK, "name");
else
check(UNLINK, ENOENT);
/* Dir can't be written */
if (unlink("dr-x/rwx") != FAIL)
err(11, UNLINK, "could unlink in non-writable dir.");
else
check(UNLINK, EACCES);
/* Try to unlink a dir being user */
if (unlink("drwx") != FAIL)
err(11, UNLINK, "unlink dir's as user");
else
check(UNLINK, EPERM);
/* Try giving link wrong input */
/* First try if link fails with incorrect parameters * name1 does not
* exist. */
if (link("non-file", "linkfile") != FAIL)
err(2, LINK, "1st name");
else
check(LINK, ENOENT);
/* Name2 exists already */
if (link("drwx/rwx", "drwx/rw-") != FAIL)
err(2, LINK, "2nd name");
else
check(LINK, EEXIST);
/* Directory of name2 not writable: */
if (link("drwx/rwx", "dr-x/linkfile") != FAIL)
err(11, LINK, "link non-writable file");
else
check(LINK, EACCES);
/* Try to link a dir, being a user */
if (link("drwx", "linkfile") != FAIL)
err(11, LINK, "link a dir without superuser!");
else
check(LINK, EPERM);
/* File has too many links */
if ((n = link_alot("drwx/rwx")) != LINKCOUNT - 1) /* file already has one
* link */
err(5, LINK, "many files");
if (unlink_alot(n) != n) err(5, UNLINK, "all linked files");
} /* test10 */
int link_alot(bigboss)
char *bigboss;
{
int i;
static char employee[6] = "aaaaa";
/* Every file has already got 1 link, so link 0176 times */
for (i = 1; i < LINKCOUNT; i++) {
if (link(bigboss, employee) != OK)
break;
else
get_new(employee);
}
return(i - 1); /* number of linked files */
} /* link_alot */
int unlink_alot(number)
int number; /* number of files to be unlinked */
{
int j;
static char employee[6] = "aaaaa";
for (j = 0; j < number; j++) {
if (unlink(employee) != OK)
break;
else
get_new(employee);
}
return(j); /* return number of unlinked files */
} /* unlink_alot */
void get_new(name)
char name[];
/* Every call changes string 'name' to a string alphabetically *
* higher. Start with "aaaaa", next value: "aaaab" . *
* N.B. after "aaaaz" comes "aaabz" and not "aaaba" (not needed). *
* The last possibility will be "zzzzz". *
* Total # possibilities: 26+25*4 = 126 = MAXLINK -1 (exactly needed) */
{
int i;
for (i = 4; i >= 0; i--)
if (name[i] != 'z') {
name[i]++;
break;
}
} /* get_new */
/* New page */
/*****************************************************************************
* test PIPE *
****************************************************************************/
void test11()
{
int n, fd[2];
char a[ARSIZE], b[ARSIZE];
if (pipe(fd) != OK)
err(13, PIPE, NIL);
else {
/* Try reading and writing on a pipe */
init_array(a);
clear_array(b);
if (write(fd[1], a, ARSIZE) != ARSIZE)
err(5, WRITE, "on pipe");
else if (read(fd[0], b, (ARSIZE / 2)) != (ARSIZE / 2))
err(5, READ, "on pipe (2nd time)");
else if (comp_array(a, b, (ARSIZE / 2)) != OK)
err(7, PIPE, "values read/written");
else if (read(fd[0], b, (ARSIZE / 2)) != (ARSIZE / 2))
err(5, READ, "on pipe 2");
else if (comp_array(&a[ARSIZE / 2], b, (ARSIZE / 2)) != OK)
err(7, PIPE, "pipe created");
/* Try to let the pipe make a mistake */
if (write(fd[0], a, ARSIZE) != FAIL)
err(11, WRITE, "write on fd[0]");
if (read(fd[1], b, ARSIZE) != FAIL) err(11, READ, "read on fd[1]");
try_close(fd[1], "'fd[1]'");
/* Now we shouldn't be able to read, because fd[1] has been closed */
if (read(fd[0], b, ARSIZE) != END_FILE) err(2, PIPE, "'fd[1]'");
try_close(fd[0], "'fd[0]'");
}
if (pipe(fd) < 0)
err(5, PIPE, "2nd time");
else {
/* Test lseek on a pipe: should fail */
if (write(fd[1], a, ARSIZE) != ARSIZE)
err(5, WRITE, "on pipe (2nd time)");
if (lseek(fd[1], 10L, SEEK_SET) != FAIL)
err(11, LSEEK, "lseek on a pipe");
else
check(PIPE, ESPIPE);
/* Eat half of the pipe: no writing should be possible */
try_close(fd[0], "'fd[0]' (2nd time)");
/* This makes UNIX crash: omit it if pdp or VAX */
#ifndef NOCRASH
if (write(fd[1], a, ARSIZE) != FAIL)
err(11, WRITE, "write on wrong pipe");
else
check(PIPE, EPIPE);
#endif
try_close(fd[1], "'fd[1]' (2nd time)");
}
/* BUG : *
* Here we planned to test if we could write 4K bytes on a pipe. *
* However, this was not possible to implement, because the whole *
* Monix system crashed when we tried to write more then 3584 bytes *
* (3.5K) on a pipe. That's why we try to write only 3.5K in the *
* folowing test. */
if (pipe(fd) < 0)
err(5, PIPE, "3rd time");
else {
for (n = 0; n < (PIPESIZE / ARSIZE); n++)
if (write(fd[1], a, ARSIZE) != ARSIZE)
err(5, WRITE, "on pipe (3rd time) 4K");
try_close(fd[1], "'fd[1]' (3rd time)");
for (n = 0; n < (PIPESIZE / ARSIZE); n++)
if (read(fd[0], b, ARSIZE) != ARSIZE)
err(5, READ, "from pipe (3rd time) 4K");
try_close(fd[0], "'fd[0]' (3rd time)");
}
/* Test opening a lot of files */
if ((n = open_alot()) != MAXOPEN) err(5, OPEN, "MAXOPEN files");
if (pipe(fd) != FAIL)
err(9, PIPE, "open");
else
check(PIPE, EMFILE);
if (close_alot(n) != n) err(5, CLOSE, "all opened files");
} /* test11 */
/* New page */
void comp_stats(stbf1, stbf2)
struct stat *stbf1, *stbf2;
{
if (stbf1->st_dev != stbf2->st_dev) err(7, "st/fst", "'dev'");
if (stbf1->st_ino != stbf2->st_ino) err(7, "st/fst", "'ino'");
if (stbf1->st_mode != stbf2->st_mode) err(7, "st/fst", "'mode'");
if (stbf1->st_nlink != stbf2->st_nlink) err(7, "st/fst", "'nlink'");
if (stbf1->st_uid != stbf2->st_uid) err(7, "st/fst", "'uid'");
if (stbf1->st_gid != stbf2->st_gid) err(7, "st/fst", "'gid'");
if (stbf1->st_rdev != stbf2->st_rdev) err(7, "st/fst", "'rdev'");
if (stbf1->st_size != stbf2->st_size) err(7, "st/fst", "'size'");
if (stbf1->st_atime != stbf2->st_atime) err(7, "st/fst", "'atime'");
if (stbf1->st_mtime != stbf2->st_mtime) err(7, "st/fst", "'mtime'");
} /* comp_stats */
/* New page */
/* "t5.c", created by Rene Montsma and Menno Wilcke */
void comp_inodes(m, m1)
int m, m1; /* twee filedes's */
{
struct stat stbf1, stbf2;
if (fstat(m, &stbf1) == OK)
if (fstat(m1, &stbf2) == OK) {
if (stbf1.st_ino != stbf2.st_ino)
err(7, DUP, "inode number");
} else
err(100, "comp_inodes", "cannot 'fstat' (m1)");
else
err(100, "comp_inodes", "cannot 'fstat' (m)");
} /* comp_inodes */
/* "support.c", created by Rene Montsma and Menno Wilcke */
/* Err, make_and_fill_dirs, init_array, clear_array, comp_array,
try_close, try_unlink, Remove, get_mode, check, open_alot,
close_alot, clean_up_the_mess.
*/
/***********************************************************************
* EXTENDED FIONS *
**********************************************************************/
/* First extended functions (i.e. not oldfashioned monixcalls.
e(), nlcr(), octal.*/
void e(string)
char *string;
{
printf("Error: %s ", string);
}
void nlcr()
{
fputs("\n",stdout);
}
void str(char *s)
{
fputs(s,stdout);
}
/*****************************************************************************
* *
* ERR(or) messages *
* *
*****************************************************************************/
void err(number, scall, name)
/* Give nice error messages */
char *scall, *name;
int number;
{
errct++;
if (errct > MAXERR) {
printf("Too many errors; test aborted\n");
quit();
}
e("");
str("\t");
switch (number) {
case 0:
str(scall);
str(": illegal initial value.");
break;
case 1:
str(scall);
str(": ");
str(name);
str(" value returned.");
break;
case 2:
str(scall);
str(": accepting illegal ");
str(name);
str(".");
break;
case 3:
str(scall);
str(": accepting non-existing file.");
break;
case 4:
str(scall);
str(": could search non-searchable dir (");
str(name);
str(").");
break;
case 5:
str(scall);
str(": cannot ");
str(scall);
str(" ");
str(name);
str(".");
break;
case 7:
str(scall);
str(": incorrect ");
str(name);
str(".");
break;
case 8:
str(scall);
str(": wrong values.");
break;
case 9:
str(scall);
str(": accepting too many ");
str(name);
str(" files.");
break;
case 10:
str(scall);
str(": even a superuser can't do anything!");
break;
case 11:
str(scall);
str(": could ");
str(name);
str(".");
break;
case 12:
str(scall);
str(": could write in non-writable dir (");
str(name);
str(").");
break;
case 13:
str(scall);
str(": wrong filedes returned (");
str(name);
str(").");
break;
case 100:
str(scall); /* very common */
str(": ");
str(name);
str(".");
break;
default: str("errornumber does not exist!\n");
}
nlcr();
} /* err */
/*****************************************************************************
* *
* MAKE_AND_FILL_DIRS *
* *
*****************************************************************************/
void make_and_fill_dirs()
/* Create 8 dir.'s: "d---", "d--x", "d-w-", "d-wx", "dr--", "dr-x", *
* "drw-", "drwx". * Then create 8 files
* in "drwx", and some needed files in other dirs. */
{
int mode, i;
for (i = 0; i < MODES; i++) {
mkdir(mode_dir[i], 0700);
chown(mode_dir[i], USER_ID, GROUP_ID);
}
setuid(USER_ID);
setgid(GROUP_ID);
for (mode = 0; mode < 8; mode++) put_file_in_dir("drwx", mode);
put_file_in_dir("d-wx", RWX);
put_file_in_dir("dr-x", RWX);
put_file_in_dir("drw-", RWX);
chmod_8_dirs(8); /* 8 means; 8 different modes */
} /* make_and_fill_dirs */
void put_file_in_dir(dirname, mode)
char *dirname;
int mode;
/* Fill directory 'dirname' with file with mode 'mode'. */
{
int nr;
if (chdir(dirname) != OK)
err(5, CHDIR, "to dirname (put_f_in_dir)");
else {
/* Creat the file */
assert(mode >= 0 && mode < MODES);
if ((nr = creat(mode_fnames[mode], mode * 0100)) < 0)
err(13, CREAT, mode_fnames[mode]);
else {
try_close(nr, mode_fnames[mode]);
}
if (chdir("..") != OK)
err(5, CHDIR, "to previous dir (put_f_in_dir)");
}
} /* put_file_in_dir */
/*****************************************************************************
* *
* MISCELLANEOUS *
* *
*(all about arrays, 'try_close', 'try_unlink', 'Remove', 'get_mode')*
* *
*****************************************************************************/
void init_array(a)
char *a;
{
int i;
i = 0;
while (i++ < ARSIZE) *a++ = 'a' + (i % 26);
} /* init_array */
void clear_array(b)
char *b;
{
int i;
i = 0;
while (i++ < ARSIZE) *b++ = '0';
} /* clear_array */
int comp_array(a, b, range)
char *a, *b;
int range;
{
if ((range < 0) || (range > ARSIZE)) {
err(100, "comp_array", "illegal range");
return(FAIL);
} else {
while (range-- && (*a++ == *b++));
if (*--a == *--b)
return(OK);
else
return(FAIL);
}
} /* comp_array */
void try_close(filedes, name)
int filedes;
char *name;
{
if (close(filedes) != OK) err(5, CLOSE, name);
} /* try_close */
void try_unlink(fname)
char *fname;
{
if (unlink(fname) != 0) err(5, UNLINK, fname);
} /* try_unlink */
void Remove(fdes, fname)
int fdes;
char *fname;
{
try_close(fdes, fname);
try_unlink(fname);
} /* Remove */
int get_mode(name)
char *name;
{
struct stat stbf1;
if (stat(name, &stbf1) != OK) {
err(5, STAT, name);
return(stbf1.st_mode); /* return a mode which will cause *
* error in the calling function *
* (file/dir bit) */
} else
return(stbf1.st_mode & 07777); /* take last 4 bits */
} /* get_mode */
/*****************************************************************************
* *
* CHECK *
* *
*****************************************************************************/
void check(scall, number)
int number;
char *scall;
{
if (errno != number) {
e(NIL);
str("\t");
str(scall);
str(": bad errno-value: ");
put(errno);
str(" should have been: ");
put(number);
nlcr();
}
} /* check */
void put(nr)
int nr;
{
switch (nr) {
case 0: str("unused"); break;
case 1: str("EPERM"); break;
case 2: str("ENOENT"); break;
case 3: str("ESRCH"); break;
case 4: str("EINTR"); break;
case 5: str("EIO"); break;
case 6: str("ENXIO"); break;
case 7: str("E2BIG"); break;
case 8: str("ENOEXEC"); break;
case 9: str("EBADF"); break;
case 10: str("ECHILD"); break;
case 11: str("EAGAIN"); break;
case 12: str("ENOMEM"); break;
case 13: str("EACCES"); break;
case 14: str("EFAULT"); break;
case 15: str("ENOTBLK"); break;
case 16: str("EBUSY"); break;
case 17: str("EEXIST"); break;
case 18: str("EXDEV"); break;
case 19: str("ENODEV"); break;
case 20: str("ENOTDIR"); break;
case 21: str("EISDIR"); break;
case 22: str("EINVAL"); break;
case 23: str("ENFILE"); break;
case 24: str("EMFILE"); break;
case 25: str("ENOTTY"); break;
case 26: str("ETXTBSY"); break;
case 27: str("EFBIG"); break;
case 28: str("ENOSPC"); break;
case 29: str("ESPIPE"); break;
case 30: str("EROFS"); break;
case 31: str("EMLINK"); break;
case 32: str("EPIPE"); break;
case 33: str("EDOM"); break;
case 34: str("ERANGE"); break;
}
}
/*****************************************************************************
* *
* ALOT-functions *
* *
*****************************************************************************/
int open_alot()
{
int i;
for (i = 0; i < MAXOPEN; i++)
if (open(filenames[i], R) == FAIL) break;
if (i == 0) err(5, "open_alot", "at all");
return(i);
} /* open_alot */
int close_alot(number)
int number;
{
int i, count = 0;
if (number > MAXOPEN)
err(5, "close_alot", "accept this argument");
else
for (i = FF; i < number + FF; i++)
if (close(i) != OK) count++;
return(number - count); /* return number of closed files */
} /* close_alot */
/*****************************************************************************
* *
* CLEAN UP THE MESS *
* *
*****************************************************************************/
void clean_up_the_mess()
{
int i;
char dirname[6];
/* First remove 'a lot' files */
for (i = 0; i < MAXOPEN; i++) {
try_unlink(filenames[i]);
}
/* Unlink the files in dir 'drwx' */
if (chdir("drwx") != OK)
err(5, CHDIR, "to 'drwx'");
else {
for (i = 0; i < MODES; i++) {
try_unlink(mode_fnames[i]);
}
if (chdir("..") != OK) err(5, CHDIR, "to '..'");
}
/* Before unlinking files in some dirs, make them writable */
chmod_8_dirs(RWX);
/* Unlink files in other dirs */
try_unlink("d-wx/rwx");
try_unlink("dr-x/rwx");
try_unlink("drw-/rwx");
/* Unlink dirs */
for (i = 0; i < MODES; i++) {
strcpy(dirname, "d");
strcat(dirname, mode_fnames[i]);
/* 'dirname' contains the directoryname */
rmdir(dirname);
}
/* FINISH */
} /* clean_up_the_mess */
void chmod_8_dirs(sw)
int sw; /* if switch == 8, give all different
* mode,else the same mode */
{
int mode;
int i;
if (sw == 8)
mode = 0;
else
mode = sw;
for (i = 0; i < MODES; i++) {
chmod(mode_dir[i], 040000 + mode * 0100);
if (sw == 8) mode++;
}
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}