00001
00002
00003
00004
00005 #include <sys/types.h>
00006 #include <sys/stat.h>
00007 #include <sys/wait.h>
00008 #include <errno.h>
00009 #include <fcntl.h>
00010 #include <stdlib.h>
00011 #include <string.h>
00012 #include <unistd.h>
00013 #include <utime.h>
00014 #include <stdio.h>
00015 #include <limits.h>
00016
00017 #define NOCRASH 1
00018 #define PDPNOHANG 1
00019 #define MAXERR 2
00020
00021 #define USER_ID 12
00022 #define GROUP_ID 1
00023 #define FF 3
00024 #define USER 1
00025 #define GROUP 0
00026
00027 #define ARSIZE 256
00028 #define PIPESIZE 3584
00029 #define MAXOPEN (OPEN_MAX-3)
00030 #define MAXLINK 0177
00031 #define LINKCOUNT 5
00032 #define MASK 0777
00033 #define END_FILE 0
00034
00035 #define OK 0
00036 #define FAIL -1
00037
00038 #define R 0
00039 #define W 1
00040 #define RW 2
00041
00042 #define RWX 7
00043
00044 #define NIL ""
00045 #define UMASK "umask"
00046 #define CREAT "creat"
00047 #define WRITE "write"
00048 #define READ "read"
00049 #define OPEN "open"
00050 #define CLOSE "close"
00051 #define LSEEK "lseek"
00052 #define ACCESS "access"
00053 #define CHDIR "chdir"
00054 #define CHMOD "chmod"
00055 #define LINK "link"
00056 #define UNLINK "unlink"
00057 #define PIPE "pipe"
00058 #define STAT "stat"
00059 #define FSTAT "fstat"
00060 #define DUP "dup"
00061 #define UTIME "utime"
00062
00063 int errct;
00064
00065 char *file[];
00066 char *fnames[];
00067 char *dir[];
00068
00069
00070
00071
00072 char *file[20] = {"f0", "f1", "f2", "f3", "f4", "f5", "f6",
00073 "f7", "f8", "f9", "f10", "f11", "f12", "f13",
00074 "f14", "f15", "f16", "f17", "f18", "f19"}, *fnames[8] = {"---", "--x", "-w-", "-wx", "r--",
00075 "r-x", "rw-", "rwx"}, *dir[8] = {"d---", "d--x", "d-w-", "d-wx", "dr--", "dr-x",
00076 "drw-", "drwx"};
00077
00078
00079
00080
00081 _PROTOTYPE(int main, (int argc, char *argv []));
00082 _PROTOTYPE(void test, (int mask));
00083 _PROTOTYPE(void test01, (void));
00084 _PROTOTYPE(void test02, (void));
00085 _PROTOTYPE(void test08, (void));
00086 _PROTOTYPE(void test09, (void));
00087 _PROTOTYPE(void test10, (void));
00088 _PROTOTYPE(int link_alot, (char *bigboss));
00089 _PROTOTYPE(int unlink_alot, (int number));
00090 _PROTOTYPE(void get_new, (char name []));
00091 _PROTOTYPE(void test11, (void));
00092 _PROTOTYPE(void comp_stats, (struct stat *stbf1, struct stat *stbf2));
00093 _PROTOTYPE(void comp_inodes, (int m, int m1));
00094 _PROTOTYPE(void e, (char *string));
00095 _PROTOTYPE(void nlcr, (void));
00096 _PROTOTYPE(void str, (char *s));
00097 _PROTOTYPE(void err, (int number, char *scall, char *name));
00098 _PROTOTYPE(void make_and_fill_dirs, (void));
00099 _PROTOTYPE(void put_file_in_dir, (char *dirname, int mode));
00100 _PROTOTYPE(void init_array, (char *a));
00101 _PROTOTYPE(void clear_array, (char *b));
00102 _PROTOTYPE(int comp_array, (char *a, char *b, int range));
00103 _PROTOTYPE(void try_close, (int filedes, char *name));
00104 _PROTOTYPE(void try_unlink, (char *fname));
00105 _PROTOTYPE(void Remove, (int fdes, char *fname));
00106 _PROTOTYPE(int get_mode, (char *name));
00107 _PROTOTYPE(void check, (char *scall, int number));
00108 _PROTOTYPE(void put, (int nr));
00109 _PROTOTYPE(int open_alot, (void));
00110 _PROTOTYPE(int close_alot, (int number));
00111 _PROTOTYPE(void clean_up_the_mess, (void));
00112 _PROTOTYPE(void chmod_8_dirs, (int sw));
00113 _PROTOTYPE(void quit, (void));
00114
00115
00116
00117
00118 int main(argc, argv)
00119 int argc;
00120 char *argv[];
00121 {
00122 int n, mask;
00123
00124 sync();
00125 if (geteuid() == 0 || getuid() == 0) {
00126 printf("Test 17 cannot run as root; test aborted\n");
00127 exit(1);
00128 }
00129
00130 system("rm -rf DIR_18; mkdir DIR_18");
00131 chdir("DIR_18");
00132
00133 mask = (argc == 2 ? atoi(argv[1]) : 0xFFFF);
00134
00135 if (fork()) {
00136 printf("Test 17 ");
00137 fflush(stdout);
00138
00139 wait(&n);
00140 clean_up_the_mess();
00141 quit();
00142 } else {
00143 test(mask);
00144 exit(0);
00145 }
00146 return(-1);
00147 }
00148
00149 void test(mask)
00150 int mask;
00151 {
00152 umask(0);
00153
00154 if (mask & 00001) test01();
00155 if (mask & 00002) make_and_fill_dirs();
00156 if (mask & 00004) test02();
00157 if (mask & 00010) test08();
00158 if (mask & 00020) test09();
00159 if (mask & 00040) test10();
00160 if (mask & 00100) test11();
00161 umask(022);
00162 }
00163
00164
00165
00166
00167
00168
00169 void test01()
00170 {
00171 int oldvalue, newvalue, tempvalue;
00172 int nr;
00173
00174 if ((oldvalue = umask(0777)) != 0) err(0, UMASK, NIL);
00175
00176
00177
00178
00179
00180 if ((newvalue = umask(~0777)) != 0777) err(1, UMASK, "illegal");
00181 if (oldvalue == newvalue) err(11, UMASK, "not change mask");
00182
00183 if ((tempvalue = umask(0)) != 0) err(2, UMASK, "values");
00184
00185
00186 for (newvalue = MASK; newvalue >= 0; newvalue -= 0111) {
00187 tempvalue = umask(newvalue);
00188 if (tempvalue != oldvalue) {
00189 err(1, UMASK, "illegal");
00190 break;
00191 } else if ((nr = creat("file01", 0777)) < 0)
00192 err(5, CREAT, "'file01'");
00193 else {
00194 try_close(nr, "'file01'");
00195 if (get_mode("file01") != (MASK & ~newvalue))
00196 err(7, UMASK, "mode computed");
00197 try_unlink("file01");
00198 }
00199 oldvalue = newvalue;
00200 }
00201
00202
00203 if ((tempvalue = umask(0)) != 0)
00204 err(7, UMASK, "umask may influence rest of tests!");
00205 }
00206
00207
00208
00209
00210 void test02()
00211 {
00212 int n, n1, mode;
00213 char a[ARSIZE], b[ARSIZE];
00214 struct stat stbf1;
00215
00216 mode = 0;
00217
00218 for (n = 0; n < MAXOPEN; n++) {
00219 if (creat(file[n], mode) != FF + n)
00220 err(13, CREAT, file[n]);
00221 else {
00222 if (get_mode(file[n]) != mode)
00223 err(7, CREAT, "mode set while creating many files");
00224
00225
00226
00227
00228 if (chmod(file[n], 0700) != OK) err(5, CHMOD, file[n]);
00229
00230 }
00231 mode = (mode + 0100) % 01000;
00232 }
00233
00234
00235 if (creat("file02", 0777) != FAIL)
00236 err(9, CREAT, "created");
00237 else
00238 check(CREAT, EMFILE);
00239
00240
00241
00242 if ((n = close_alot(MAXOPEN)) < MAXOPEN) err(5, CLOSE, "MAXOPEN files");
00243
00244
00245 if ((n = creat("file02", 0777)) < 0)
00246 err(5, CREAT, "'file02'");
00247 else {
00248 init_array(a);
00249 if (write(n, a, ARSIZE) != ARSIZE) err(1, WRITE, "bad");
00250
00251 if ((n1 = creat("file02", 0755)) < 0)
00252 err(5, CREAT, "'file02' (2nd time)");
00253 else {
00254
00255 if (lseek(n1, 0L, SEEK_END) != 0)
00256 err(11, CREAT, "not truncate file by recreation");
00257 else {
00258
00259 clear_array(b);
00260
00261 if (lseek(n1, 0L, SEEK_SET) != 0)
00262 err(5, LSEEK, "to top of 2nd fd 'file02'");
00263 if (write(n1, a, ARSIZE) != ARSIZE)
00264 err(1, WRITE, "(2) bad");
00265
00266
00267 try_close(n1, "'file02' (2nd creation)");
00268 if ((n1 = open("file02", RW)) < 0)
00269 err(5, OPEN, "'file02' (2nd recreation)");
00270
00271
00272 if (lseek(n1, 0L, SEEK_SET) != 0)
00273 err(5, LSEEK, "to top 'file02'(2nd fd) (2)");
00274 if (read(n1, b, ARSIZE) != ARSIZE)
00275 err(1, READ, "wrong");
00276
00277 if (comp_array(a, b, ARSIZE) != OK) err(11, CREAT,
00278 "not really truncate file by recreation");
00279 }
00280 if (get_mode("file02") != 0777)
00281 err(11, CREAT, "not maintain mode by recreation");
00282 try_close(n1, "recreated 'file02'");
00283
00284 }
00285 Remove(n, "file02");
00286 }
00287
00288
00289 if (creat("drw-/file02", 0777) != FAIL)
00290 err(4, CREAT, "'drw-'");
00291 else
00292 check(CREAT, EACCES);
00293
00294
00295 if (creat("dr-x/file02", 0777) != FAIL)
00296 err(12, CREAT, "'dr-x/file02'");
00297 else
00298 check(CREAT, EACCES);
00299
00300
00301 if (creat("drwx/r-x", 0777) != FAIL)
00302 err(11, CREAT, "recreate non-writable file");
00303 else
00304 check(CREAT, EACCES);
00305
00306
00307 if ((n = creat("dir", 040777)) != FAIL) {
00308 if (fstat(n, &stbf1) != OK)
00309 err(5, FSTAT, "'dir'");
00310 else if (stbf1.st_mode != (mode_t) 0100777)
00311
00312 err(11, CREAT, "'creat' a new directory");
00313 Remove(n, "dir");
00314 }
00315
00316
00317
00318
00319
00320 if (creat("drwx", 0777) != FAIL)
00321 err(11, CREAT, "create an existing dir!");
00322 else
00323 check(CREAT, EISDIR);
00324 }
00325
00326 void test08()
00327 {
00328
00329 if (chdir("drwx") != OK)
00330 err(5, CHDIR, "to accessible dir");
00331 else if (chdir("..") != OK)
00332 err(11, CHDIR, "not return to '..'");
00333
00334
00335 if (chdir("drwx") != OK)
00336 err(5, CHDIR, "to 'drwx'");
00337 else {
00338 if (chdir(".") != OK) err(5, CHDIR, "to working dir (.)");
00339
00340
00341
00342 if (access("rwx", 0) != OK) err(5, CHDIR, "rightly to '.'");
00343
00344
00345 if (chdir("././../././d--x/../d--x/././..") != OK)
00346 err(5, CHDIR, "to motherdir (..)");
00347
00348
00349 if (chdir("d--x") != OK) err(5, CHDIR, "rightly to a '..'");
00350 }
00351
00352
00353 if (chdir("..") != OK) err(5, CHDIR, "to '..'");
00354
00355 if (chdir("././././drwx") != OK)
00356 err(11, CHDIR, "not follow a path");
00357 else if (chdir("././././..") != OK)
00358 err(11, CHDIR, "not return to path");
00359
00360
00361 if (chdir("drwx/rwx") != FAIL)
00362 err(11, CHDIR, "chdir to a file");
00363 else
00364 check(CHDIR, ENOTDIR);
00365
00366 if (chdir("drw-") != FAIL)
00367 err(4, CHDIR, "'/drw-'");
00368 else
00369 check(CHDIR, EACCES);
00370
00371
00372
00373 }
00374
00375
00376
00377
00378
00379 void test09()
00380 {
00381 int n;
00382
00383
00384 if ((n = creat("drwx/file09", 0644)) != FF) err(5, CREAT, "'drwx/file09'");
00385
00386 try_close(n, "'file09'");
00387
00388
00389 if (chmod("drwx/file09", 0700) != OK)
00390 err(5, CHMOD, "'drwx/file09'");
00391 else {
00392
00393 if (get_mode("drwx/file09") != 0700) err(7, CHMOD, "mode");
00394
00395
00396 if (chdir("drwx") != OK)
00397 err(5, CHDIR, "to '/drwx'");
00398 else if (chmod("file09", 0177) != OK)
00399 err(5, CHMOD, "'h1'");
00400 else
00401
00402 if (get_mode("../drwx/file09") != 0177)
00403 err(7, CHMOD, "restored mode");
00404 }
00405
00406
00407 if ((chmod("file09", 04777) != OK) || (get_mode("file09") != 04777))
00408 err(11, CHMOD, "not set uid-bit");
00409 if ((chmod("file09", 02777) != OK) || (get_mode("file09") != 02777))
00410 err(11, CHMOD, "not set gid-bit");
00411
00412
00413 try_unlink("file09");
00414
00415 if (chdir("..") != OK) err(5, CHDIR, "to '..'");
00416
00417
00418 if (chmod("d---", 0777) != OK)
00419 err(5, CHMOD, "dir 'd---'");
00420 else {
00421 if (get_mode("d---") != 0777) err(7, CHMOD, "protection value");
00422 if (chmod("d---", 0000) != OK) err(5, CHMOD, "dir 'a' 2nd time");
00423
00424
00425 if (get_mode("d---") != 0000)
00426 err(7, CHMOD, "restored protection value");
00427 }
00428
00429
00430
00431
00432
00433 if (chmod("non-file", 0777) != FAIL)
00434 err(3, CHMOD, NIL);
00435 else
00436 check(CHMOD, ENOENT);
00437
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447 void test10()
00448 {
00449 int n, n1;
00450 char a[ARSIZE], b[ARSIZE], *f, *lf;
00451
00452 f = "file10";
00453 lf = "linkfile10";
00454
00455 if ((n = creat(f, 0702)) != FF)
00456 err(13, CREAT, f);
00457 else {
00458
00459 if (link(f, lf) != OK)
00460 err(5, LINK, lf);
00461 else if ((n1 = open(lf, RW)) < 0)
00462 err(5, OPEN, "'linkfile10'");
00463 else {
00464 init_array(a);
00465 clear_array(b);
00466
00467
00468
00469 if (write(n, a, ARSIZE) != ARSIZE) err(1, WRITE, "bad");
00470 if (read(n1, b, ARSIZE) != ARSIZE) err(1, READ, "bad");
00471 if (comp_array(a, b, ARSIZE) != OK) err(8, "r/w", NIL);
00472
00473
00474 Remove(n, f);
00475 try_close(n1, "'linkfile10'");
00476
00477
00478
00479 if ((n1 = open(lf, R)) < 0)
00480 err(5, OPEN, "'linkfile10'");
00481 else {
00482
00483
00484 clear_array(b);
00485 if (read(n1, b, ARSIZE) != ARSIZE)
00486 err(1, READ, "bad");
00487 if (comp_array(a, b, ARSIZE) != OK)
00488 err(8, "r/w", NIL);
00489
00490 try_close(n1, "'linkfile10' 2nd time");
00491 try_unlink(lf);
00492 }
00493 }
00494 }
00495
00496
00497
00498 if (unlink("non-file") != FAIL)
00499 err(2, UNLINK, "name");
00500 else
00501 check(UNLINK, ENOENT);
00502
00503
00504 if (unlink("dr-x/rwx") != FAIL)
00505 err(11, UNLINK, "could unlink in non-writable dir.");
00506 else
00507 check(UNLINK, EACCES);
00508
00509
00510 if (unlink("drwx") != FAIL)
00511 err(11, UNLINK, "unlink dir's as user");
00512 else
00513 check(UNLINK, EPERM);
00514
00515
00516
00517
00518
00519 if (link("non-file", "linkfile") != FAIL)
00520 err(2, LINK, "1st name");
00521 else
00522 check(LINK, ENOENT);
00523
00524
00525 if (link("drwx/rwx", "drwx/rw-") != FAIL)
00526 err(2, LINK, "2nd name");
00527 else
00528 check(LINK, EEXIST);
00529
00530
00531 if (link("drwx/rwx", "dr-x/linkfile") != FAIL)
00532 err(11, LINK, "link non-writable file");
00533 else
00534 check(LINK, EACCES);
00535
00536
00537 if (link("drwx", "linkfile") != FAIL)
00538 err(11, LINK, "link a dir without superuser!");
00539 else
00540 check(LINK, EPERM);
00541
00542
00543 if ((n = link_alot("drwx/rwx")) != LINKCOUNT - 1)
00544
00545 err(5, LINK, "many files");
00546 if (unlink_alot(n) != n) err(5, UNLINK, "all linked files");
00547
00548 }
00549
00550 int link_alot(bigboss)
00551 char *bigboss;
00552 {
00553 int i;
00554 static char employee[6] = "aaaaa";
00555
00556
00557 for (i = 1; i < LINKCOUNT; i++) {
00558 if (link(bigboss, employee) != OK)
00559 break;
00560 else
00561 get_new(employee);
00562 }
00563
00564 return(i - 1);
00565 }
00566
00567 int unlink_alot(number)
00568 int number;
00569 {
00570 int j;
00571 static char employee[6] = "aaaaa";
00572
00573 for (j = 0; j < number; j++) {
00574 if (unlink(employee) != OK)
00575 break;
00576 else
00577 get_new(employee);
00578 }
00579
00580 return(j);
00581 }
00582
00583 void get_new(name)
00584 char name[];
00585
00586
00587
00588
00589
00590 {
00591 int i;
00592
00593 for (i = 4; i >= 0; i--)
00594 if (name[i] != 'z') {
00595 name[i]++;
00596 break;
00597 }
00598 }
00599
00600
00601
00602
00603
00604
00605 void test11()
00606 {
00607 int n, fd[2];
00608 char a[ARSIZE], b[ARSIZE];
00609
00610 if (pipe(fd) != OK)
00611 err(13, PIPE, NIL);
00612 else {
00613
00614 init_array(a);
00615 clear_array(b);
00616
00617 if (write(fd[1], a, ARSIZE) != ARSIZE)
00618 err(5, WRITE, "on pipe");
00619 else if (read(fd[0], b, (ARSIZE / 2)) != (ARSIZE / 2))
00620 err(5, READ, "on pipe (2nd time)");
00621 else if (comp_array(a, b, (ARSIZE / 2)) != OK)
00622 err(7, PIPE, "values read/written");
00623 else if (read(fd[0], b, (ARSIZE / 2)) != (ARSIZE / 2))
00624 err(5, READ, "on pipe 2");
00625 else if (comp_array(&a[ARSIZE / 2], b, (ARSIZE / 2)) != OK)
00626 err(7, PIPE, "pipe created");
00627
00628
00629 if (write(fd[0], a, ARSIZE) != FAIL)
00630 err(11, WRITE, "write on fd[0]");
00631 if (read(fd[1], b, ARSIZE) != FAIL) err(11, READ, "read on fd[1]");
00632
00633 try_close(fd[1], "'fd[1]'");
00634
00635
00636 if (read(fd[0], b, ARSIZE) != END_FILE) err(2, PIPE, "'fd[1]'");
00637
00638 try_close(fd[0], "'fd[0]'");
00639 }
00640 if (pipe(fd) < 0)
00641 err(5, PIPE, "2nd time");
00642 else {
00643
00644 if (write(fd[1], a, ARSIZE) != ARSIZE)
00645 err(5, WRITE, "on pipe (2nd time)");
00646 if (lseek(fd[1], 10L, SEEK_SET) != FAIL)
00647 err(11, LSEEK, "lseek on a pipe");
00648 else
00649 check(PIPE, ESPIPE);
00650
00651
00652 try_close(fd[0], "'fd[0]' (2nd time)");
00653
00654
00655 #ifndef NOCRASH
00656 if (write(fd[1], a, ARSIZE) != FAIL)
00657 err(11, WRITE, "write on wrong pipe");
00658 else
00659 check(PIPE, EPIPE);
00660 #endif
00661 try_close(fd[1], "'fd[1]' (2nd time)");
00662 }
00663
00664
00665
00666
00667
00668
00669
00670 if (pipe(fd) < 0)
00671 err(5, PIPE, "3rd time");
00672 else {
00673 for (n = 0; n < (PIPESIZE / ARSIZE); n++)
00674 if (write(fd[1], a, ARSIZE) != ARSIZE)
00675 err(5, WRITE, "on pipe (3rd time) 4K");
00676 try_close(fd[1], "'fd[1]' (3rd time)");
00677
00678 for (n = 0; n < (PIPESIZE / ARSIZE); n++)
00679 if (read(fd[0], b, ARSIZE) != ARSIZE)
00680 err(5, READ, "from pipe (3rd time) 4K");
00681 try_close(fd[0], "'fd[0]' (3rd time)");
00682 }
00683
00684
00685 if ((n = open_alot()) != MAXOPEN) err(5, OPEN, "MAXOPEN files");
00686 if (pipe(fd) != FAIL)
00687 err(9, PIPE, "open");
00688 else
00689 check(PIPE, EMFILE);
00690 if (close_alot(n) != n) err(5, CLOSE, "all opened files");
00691 }
00692
00693
00694
00695 void comp_stats(stbf1, stbf2)
00696 struct stat *stbf1, *stbf2;
00697 {
00698 if (stbf1->st_dev != stbf2->st_dev) err(7, "st/fst", "'dev'");
00699 if (stbf1->st_ino != stbf2->st_ino) err(7, "st/fst", "'ino'");
00700 if (stbf1->st_mode != stbf2->st_mode) err(7, "st/fst", "'mode'");
00701 if (stbf1->st_nlink != stbf2->st_nlink) err(7, "st/fst", "'nlink'");
00702 if (stbf1->st_uid != stbf2->st_uid) err(7, "st/fst", "'uid'");
00703 if (stbf1->st_gid != stbf2->st_gid) err(7, "st/fst", "'gid'");
00704 if (stbf1->st_rdev != stbf2->st_rdev) err(7, "st/fst", "'rdev'");
00705 if (stbf1->st_size != stbf2->st_size) err(7, "st/fst", "'size'");
00706 if (stbf1->st_atime != stbf2->st_atime) err(7, "st/fst", "'atime'");
00707 if (stbf1->st_mtime != stbf2->st_mtime) err(7, "st/fst", "'mtime'");
00708 }
00709
00710
00711
00712
00713
00714 void comp_inodes(m, m1)
00715 int m, m1;
00716 {
00717 struct stat stbf1, stbf2;
00718
00719 if (fstat(m, &stbf1) == OK)
00720 if (fstat(m1, &stbf2) == OK) {
00721 if (stbf1.st_ino != stbf2.st_ino)
00722 err(7, DUP, "inode number");
00723 } else
00724 err(100, "comp_inodes", "cannot 'fstat' (m1)");
00725 else
00726 err(100, "comp_inodes", "cannot 'fstat' (m)");
00727 }
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742 void e(string)
00743 char *string;
00744 {
00745 printf("Error: %s ", string);
00746 }
00747
00748 void nlcr()
00749 {
00750 printf("\n");
00751 }
00752
00753 void str(s)
00754 char *s;
00755 {
00756 printf(s);
00757 }
00758
00759
00760
00761
00762
00763
00764 void err(number, scall, name)
00765
00766
00767 char *scall, *name;
00768 int number;
00769
00770 {
00771 errct++;
00772 if (errct > MAXERR) {
00773 printf("Too many errors; test aborted\n");
00774 quit();
00775 }
00776 e("");
00777 str("\t");
00778 switch (number) {
00779 case 0:
00780 str(scall);
00781 str(": illegal initial value.");
00782 break;
00783 case 1:
00784 str(scall);
00785 str(": ");
00786 str(name);
00787 str(" value returned.");
00788 break;
00789 case 2:
00790 str(scall);
00791 str(": accepting illegal ");
00792 str(name);
00793 str(".");
00794 break;
00795 case 3:
00796 str(scall);
00797 str(": accepting non-existing file.");
00798 break;
00799 case 4:
00800 str(scall);
00801 str(": could search non-searchable dir (");
00802 str(name);
00803 str(").");
00804 break;
00805 case 5:
00806 str(scall);
00807 str(": cannot ");
00808 str(scall);
00809 str(" ");
00810 str(name);
00811 str(".");
00812 break;
00813 case 7:
00814 str(scall);
00815 str(": incorrect ");
00816 str(name);
00817 str(".");
00818 break;
00819 case 8:
00820 str(scall);
00821 str(": wrong values.");
00822 break;
00823 case 9:
00824 str(scall);
00825 str(": accepting too many ");
00826 str(name);
00827 str(" files.");
00828 break;
00829 case 10:
00830 str(scall);
00831 str(": even a superuser can't do anything!");
00832 break;
00833 case 11:
00834 str(scall);
00835 str(": could ");
00836 str(name);
00837 str(".");
00838 break;
00839 case 12:
00840 str(scall);
00841 str(": could write in non-writable dir (");
00842 str(name);
00843 str(").");
00844 break;
00845 case 13:
00846 str(scall);
00847 str(": wrong filedes returned (");
00848 str(name);
00849 str(").");
00850 break;
00851 case 100:
00852 str(scall);
00853 str(": ");
00854 str(name);
00855 str(".");
00856 break;
00857 default: str("errornumber does not exist!\n");
00858 }
00859 nlcr();
00860 }
00861
00862
00863
00864
00865
00866
00867
00868 void make_and_fill_dirs()
00869
00870
00871
00872 {
00873 int mode, i;
00874
00875 for (i = 0; i < 8; i++) {
00876 mkdir(dir[i], 0700);
00877 chown(dir[i], USER_ID, GROUP_ID);
00878 }
00879 setuid(USER_ID);
00880 setgid(GROUP_ID);
00881
00882 for (mode = 0; mode < 8; mode++) put_file_in_dir("drwx", mode);
00883
00884 put_file_in_dir("d-wx", RWX);
00885 put_file_in_dir("dr-x", RWX);
00886 put_file_in_dir("drw-", RWX);
00887
00888 chmod_8_dirs(8);
00889
00890 }
00891
00892 void put_file_in_dir(dirname, mode)
00893 char *dirname;
00894 int mode;
00895
00896 {
00897 int nr;
00898
00899 if (chdir(dirname) != OK)
00900 err(5, CHDIR, "to dirname (put_f_in_dir)");
00901 else {
00902
00903 if ((nr = creat(fnames[mode], mode * 0100)) < 0)
00904 err(13, CREAT, fnames[mode]);
00905 else
00906 try_close(nr, fnames[mode]);
00907
00908 if (chdir("..") != OK)
00909 err(5, CHDIR, "to previous dir (put_f_in_dir)");
00910 }
00911 }
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921 void init_array(a)
00922 char *a;
00923 {
00924 int i;
00925
00926 i = 0;
00927 while (i++ < ARSIZE) *a++ = 'a' + (i % 26);
00928 }
00929
00930 void clear_array(b)
00931 char *b;
00932 {
00933 int i;
00934
00935 i = 0;
00936 while (i++ < ARSIZE) *b++ = '0';
00937
00938 }
00939
00940 int comp_array(a, b, range)
00941 char *a, *b;
00942 int range;
00943 {
00944 if ((range < 0) || (range > ARSIZE)) {
00945 err(100, "comp_array", "illegal range");
00946 return(FAIL);
00947 } else {
00948 while (range-- && (*a++ == *b++));
00949 if (*--a == *--b)
00950 return(OK);
00951 else
00952 return(FAIL);
00953 }
00954 }
00955
00956 void try_close(filedes, name)
00957 int filedes;
00958 char *name;
00959 {
00960 if (close(filedes) != OK) err(5, CLOSE, name);
00961 }
00962
00963 void try_unlink(fname)
00964 char *fname;
00965 {
00966 if (unlink(fname) != 0) err(5, UNLINK, fname);
00967 }
00968
00969 void Remove(fdes, fname)
00970 int fdes;
00971 char *fname;
00972 {
00973 try_close(fdes, fname);
00974 try_unlink(fname);
00975 }
00976
00977 int get_mode(name)
00978 char *name;
00979 {
00980 struct stat stbf1;
00981
00982 if (stat(name, &stbf1) != OK) {
00983 err(5, STAT, name);
00984 return(stbf1.st_mode);
00985
00986
00987 } else
00988 return(stbf1.st_mode & 07777);
00989 }
00990
00991
00992
00993
00994
00995
00996
00997 void check(scall, number)
00998 int number;
00999 char *scall;
01000 {
01001 if (errno != number) {
01002 e(NIL);
01003 str("\t");
01004 str(scall);
01005 str(": bad errno-value: ");
01006 put(errno);
01007 str(" should have been: ");
01008 put(number);
01009 nlcr();
01010 }
01011 }
01012
01013 void put(nr)
01014 int nr;
01015 {
01016 switch (nr) {
01017 case 0: str("unused"); break;
01018 case 1: str("EPERM"); break;
01019 case 2: str("ENOENT"); break;
01020 case 3: str("ESRCH"); break;
01021 case 4: str("EINTR"); break;
01022 case 5: str("EIO"); break;
01023 case 6: str("ENXIO"); break;
01024 case 7: str("E2BIG"); break;
01025 case 8: str("ENOEXEC"); break;
01026 case 9: str("EBADF"); break;
01027 case 10: str("ECHILD"); break;
01028 case 11: str("EAGAIN"); break;
01029 case 12: str("ENOMEM"); break;
01030 case 13: str("EACCES"); break;
01031 case 14: str("EFAULT"); break;
01032 case 15: str("ENOTBLK"); break;
01033 case 16: str("EBUSY"); break;
01034 case 17: str("EEXIST"); break;
01035 case 18: str("EXDEV"); break;
01036 case 19: str("ENODEV"); break;
01037 case 20: str("ENOTDIR"); break;
01038 case 21: str("EISDIR"); break;
01039 case 22: str("EINVAL"); break;
01040 case 23: str("ENFILE"); break;
01041 case 24: str("EMFILE"); break;
01042 case 25: str("ENOTTY"); break;
01043 case 26: str("ETXTBSY"); break;
01044 case 27: str("EFBIG"); break;
01045 case 28: str("ENOSPC"); break;
01046 case 29: str("ESPIPE"); break;
01047 case 30: str("EROFS"); break;
01048 case 31: str("EMLINK"); break;
01049 case 32: str("EPIPE"); break;
01050 case 33: str("EDOM"); break;
01051 case 34: str("ERANGE"); break;
01052 }
01053 }
01054
01055
01056
01057
01058
01059
01060
01061 int open_alot()
01062 {
01063 int i;
01064
01065 for (i = 0; i < MAXOPEN; i++)
01066 if (open(file[i], R) == FAIL) break;
01067 if (i == 0) err(5, "open_alot", "at all");
01068 return(i);
01069 }
01070
01071 int close_alot(number)
01072 int number;
01073 {
01074 int i, count = 0;
01075
01076 if (number > MAXOPEN)
01077 err(5, "close_alot", "accept this argument");
01078 else
01079 for (i = FF; i < number + FF; i++)
01080 if (close(i) != OK) count++;
01081
01082 return(number - count);
01083 }
01084
01085
01086
01087
01088
01089
01090
01091 void clean_up_the_mess()
01092 {
01093 int i;
01094 char dirname[6];
01095
01096
01097 for (i = 0; i < MAXOPEN; i++) try_unlink(file[i]);
01098
01099
01100 if (chdir("drwx") != OK)
01101 err(5, CHDIR, "to 'drwx'");
01102 else {
01103 for (i = 0; i < 8; i++) try_unlink(fnames[i]);
01104 if (chdir("..") != OK) err(5, CHDIR, "to '..'");
01105 }
01106
01107
01108 chmod_8_dirs(RWX);
01109
01110
01111 try_unlink("d-wx/rwx");
01112 try_unlink("dr-x/rwx");
01113 try_unlink("drw-/rwx");
01114
01115
01116 for (i = 0; i < 8; i++) {
01117 strcpy(dirname, "d");
01118 strcat(dirname, fnames[i]);
01119
01120
01121 rmdir(dirname);
01122 }
01123
01124
01125 }
01126
01127 void chmod_8_dirs(sw)
01128 int sw;
01129
01130 {
01131 int mode;
01132 int i;
01133
01134 if (sw == 8)
01135 mode = 0;
01136 else
01137 mode = sw;
01138
01139 for (i = 0; i < 8; i++) {
01140 chmod(dir[i], 040000 + mode * 0100);
01141 if (sw == 8) mode++;
01142 }
01143 }
01144
01145 void quit()
01146 {
01147
01148 chdir("..");
01149 system("rm -rf DIR*");
01150
01151 if (errct == 0) {
01152 printf("ok\n");
01153 exit(0);
01154 } else {
01155 printf("%d errors\n", errct);
01156 exit(1);
01157 }
01158 }