| [9] | 1 | /* Comment on usage and program: ark!/mnt/rene/prac/os/unix/comment.changes */
 | 
|---|
 | 2 | 
 | 
|---|
 | 3 | /* "const.h", created by Rene Montsma and Menno Wilcke */
 | 
|---|
 | 4 | 
 | 
|---|
 | 5 | #include <sys/types.h>          /* type defs */
 | 
|---|
 | 6 | #include <sys/stat.h>           /* struct stat */
 | 
|---|
 | 7 | #include <sys/wait.h>
 | 
|---|
 | 8 | #include <errno.h>              /* the error-numbers */
 | 
|---|
 | 9 | #include <fcntl.h>
 | 
|---|
 | 10 | #include <stdlib.h>
 | 
|---|
 | 11 | #include <string.h>
 | 
|---|
 | 12 | #include <unistd.h>
 | 
|---|
 | 13 | #include <utime.h>
 | 
|---|
 | 14 | #include <stdio.h>
 | 
|---|
 | 15 | #include <limits.h>
 | 
|---|
 | 16 | 
 | 
|---|
 | 17 | #define NOCRASH 1               /* test11(), 2nd pipe */
 | 
|---|
 | 18 | #define PDPNOHANG  1            /* test03(), write_standards() */
 | 
|---|
 | 19 | #define MAXERR 2
 | 
|---|
 | 20 | 
 | 
|---|
 | 21 | #define USER_ID   12
 | 
|---|
 | 22 | #define GROUP_ID   1
 | 
|---|
 | 23 | #define FF        3             /* first free filedes. */
 | 
|---|
 | 24 | #define USER      1             /* uid */
 | 
|---|
 | 25 | #define GROUP     0             /* gid */
 | 
|---|
 | 26 | 
 | 
|---|
 | 27 | #define ARSIZE   256            /* array size */
 | 
|---|
 | 28 | #define PIPESIZE 3584           /* max number of bytes to be written on pipe */
 | 
|---|
 | 29 | #define MAXOPEN  (OPEN_MAX-3)           /* maximum number of extra open files */
 | 
|---|
 | 30 | #define MAXLINK 0177            /* maximum number of links per file */
 | 
|---|
 | 31 | #define LINKCOUNT 5
 | 
|---|
 | 32 | #define MASK    0777            /* selects lower nine bits */
 | 
|---|
 | 33 | #define END_FILE     0          /* returned by read-call at eof */
 | 
|---|
 | 34 | 
 | 
|---|
 | 35 | #define OK      0
 | 
|---|
 | 36 | #define FAIL   -1
 | 
|---|
 | 37 | 
 | 
|---|
 | 38 | #define R       0               /* read (open-call) */
 | 
|---|
 | 39 | #define W       1               /* write (open-call) */
 | 
|---|
 | 40 | #define RW      2               /* read & write (open-call) */
 | 
|---|
 | 41 | 
 | 
|---|
 | 42 | #define RWX     7               /* read & write & execute (mode) */
 | 
|---|
 | 43 | 
 | 
|---|
 | 44 | #define NIL     ""
 | 
|---|
 | 45 | #define UMASK   "umask"
 | 
|---|
 | 46 | #define CREAT   "creat"
 | 
|---|
 | 47 | #define WRITE   "write"
 | 
|---|
 | 48 | #define READ    "read"
 | 
|---|
 | 49 | #define OPEN    "open"
 | 
|---|
 | 50 | #define CLOSE   "close"
 | 
|---|
 | 51 | #define LSEEK   "lseek"
 | 
|---|
 | 52 | #define ACCESS  "access"
 | 
|---|
 | 53 | #define CHDIR   "chdir"
 | 
|---|
 | 54 | #define CHMOD   "chmod"
 | 
|---|
 | 55 | #define LINK    "link"
 | 
|---|
 | 56 | #define UNLINK  "unlink"
 | 
|---|
 | 57 | #define PIPE    "pipe"
 | 
|---|
 | 58 | #define STAT    "stat"
 | 
|---|
 | 59 | #define FSTAT   "fstat"
 | 
|---|
 | 60 | #define DUP     "dup"
 | 
|---|
 | 61 | #define UTIME   "utime"
 | 
|---|
 | 62 | 
 | 
|---|
 | 63 | int errct;
 | 
|---|
 | 64 | 
 | 
|---|
 | 65 | char *file[];
 | 
|---|
 | 66 | char *fnames[];
 | 
|---|
 | 67 | char *dir[];
 | 
|---|
 | 68 | 
 | 
|---|
 | 69 | /* "decl.c", created by Rene Montsma and Menno Wilcke */
 | 
|---|
 | 70 | 
 | 
|---|
 | 71 | /* Used in open_alot, close_alot */
 | 
|---|
 | 72 | char *file[20] = {"f0", "f1", "f2", "f3", "f4", "f5", "f6",
 | 
|---|
 | 73 |           "f7", "f8", "f9", "f10", "f11", "f12", "f13",
 | 
|---|
 | 74 |           "f14", "f15", "f16", "f17", "f18", "f19"}, *fnames[8] = {"---", "--x", "-w-", "-wx", "r--",
 | 
|---|
 | 75 |                                                                    "r-x", "rw-", "rwx"}, *dir[8] = {"d---", "d--x", "d-w-", "d-wx", "dr--", "dr-x",
 | 
|---|
 | 76 |                                                     "drw-", "drwx"};
 | 
|---|
 | 77 |  /* Needed for easy creating and deleting of directories */
 | 
|---|
 | 78 | 
 | 
|---|
 | 79 | /* "test.c", created by Rene Montsma and Menno Wilcke */
 | 
|---|
 | 80 | 
 | 
|---|
 | 81 | _PROTOTYPE(int main, (int argc, char *argv []));
 | 
|---|
 | 82 | _PROTOTYPE(void test, (int mask));
 | 
|---|
 | 83 | _PROTOTYPE(void test01, (void));
 | 
|---|
 | 84 | _PROTOTYPE(void test02, (void));
 | 
|---|
 | 85 | _PROTOTYPE(void test08, (void));
 | 
|---|
 | 86 | _PROTOTYPE(void test09, (void));
 | 
|---|
 | 87 | _PROTOTYPE(void test10, (void));
 | 
|---|
 | 88 | _PROTOTYPE(int link_alot, (char *bigboss));
 | 
|---|
 | 89 | _PROTOTYPE(int unlink_alot, (int number));
 | 
|---|
 | 90 | _PROTOTYPE(void get_new, (char name []));
 | 
|---|
 | 91 | _PROTOTYPE(void test11, (void));
 | 
|---|
 | 92 | _PROTOTYPE(void comp_stats, (struct stat *stbf1, struct stat *stbf2));
 | 
|---|
 | 93 | _PROTOTYPE(void comp_inodes, (int m, int m1));
 | 
|---|
 | 94 | _PROTOTYPE(void e, (char *string));
 | 
|---|
 | 95 | _PROTOTYPE(void nlcr, (void));
 | 
|---|
 | 96 | _PROTOTYPE(void str, (char *s));
 | 
|---|
 | 97 | _PROTOTYPE(void err, (int number, char *scall, char *name));
 | 
|---|
 | 98 | _PROTOTYPE(void make_and_fill_dirs, (void));
 | 
|---|
 | 99 | _PROTOTYPE(void put_file_in_dir, (char *dirname, int mode));
 | 
|---|
 | 100 | _PROTOTYPE(void init_array, (char *a));
 | 
|---|
 | 101 | _PROTOTYPE(void clear_array, (char *b));
 | 
|---|
 | 102 | _PROTOTYPE(int comp_array, (char *a, char *b, int range));
 | 
|---|
 | 103 | _PROTOTYPE(void try_close, (int filedes, char *name));
 | 
|---|
 | 104 | _PROTOTYPE(void try_unlink, (char *fname));
 | 
|---|
 | 105 | _PROTOTYPE(void Remove, (int fdes, char *fname));
 | 
|---|
 | 106 | _PROTOTYPE(int get_mode, (char *name));
 | 
|---|
 | 107 | _PROTOTYPE(void check, (char *scall, int number));
 | 
|---|
 | 108 | _PROTOTYPE(void put, (int nr));
 | 
|---|
 | 109 | _PROTOTYPE(int open_alot, (void));
 | 
|---|
 | 110 | _PROTOTYPE(int close_alot, (int number));
 | 
|---|
 | 111 | _PROTOTYPE(void clean_up_the_mess, (void));
 | 
|---|
 | 112 | _PROTOTYPE(void chmod_8_dirs, (int sw));
 | 
|---|
 | 113 | _PROTOTYPE(void quit, (void));
 | 
|---|
 | 114 | 
 | 
|---|
 | 115 | /*****************************************************************************
 | 
|---|
 | 116 |  *                              TEST                                         *
 | 
|---|
 | 117 |  ****************************************************************************/
 | 
|---|
 | 118 | int main(argc, argv)
 | 
|---|
 | 119 | int argc;
 | 
|---|
 | 120 | char *argv[];
 | 
|---|
 | 121 | {
 | 
|---|
 | 122 |   int n, mask;
 | 
|---|
 | 123 | 
 | 
|---|
 | 124 |   sync();
 | 
|---|
 | 125 |   if (geteuid() == 0 || getuid() == 0) {
 | 
|---|
 | 126 |         printf("Test 17 cannot run as root; test aborted\n");
 | 
|---|
 | 127 |         exit(1);
 | 
|---|
 | 128 |   }
 | 
|---|
 | 129 | 
 | 
|---|
 | 130 |   system("rm -rf DIR_18; mkdir DIR_18");
 | 
|---|
 | 131 |   chdir("DIR_18");
 | 
|---|
 | 132 | 
 | 
|---|
 | 133 |   mask = (argc == 2 ? atoi(argv[1]) : 0xFFFF);
 | 
|---|
 | 134 | 
 | 
|---|
 | 135 |   if (fork()) {
 | 
|---|
 | 136 |         printf("Test 17 ");
 | 
|---|
 | 137 |         fflush(stdout);
 | 
|---|
 | 138 | 
 | 
|---|
 | 139 |         wait(&n);
 | 
|---|
 | 140 |         clean_up_the_mess();
 | 
|---|
 | 141 |         quit();
 | 
|---|
 | 142 |   } else {
 | 
|---|
 | 143 |         test(mask);
 | 
|---|
 | 144 |         exit(0);
 | 
|---|
 | 145 |   }
 | 
|---|
 | 146 |   return(-1);                   /* impossible */
 | 
|---|
 | 147 | }
 | 
|---|
 | 148 | 
 | 
|---|
 | 149 | void test(mask)
 | 
|---|
 | 150 | int mask;
 | 
|---|
 | 151 | {
 | 
|---|
 | 152 |   umask(0);                     /* not honest, but i always forget */
 | 
|---|
 | 153 | 
 | 
|---|
 | 154 |   if (mask & 00001) test01();
 | 
|---|
 | 155 |   if (mask & 00002) make_and_fill_dirs();
 | 
|---|
 | 156 |   if (mask & 00004) test02();
 | 
|---|
 | 157 |   if (mask & 00010) test08();
 | 
|---|
 | 158 |   if (mask & 00020) test09();
 | 
|---|
 | 159 |   if (mask & 00040) test10();
 | 
|---|
 | 160 |   if (mask & 00100) test11();
 | 
|---|
 | 161 |   umask(022);
 | 
|---|
 | 162 | }                               /* test */
 | 
|---|
 | 163 | 
 | 
|---|
 | 164 | /* "t1.c" created by Rene Montsma and Menno Wilcke */
 | 
|---|
 | 165 | 
 | 
|---|
 | 166 | /*****************************************************************************
 | 
|---|
 | 167 |  *                              test UMASK                                   *
 | 
|---|
 | 168 |  ****************************************************************************/
 | 
|---|
 | 169 | void test01()
 | 
|---|
 | 170 | {
 | 
|---|
 | 171 |   int oldvalue, newvalue, tempvalue;
 | 
|---|
 | 172 |   int nr;
 | 
|---|
 | 173 | 
 | 
|---|
 | 174 |   if ((oldvalue = umask(0777)) != 0) err(0, UMASK, NIL);
 | 
|---|
 | 175 | 
 | 
|---|
 | 176 |   /* Special test: only the lower 9 bits (protection bits) may part- *
 | 
|---|
 | 177 |    * icipate. ~0777 means: 111 000 000 000. Giving this to umask must*
 | 
|---|
 | 178 |    * not change any value.                                           */
 | 
|---|
 | 179 | 
 | 
|---|
 | 180 |   if ((newvalue = umask(~0777)) != 0777) err(1, UMASK, "illegal");
 | 
|---|
 | 181 |   if (oldvalue == newvalue) err(11, UMASK, "not change mask");
 | 
|---|
 | 182 | 
 | 
|---|
 | 183 |   if ((tempvalue = umask(0)) != 0) err(2, UMASK, "values");
 | 
|---|
 | 184 | 
 | 
|---|
 | 185 |   /* Now test all possible modes of umask on a file */
 | 
|---|
 | 186 |   for (newvalue = MASK; newvalue >= 0; newvalue -= 0111) {
 | 
|---|
 | 187 |         tempvalue = umask(newvalue);
 | 
|---|
 | 188 |         if (tempvalue != oldvalue) {
 | 
|---|
 | 189 |                 err(1, UMASK, "illegal");
 | 
|---|
 | 190 |                 break;          /* no use trying more */
 | 
|---|
 | 191 |         } else if ((nr = creat("file01", 0777)) < 0)
 | 
|---|
 | 192 |                 err(5, CREAT, "'file01'");
 | 
|---|
 | 193 |         else {
 | 
|---|
 | 194 |                 try_close(nr, "'file01'");
 | 
|---|
 | 195 |                 if (get_mode("file01") != (MASK & ~newvalue))
 | 
|---|
 | 196 |                         err(7, UMASK, "mode computed");
 | 
|---|
 | 197 |                 try_unlink("file01");
 | 
|---|
 | 198 |         }
 | 
|---|
 | 199 |         oldvalue = newvalue;
 | 
|---|
 | 200 |   }
 | 
|---|
 | 201 | 
 | 
|---|
 | 202 |   /* The loop has terminated with umask(0) */
 | 
|---|
 | 203 |   if ((tempvalue = umask(0)) != 0)
 | 
|---|
 | 204 |         err(7, UMASK, "umask may influence rest of tests!");
 | 
|---|
 | 205 | }                               /* test01 */
 | 
|---|
 | 206 | 
 | 
|---|
 | 207 | /*****************************************************************************
 | 
|---|
 | 208 |  *                              test CREAT                                   *
 | 
|---|
 | 209 |  ****************************************************************************/
 | 
|---|
 | 210 | void test02()
 | 
|---|
 | 211 | {
 | 
|---|
 | 212 |   int n, n1, mode;
 | 
|---|
 | 213 |   char a[ARSIZE], b[ARSIZE];
 | 
|---|
 | 214 |   struct stat stbf1;
 | 
|---|
 | 215 | 
 | 
|---|
 | 216 |   mode = 0;
 | 
|---|
 | 217 |   /* Create twenty files, check filedes */
 | 
|---|
 | 218 |   for (n = 0; n < MAXOPEN; n++) {
 | 
|---|
 | 219 |         if (creat(file[n], mode) != FF + n)
 | 
|---|
 | 220 |                 err(13, CREAT, file[n]);
 | 
|---|
 | 221 |         else {
 | 
|---|
 | 222 |                 if (get_mode(file[n]) != mode)
 | 
|---|
 | 223 |                         err(7, CREAT, "mode set while creating many files");
 | 
|---|
 | 224 | 
 | 
|---|
 | 225 |                 /* Change  mode of file to standard mode, we want to *
 | 
|---|
 | 226 |                  * use a lot (20) of files to be opened later, see   *
 | 
|---|
 | 227 |                  * open_alot(), close_alot().                        */
 | 
|---|
 | 228 |                 if (chmod(file[n], 0700) != OK) err(5, CHMOD, file[n]);
 | 
|---|
 | 229 | 
 | 
|---|
 | 230 |         }
 | 
|---|
 | 231 |         mode = (mode + 0100) % 01000;
 | 
|---|
 | 232 |   }
 | 
|---|
 | 233 | 
 | 
|---|
 | 234 |   /* Already twenty files opened; opening another has to fail */
 | 
|---|
 | 235 |   if (creat("file02", 0777) != FAIL)
 | 
|---|
 | 236 |         err(9, CREAT, "created");
 | 
|---|
 | 237 |   else
 | 
|---|
 | 238 |         check(CREAT, EMFILE);
 | 
|---|
 | 239 | 
 | 
|---|
 | 240 |   /* Close all files: seems blunt, but it isn't because we've  *
 | 
|---|
 | 241 |    * checked all fd's already                                  */
 | 
|---|
 | 242 |   if ((n = close_alot(MAXOPEN)) < MAXOPEN) err(5, CLOSE, "MAXOPEN files");
 | 
|---|
 | 243 | 
 | 
|---|
 | 244 |   /* Creat 1 file twice; check */
 | 
|---|
 | 245 |   if ((n = creat("file02", 0777)) < 0)
 | 
|---|
 | 246 |         err(5, CREAT, "'file02'");
 | 
|---|
 | 247 |   else {
 | 
|---|
 | 248 |         init_array(a);
 | 
|---|
 | 249 |         if (write(n, a, ARSIZE) != ARSIZE) err(1, WRITE, "bad");
 | 
|---|
 | 250 | 
 | 
|---|
 | 251 |         if ((n1 = creat("file02", 0755)) < 0)   /* receate 'file02' */
 | 
|---|
 | 252 |                 err(5, CREAT, "'file02' (2nd time)");
 | 
|---|
 | 253 |         else {
 | 
|---|
 | 254 |                 /* Fd should be at the top after recreation */
 | 
|---|
 | 255 |                 if (lseek(n1, 0L, SEEK_END) != 0)
 | 
|---|
 | 256 |                         err(11, CREAT, "not truncate file by recreation");
 | 
|---|
 | 257 |                 else {
 | 
|---|
 | 258 |                         /* Try to write on recreated file */
 | 
|---|
 | 259 |                         clear_array(b);
 | 
|---|
 | 260 | 
 | 
|---|
 | 261 |                         if (lseek(n1, 0L, SEEK_SET) != 0)
 | 
|---|
 | 262 |                                 err(5, LSEEK, "to top of 2nd fd 'file02'");
 | 
|---|
 | 263 |                         if (write(n1, a, ARSIZE) != ARSIZE)
 | 
|---|
 | 264 |                                 err(1, WRITE, "(2) bad");
 | 
|---|
 | 265 | 
 | 
|---|
 | 266 |                         /* In order to read we've to close and open again */
 | 
|---|
 | 267 |                         try_close(n1, "'file02'  (2nd creation)");
 | 
|---|
 | 268 |                         if ((n1 = open("file02", RW)) < 0)
 | 
|---|
 | 269 |                                 err(5, OPEN, "'file02'  (2nd recreation)");
 | 
|---|
 | 270 | 
 | 
|---|
 | 271 |                         /* Continue */
 | 
|---|
 | 272 |                         if (lseek(n1, 0L, SEEK_SET) != 0)
 | 
|---|
 | 273 |                                 err(5, LSEEK, "to top 'file02'(2nd fd) (2)");
 | 
|---|
 | 274 |                         if (read(n1, b, ARSIZE) != ARSIZE)
 | 
|---|
 | 275 |                                 err(1, READ, "wrong");
 | 
|---|
 | 276 | 
 | 
|---|
 | 277 |                         if (comp_array(a, b, ARSIZE) != OK) err(11, CREAT,
 | 
|---|
 | 278 |                                     "not really truncate file by recreation");
 | 
|---|
 | 279 |                 }
 | 
|---|
 | 280 |                 if (get_mode("file02") != 0777)
 | 
|---|
 | 281 |                         err(11, CREAT, "not maintain mode by recreation");
 | 
|---|
 | 282 |                 try_close(n1, "recreated 'file02'");
 | 
|---|
 | 283 | 
 | 
|---|
 | 284 |         }
 | 
|---|
 | 285 |         Remove(n, "file02");
 | 
|---|
 | 286 |   }
 | 
|---|
 | 287 | 
 | 
|---|
 | 288 |   /* Give 'creat' wrong input: dir not searchable */
 | 
|---|
 | 289 |   if (creat("drw-/file02", 0777) != FAIL)
 | 
|---|
 | 290 |         err(4, CREAT, "'drw-'");
 | 
|---|
 | 291 |   else
 | 
|---|
 | 292 |         check(CREAT, EACCES);
 | 
|---|
 | 293 | 
 | 
|---|
 | 294 |   /* Dir not writable */
 | 
|---|
 | 295 |   if (creat("dr-x/file02", 0777) != FAIL)
 | 
|---|
 | 296 |         err(12, CREAT, "'dr-x/file02'");
 | 
|---|
 | 297 |   else
 | 
|---|
 | 298 |         check(CREAT, EACCES);
 | 
|---|
 | 299 | 
 | 
|---|
 | 300 |   /* File not writable */
 | 
|---|
 | 301 |   if (creat("drwx/r-x", 0777) != FAIL)
 | 
|---|
 | 302 |         err(11, CREAT, "recreate non-writable file");
 | 
|---|
 | 303 |   else
 | 
|---|
 | 304 |         check(CREAT, EACCES);
 | 
|---|
 | 305 | 
 | 
|---|
 | 306 |   /* Try to creat a dir */
 | 
|---|
 | 307 |   if ((n = creat("dir", 040777)) != FAIL) {
 | 
|---|
 | 308 |         if (fstat(n, &stbf1) != OK)
 | 
|---|
 | 309 |                 err(5, FSTAT, "'dir'");
 | 
|---|
 | 310 |         else if (stbf1.st_mode != (mode_t) 0100777)
 | 
|---|
 | 311 |                                 /* cast because mode is negative :-( */
 | 
|---|
 | 312 |                 err(11, CREAT, "'creat' a new directory");
 | 
|---|
 | 313 |         Remove(n, "dir");
 | 
|---|
 | 314 |   }
 | 
|---|
 | 315 | 
 | 
|---|
 | 316 |   /* We don't consider it to be a bug when creat * does not accept
 | 
|---|
 | 317 |    * tricky modes                */
 | 
|---|
 | 318 | 
 | 
|---|
 | 319 |   /* File is an existing dir */
 | 
|---|
 | 320 |   if (creat("drwx", 0777) != FAIL)
 | 
|---|
 | 321 |         err(11, CREAT, "create an existing dir!");
 | 
|---|
 | 322 |   else
 | 
|---|
 | 323 |         check(CREAT, EISDIR);
 | 
|---|
 | 324 | }                               /* test02 */
 | 
|---|
 | 325 | 
 | 
|---|
 | 326 | void test08()
 | 
|---|
 | 327 | {
 | 
|---|
 | 328 |   /* Test chdir to searchable dir */
 | 
|---|
 | 329 |   if (chdir("drwx") != OK)
 | 
|---|
 | 330 |         err(5, CHDIR, "to accessible dir");
 | 
|---|
 | 331 |   else if (chdir("..") != OK)
 | 
|---|
 | 332 |         err(11, CHDIR, "not return to '..'");
 | 
|---|
 | 333 | 
 | 
|---|
 | 334 |   /* Check the chdir(".") and chdir("..") mechanism */
 | 
|---|
 | 335 |   if (chdir("drwx") != OK)
 | 
|---|
 | 336 |         err(5, CHDIR, "to 'drwx'");
 | 
|---|
 | 337 |   else {
 | 
|---|
 | 338 |         if (chdir(".") != OK) err(5, CHDIR, "to working dir (.)");
 | 
|---|
 | 339 | 
 | 
|---|
 | 340 |         /* If we still are in 'drwx' , we should be able to access *
 | 
|---|
 | 341 |          * file 'rwx'.                                              */
 | 
|---|
 | 342 |         if (access("rwx", 0) != OK) err(5, CHDIR, "rightly to '.'");
 | 
|---|
 | 343 | 
 | 
|---|
 | 344 |         /* Try to return to previous dir ('/' !!) */
 | 
|---|
 | 345 |         if (chdir("././../././d--x/../d--x/././..") != OK)
 | 
|---|
 | 346 |                 err(5, CHDIR, "to motherdir (..)");
 | 
|---|
 | 347 | 
 | 
|---|
 | 348 |         /* Check whether we are back in '/' */
 | 
|---|
 | 349 |         if (chdir("d--x") != OK) err(5, CHDIR, "rightly to  a '..'");
 | 
|---|
 | 350 |   }
 | 
|---|
 | 351 | 
 | 
|---|
 | 352 |   /* Return to '..' */
 | 
|---|
 | 353 |   if (chdir("..") != OK) err(5, CHDIR, "to '..'");
 | 
|---|
 | 354 | 
 | 
|---|
 | 355 |   if (chdir("././././drwx") != OK)
 | 
|---|
 | 356 |         err(11, CHDIR, "not follow a path");
 | 
|---|
 | 357 |   else if (chdir("././././..") != OK)
 | 
|---|
 | 358 |         err(11, CHDIR, "not return to path");
 | 
|---|
 | 359 | 
 | 
|---|
 | 360 |   /* Try giving chdir wrong parameters */
 | 
|---|
 | 361 |   if (chdir("drwx/rwx") != FAIL)
 | 
|---|
 | 362 |         err(11, CHDIR, "chdir to a file");
 | 
|---|
 | 363 |   else
 | 
|---|
 | 364 |         check(CHDIR, ENOTDIR);
 | 
|---|
 | 365 | 
 | 
|---|
 | 366 |   if (chdir("drw-") != FAIL)
 | 
|---|
 | 367 |         err(4, CHDIR, "'/drw-'");
 | 
|---|
 | 368 |   else
 | 
|---|
 | 369 |         check(CHDIR, EACCES);
 | 
|---|
 | 370 | 
 | 
|---|
 | 371 |   /* To be sure: return to root */
 | 
|---|
 | 372 |   /* If (chdir("/") != OK) err(5, CHDIR, "to '/' (2nd time)"); */
 | 
|---|
 | 373 | }                               /* test08 */
 | 
|---|
 | 374 | 
 | 
|---|
 | 375 | /* New page */ | 
|---|
 | 376 | 
 | 
|---|
 | 377 | /*****************************************************************************
 | 
|---|
 | 378 |  *                              test CHMOD                                   *
 | 
|---|
 | 379 |  ****************************************************************************/
 | 
|---|
 | 380 | void test09()
 | 
|---|
 | 381 | {
 | 
|---|
 | 382 |   int n;
 | 
|---|
 | 383 | 
 | 
|---|
 | 384 |   /* Prepare file09 */
 | 
|---|
 | 385 |   if ((n = creat("drwx/file09", 0644)) != FF) err(5, CREAT, "'drwx/file09'");
 | 
|---|
 | 386 | 
 | 
|---|
 | 387 |   try_close(n, "'file09'");
 | 
|---|
 | 388 | 
 | 
|---|
 | 389 |   /* Try to chmod a file, check and restore old values, check */
 | 
|---|
 | 390 |   if (chmod("drwx/file09", 0700) != OK)
 | 
|---|
 | 391 |         err(5, CHMOD, "'drwx/file09'"); /* set rwx */
 | 
|---|
 | 392 |   else {
 | 
|---|
 | 393 |         /* Check protection */
 | 
|---|
 | 394 |         if (get_mode("drwx/file09") != 0700) err(7, CHMOD, "mode");
 | 
|---|
 | 395 | 
 | 
|---|
 | 396 |         /* Test if chmod accepts just filenames too */
 | 
|---|
 | 397 |         if (chdir("drwx") != OK)
 | 
|---|
 | 398 |                 err(5, CHDIR, "to '/drwx'");
 | 
|---|
 | 399 |         else if (chmod("file09", 0177) != OK)   /* restore oldies */
 | 
|---|
 | 400 |                 err(5, CHMOD, "'h1'");
 | 
|---|
 | 401 |         else
 | 
|---|
 | 402 |                 /* Check if value has been restored */
 | 
|---|
 | 403 |         if (get_mode("../drwx/file09") != 0177)
 | 
|---|
 | 404 |                 err(7, CHMOD, "restored mode");
 | 
|---|
 | 405 |   }
 | 
|---|
 | 406 | 
 | 
|---|
 | 407 |   /* Try setuid and setgid */
 | 
|---|
 | 408 |   if ((chmod("file09", 04777) != OK) || (get_mode("file09") != 04777))
 | 
|---|
 | 409 |         err(11, CHMOD, "not set uid-bit");
 | 
|---|
 | 410 |   if ((chmod("file09", 02777) != OK) || (get_mode("file09") != 02777))
 | 
|---|
 | 411 |         err(11, CHMOD, "not set gid-bit");
 | 
|---|
 | 412 | 
 | 
|---|
 | 413 |   /* Remove testfile */
 | 
|---|
 | 414 |   try_unlink("file09");
 | 
|---|
 | 415 | 
 | 
|---|
 | 416 |   if (chdir("..") != OK) err(5, CHDIR, "to '..'");
 | 
|---|
 | 417 | 
 | 
|---|
 | 418 |   /* Try to chmod directory */
 | 
|---|
 | 419 |   if (chmod("d---", 0777) != OK)
 | 
|---|
 | 420 |         err(5, CHMOD, "dir 'd---'");
 | 
|---|
 | 421 |   else {
 | 
|---|
 | 422 |         if (get_mode("d---") != 0777) err(7, CHMOD, "protection value");
 | 
|---|
 | 423 |         if (chmod("d---", 0000) != OK) err(5, CHMOD, "dir 'a' 2nd time");
 | 
|---|
 | 424 | 
 | 
|---|
 | 425 |         /* Check if old value has been restored */
 | 
|---|
 | 426 |         if (get_mode("d---") != 0000)
 | 
|---|
 | 427 |                 err(7, CHMOD, "restored protection value");
 | 
|---|
 | 428 |   }
 | 
|---|
 | 429 | 
 | 
|---|
 | 430 |   /* Try to make chmod failures */
 | 
|---|
 | 431 | 
 | 
|---|
 | 432 |   /* We still are in dir root */
 | 
|---|
 | 433 |   /* Wrong filename */
 | 
|---|
 | 434 |   if (chmod("non-file", 0777) != FAIL)
 | 
|---|
 | 435 |         err(3, CHMOD, NIL);
 | 
|---|
 | 436 |   else
 | 
|---|
 | 437 |         check(CHMOD, ENOENT);
 | 
|---|
 | 438 | 
 | 
|---|
 | 439 | }                               /* test 09 */
 | 
|---|
 | 440 | 
 | 
|---|
 | 441 | /* New page */ | 
|---|
 | 442 | 
 | 
|---|
 | 443 | 
 | 
|---|
 | 444 | /* "t4.c", created by Rene Montsma and Menno Wilcke */
 | 
|---|
 | 445 | 
 | 
|---|
 | 446 | /*****************************************************************************
 | 
|---|
 | 447 |  *                              test LINK/UNLINK                             *
 | 
|---|
 | 448 |  ****************************************************************************/
 | 
|---|
 | 449 | void test10()
 | 
|---|
 | 450 | {
 | 
|---|
 | 451 |   int n, n1;
 | 
|---|
 | 452 |   char a[ARSIZE], b[ARSIZE], *f, *lf;
 | 
|---|
 | 453 | 
 | 
|---|
 | 454 |   f = "file10";
 | 
|---|
 | 455 |   lf = "linkfile10";
 | 
|---|
 | 456 | 
 | 
|---|
 | 457 |   if ((n = creat(f, 0702)) != FF)       /* no other open files */
 | 
|---|
 | 458 |         err(13, CREAT, f);
 | 
|---|
 | 459 |   else {
 | 
|---|
 | 460 |         /* Now link correctly */
 | 
|---|
 | 461 |         if (link(f, lf) != OK)
 | 
|---|
 | 462 |                 err(5, LINK, lf);
 | 
|---|
 | 463 |         else if ((n1 = open(lf, RW)) < 0)
 | 
|---|
 | 464 |                 err(5, OPEN, "'linkfile10'");
 | 
|---|
 | 465 |         else {
 | 
|---|
 | 466 |                 init_array(a);
 | 
|---|
 | 467 |                 clear_array(b);
 | 
|---|
 | 468 | 
 | 
|---|
 | 469 |                 /* Write on 'file10' means being able to    * read
 | 
|---|
 | 470 |                  * through linked filedescriptor       */
 | 
|---|
 | 471 |                 if (write(n, a, ARSIZE) != ARSIZE) err(1, WRITE, "bad");
 | 
|---|
 | 472 |                 if (read(n1, b, ARSIZE) != ARSIZE) err(1, READ, "bad");
 | 
|---|
 | 473 |                 if (comp_array(a, b, ARSIZE) != OK) err(8, "r/w", NIL);
 | 
|---|
 | 474 | 
 | 
|---|
 | 475 |                 /* Clean up: unlink and close (twice): */
 | 
|---|
 | 476 |                 Remove(n, f);
 | 
|---|
 | 477 |                 try_close(n1, "'linkfile10'");
 | 
|---|
 | 478 | 
 | 
|---|
 | 479 |                 /* Check if "linkfile" exists and the info    * on it
 | 
|---|
 | 480 |                  * is correct ('file' has been deleted) */
 | 
|---|
 | 481 |                 if ((n1 = open(lf, R)) < 0)
 | 
|---|
 | 482 |                         err(5, OPEN, "'linkfile10'");
 | 
|---|
 | 483 |                 else {
 | 
|---|
 | 484 |                         /* See if 'linkfile' still contains 0..511 ? */
 | 
|---|
 | 485 | 
 | 
|---|
 | 486 |                         clear_array(b);
 | 
|---|
 | 487 |                         if (read(n1, b, ARSIZE) != ARSIZE)
 | 
|---|
 | 488 |                                 err(1, READ, "bad");
 | 
|---|
 | 489 |                         if (comp_array(a, b, ARSIZE) != OK)
 | 
|---|
 | 490 |                                 err(8, "r/w", NIL);
 | 
|---|
 | 491 | 
 | 
|---|
 | 492 |                         try_close(n1, "'linkfile10' 2nd time");
 | 
|---|
 | 493 |                         try_unlink(lf);
 | 
|---|
 | 494 |                 }
 | 
|---|
 | 495 |         }
 | 
|---|
 | 496 |   }
 | 
|---|
 | 497 | 
 | 
|---|
 | 498 |   /* Try if unlink fails with incorrect parameters */
 | 
|---|
 | 499 |   /* File does not exist: */
 | 
|---|
 | 500 |   if (unlink("non-file") != FAIL)
 | 
|---|
 | 501 |         err(2, UNLINK, "name");
 | 
|---|
 | 502 |   else
 | 
|---|
 | 503 |         check(UNLINK, ENOENT);
 | 
|---|
 | 504 | 
 | 
|---|
 | 505 |   /* Dir can't be written */
 | 
|---|
 | 506 |   if (unlink("dr-x/rwx") != FAIL)
 | 
|---|
 | 507 |         err(11, UNLINK, "could unlink in non-writable dir.");
 | 
|---|
 | 508 |   else
 | 
|---|
 | 509 |         check(UNLINK, EACCES);
 | 
|---|
 | 510 | 
 | 
|---|
 | 511 |   /* Try to unlink a dir being user */
 | 
|---|
 | 512 |   if (unlink("drwx") != FAIL)
 | 
|---|
 | 513 |         err(11, UNLINK, "unlink dir's as user");
 | 
|---|
 | 514 |   else
 | 
|---|
 | 515 |         check(UNLINK, EPERM);
 | 
|---|
 | 516 | 
 | 
|---|
 | 517 |   /* Try giving link wrong input */
 | 
|---|
 | 518 | 
 | 
|---|
 | 519 |   /* First try if link fails with incorrect parameters * name1 does not
 | 
|---|
 | 520 |    * exist.                             */
 | 
|---|
 | 521 |   if (link("non-file", "linkfile") != FAIL)
 | 
|---|
 | 522 |         err(2, LINK, "1st name");
 | 
|---|
 | 523 |   else
 | 
|---|
 | 524 |         check(LINK, ENOENT);
 | 
|---|
 | 525 | 
 | 
|---|
 | 526 |   /* Name2 exists already */
 | 
|---|
 | 527 |   if (link("drwx/rwx", "drwx/rw-") != FAIL)
 | 
|---|
 | 528 |         err(2, LINK, "2nd name");
 | 
|---|
 | 529 |   else
 | 
|---|
 | 530 |         check(LINK, EEXIST);
 | 
|---|
 | 531 | 
 | 
|---|
 | 532 |   /* Directory of name2 not writable:  */
 | 
|---|
 | 533 |   if (link("drwx/rwx", "dr-x/linkfile") != FAIL)
 | 
|---|
 | 534 |         err(11, LINK, "link non-writable  file");
 | 
|---|
 | 535 |   else
 | 
|---|
 | 536 |         check(LINK, EACCES);
 | 
|---|
 | 537 | 
 | 
|---|
 | 538 |   /* Try to link a dir, being a user */
 | 
|---|
 | 539 |   if (link("drwx", "linkfile") != FAIL)
 | 
|---|
 | 540 |         err(11, LINK, "link a dir without superuser!");
 | 
|---|
 | 541 |   else
 | 
|---|
 | 542 |         check(LINK, EPERM);
 | 
|---|
 | 543 | 
 | 
|---|
 | 544 |   /* File has too many links */
 | 
|---|
 | 545 |   if ((n = link_alot("drwx/rwx")) != LINKCOUNT - 1)     /* file already has one
 | 
|---|
 | 546 |                                                          * link */
 | 
|---|
 | 547 |         err(5, LINK, "many files");
 | 
|---|
 | 548 |   if (unlink_alot(n) != n) err(5, UNLINK, "all linked files");
 | 
|---|
 | 549 | 
 | 
|---|
 | 550 | }                               /* test10 */
 | 
|---|
 | 551 | 
 | 
|---|
 | 552 | int link_alot(bigboss)
 | 
|---|
 | 553 | char *bigboss;
 | 
|---|
 | 554 | {
 | 
|---|
 | 555 |   int i;
 | 
|---|
 | 556 |   static char employee[6] = "aaaaa";
 | 
|---|
 | 557 | 
 | 
|---|
 | 558 |   /* Every file has already got 1 link, so link 0176 times */
 | 
|---|
 | 559 |   for (i = 1; i < LINKCOUNT; i++) {
 | 
|---|
 | 560 |         if (link(bigboss, employee) != OK)
 | 
|---|
 | 561 |                 break;
 | 
|---|
 | 562 |         else
 | 
|---|
 | 563 |                 get_new(employee);
 | 
|---|
 | 564 |   }
 | 
|---|
 | 565 | 
 | 
|---|
 | 566 |   return(i - 1);                /* number of linked files */
 | 
|---|
 | 567 | }                               /* link_alot */
 | 
|---|
 | 568 | 
 | 
|---|
 | 569 | int unlink_alot(number)
 | 
|---|
 | 570 | int number;                     /* number of files to be unlinked */
 | 
|---|
 | 571 | {
 | 
|---|
 | 572 |   int j;
 | 
|---|
 | 573 |   static char employee[6] = "aaaaa";
 | 
|---|
 | 574 | 
 | 
|---|
 | 575 |   for (j = 0; j < number; j++) {
 | 
|---|
 | 576 |         if (unlink(employee) != OK)
 | 
|---|
 | 577 |                 break;
 | 
|---|
 | 578 |         else
 | 
|---|
 | 579 |                 get_new(employee);
 | 
|---|
 | 580 |   }
 | 
|---|
 | 581 | 
 | 
|---|
 | 582 |   return(j);                    /* return number of unlinked files */
 | 
|---|
 | 583 | }                               /* unlink_alot */
 | 
|---|
 | 584 | 
 | 
|---|
 | 585 | void get_new(name)
 | 
|---|
 | 586 | char name[];
 | 
|---|
 | 587 |  /* Every call changes string 'name' to a string alphabetically          *
 | 
|---|
 | 588 |   * higher. Start with "aaaaa", next value: "aaaab" .                    *
 | 
|---|
 | 589 |   * N.B. after "aaaaz" comes "aaabz" and not "aaaba" (not needed).       *
 | 
|---|
 | 590 |   * The last possibility will be "zzzzz".                                *
 | 
|---|
 | 591 |   * Total # possibilities: 26+25*4 = 126 = MAXLINK -1 (exactly needed)   */
 | 
|---|
 | 592 | {
 | 
|---|
 | 593 |   int i;
 | 
|---|
 | 594 | 
 | 
|---|
 | 595 |   for (i = 4; i >= 0; i--)
 | 
|---|
 | 596 |         if (name[i] != 'z') {
 | 
|---|
 | 597 |                 name[i]++;
 | 
|---|
 | 598 |                 break;
 | 
|---|
 | 599 |         }
 | 
|---|
 | 600 | }                               /* get_new */
 | 
|---|
 | 601 | 
 | 
|---|
 | 602 | /* New page */ | 
|---|
 | 603 | 
 | 
|---|
 | 604 | 
 | 
|---|
 | 605 | /*****************************************************************************
 | 
|---|
 | 606 |  *                              test PIPE                                    *
 | 
|---|
 | 607 |  ****************************************************************************/
 | 
|---|
 | 608 | void test11()
 | 
|---|
 | 609 | {
 | 
|---|
 | 610 |   int n, fd[2];
 | 
|---|
 | 611 |   char a[ARSIZE], b[ARSIZE];
 | 
|---|
 | 612 | 
 | 
|---|
 | 613 |   if (pipe(fd) != OK)
 | 
|---|
 | 614 |         err(13, PIPE, NIL);
 | 
|---|
 | 615 |   else {
 | 
|---|
 | 616 |         /* Try reading and writing on a pipe */
 | 
|---|
 | 617 |         init_array(a);
 | 
|---|
 | 618 |         clear_array(b);
 | 
|---|
 | 619 | 
 | 
|---|
 | 620 |         if (write(fd[1], a, ARSIZE) != ARSIZE)
 | 
|---|
 | 621 |                 err(5, WRITE, "on pipe");
 | 
|---|
 | 622 |         else if (read(fd[0], b, (ARSIZE / 2)) != (ARSIZE / 2))
 | 
|---|
 | 623 |                 err(5, READ, "on pipe (2nd time)");
 | 
|---|
 | 624 |         else if (comp_array(a, b, (ARSIZE / 2)) != OK)
 | 
|---|
 | 625 |                 err(7, PIPE, "values read/written");
 | 
|---|
 | 626 |         else if (read(fd[0], b, (ARSIZE / 2)) != (ARSIZE / 2))
 | 
|---|
 | 627 |                 err(5, READ, "on pipe 2");
 | 
|---|
 | 628 |         else if (comp_array(&a[ARSIZE / 2], b, (ARSIZE / 2)) != OK)
 | 
|---|
 | 629 |                 err(7, PIPE, "pipe created");
 | 
|---|
 | 630 | 
 | 
|---|
 | 631 |         /* Try to let the pipe make a mistake */
 | 
|---|
 | 632 |         if (write(fd[0], a, ARSIZE) != FAIL)
 | 
|---|
 | 633 |                 err(11, WRITE, "write on fd[0]");
 | 
|---|
 | 634 |         if (read(fd[1], b, ARSIZE) != FAIL) err(11, READ, "read on fd[1]");
 | 
|---|
 | 635 | 
 | 
|---|
 | 636 |         try_close(fd[1], "'fd[1]'");
 | 
|---|
 | 637 | 
 | 
|---|
 | 638 |         /* Now we shouldn't be able to read, because fd[1] has been closed */
 | 
|---|
 | 639 |         if (read(fd[0], b, ARSIZE) != END_FILE) err(2, PIPE, "'fd[1]'");
 | 
|---|
 | 640 | 
 | 
|---|
 | 641 |         try_close(fd[0], "'fd[0]'");
 | 
|---|
 | 642 |   }
 | 
|---|
 | 643 |   if (pipe(fd) < 0)
 | 
|---|
 | 644 |         err(5, PIPE, "2nd time");
 | 
|---|
 | 645 |   else {
 | 
|---|
 | 646 |         /* Test lseek on a pipe: should fail */
 | 
|---|
 | 647 |         if (write(fd[1], a, ARSIZE) != ARSIZE)
 | 
|---|
 | 648 |                 err(5, WRITE, "on pipe (2nd time)");
 | 
|---|
 | 649 |         if (lseek(fd[1], 10L, SEEK_SET) != FAIL)
 | 
|---|
 | 650 |                 err(11, LSEEK, "lseek on a pipe");
 | 
|---|
 | 651 |         else
 | 
|---|
 | 652 |                 check(PIPE, ESPIPE);
 | 
|---|
 | 653 | 
 | 
|---|
 | 654 |         /* Eat half of the pipe: no writing should be possible */
 | 
|---|
 | 655 |         try_close(fd[0], "'fd[0]'  (2nd time)");
 | 
|---|
 | 656 | 
 | 
|---|
 | 657 |         /* This makes UNIX crash: omit it if pdp or VAX */
 | 
|---|
 | 658 | #ifndef NOCRASH
 | 
|---|
 | 659 |         if (write(fd[1], a, ARSIZE) != FAIL)
 | 
|---|
 | 660 |                 err(11, WRITE, "write on wrong pipe");
 | 
|---|
 | 661 |         else
 | 
|---|
 | 662 |                 check(PIPE, EPIPE);
 | 
|---|
 | 663 | #endif
 | 
|---|
 | 664 |         try_close(fd[1], "'fd[1]'  (2nd time)");
 | 
|---|
 | 665 |   }
 | 
|---|
 | 666 | 
 | 
|---|
 | 667 |   /* BUG :                                                            *
 | 
|---|
 | 668 |    * Here we planned to test if we could write 4K bytes on a pipe.    *
 | 
|---|
 | 669 |    * However, this was not possible to implement, because the whole   *
 | 
|---|
 | 670 |    * Monix system crashed when we tried to write more then 3584 bytes *
 | 
|---|
 | 671 |    * (3.5K) on a pipe. That's why we try to write only 3.5K in the    *
 | 
|---|
 | 672 |    * folowing test.                                                   */
 | 
|---|
 | 673 |   if (pipe(fd) < 0)
 | 
|---|
 | 674 |         err(5, PIPE, "3rd time");
 | 
|---|
 | 675 |   else {
 | 
|---|
 | 676 |         for (n = 0; n < (PIPESIZE / ARSIZE); n++)
 | 
|---|
 | 677 |                 if (write(fd[1], a, ARSIZE) != ARSIZE)
 | 
|---|
 | 678 |                         err(5, WRITE, "on pipe (3rd time) 4K");
 | 
|---|
 | 679 |         try_close(fd[1], "'fd[1]' (3rd time)");
 | 
|---|
 | 680 | 
 | 
|---|
 | 681 |         for (n = 0; n < (PIPESIZE / ARSIZE); n++)
 | 
|---|
 | 682 |                 if (read(fd[0], b, ARSIZE) != ARSIZE)
 | 
|---|
 | 683 |                         err(5, READ, "from pipe (3rd time) 4K");
 | 
|---|
 | 684 |         try_close(fd[0], "'fd[0]' (3rd time)");
 | 
|---|
 | 685 |   }
 | 
|---|
 | 686 | 
 | 
|---|
 | 687 |   /* Test opening a lot of files */
 | 
|---|
 | 688 |   if ((n = open_alot()) != MAXOPEN) err(5, OPEN, "MAXOPEN files");
 | 
|---|
 | 689 |   if (pipe(fd) != FAIL)
 | 
|---|
 | 690 |         err(9, PIPE, "open");
 | 
|---|
 | 691 |   else
 | 
|---|
 | 692 |         check(PIPE, EMFILE);
 | 
|---|
 | 693 |   if (close_alot(n) != n) err(5, CLOSE, "all opened files");
 | 
|---|
 | 694 | }                               /* test11 */
 | 
|---|
 | 695 | 
 | 
|---|
 | 696 | /* New page */ | 
|---|
 | 697 | 
 | 
|---|
 | 698 | 
 | 
|---|
 | 699 | void comp_stats(stbf1, stbf2)
 | 
|---|
 | 700 | struct stat *stbf1, *stbf2;
 | 
|---|
 | 701 | {
 | 
|---|
 | 702 |   if (stbf1->st_dev != stbf2->st_dev) err(7, "st/fst", "'dev'");
 | 
|---|
 | 703 |   if (stbf1->st_ino != stbf2->st_ino) err(7, "st/fst", "'ino'");
 | 
|---|
 | 704 |   if (stbf1->st_mode != stbf2->st_mode) err(7, "st/fst", "'mode'");
 | 
|---|
 | 705 |   if (stbf1->st_nlink != stbf2->st_nlink) err(7, "st/fst", "'nlink'");
 | 
|---|
 | 706 |   if (stbf1->st_uid != stbf2->st_uid) err(7, "st/fst", "'uid'");
 | 
|---|
 | 707 |   if (stbf1->st_gid != stbf2->st_gid) err(7, "st/fst", "'gid'");
 | 
|---|
 | 708 |   if (stbf1->st_rdev != stbf2->st_rdev) err(7, "st/fst", "'rdev'");
 | 
|---|
 | 709 |   if (stbf1->st_size != stbf2->st_size) err(7, "st/fst", "'size'");
 | 
|---|
 | 710 |   if (stbf1->st_atime != stbf2->st_atime) err(7, "st/fst", "'atime'");
 | 
|---|
 | 711 |   if (stbf1->st_mtime != stbf2->st_mtime) err(7, "st/fst", "'mtime'");
 | 
|---|
 | 712 | }                               /* comp_stats */
 | 
|---|
 | 713 | 
 | 
|---|
 | 714 | /* New page */ | 
|---|
 | 715 | 
 | 
|---|
 | 716 | 
 | 
|---|
 | 717 | /* "t5.c", created by Rene Montsma and Menno Wilcke */
 | 
|---|
 | 718 | 
 | 
|---|
 | 719 | void comp_inodes(m, m1)
 | 
|---|
 | 720 | int m, m1;                      /* twee filedes's */
 | 
|---|
 | 721 | {
 | 
|---|
 | 722 |   struct stat stbf1, stbf2;
 | 
|---|
 | 723 | 
 | 
|---|
 | 724 |   if (fstat(m, &stbf1) == OK)
 | 
|---|
 | 725 |         if (fstat(m1, &stbf2) == OK) {
 | 
|---|
 | 726 |                 if (stbf1.st_ino != stbf2.st_ino)
 | 
|---|
 | 727 |                         err(7, DUP, "inode number");
 | 
|---|
 | 728 |         } else
 | 
|---|
 | 729 |                 err(100, "comp_inodes", "cannot 'fstat' (m1)");
 | 
|---|
 | 730 |   else
 | 
|---|
 | 731 |         err(100, "comp_inodes", "cannot 'fstat' (m)");
 | 
|---|
 | 732 | }                               /* comp_inodes */
 | 
|---|
 | 733 | 
 | 
|---|
 | 734 | /* "support.c", created by Rene Montsma and Menno Wilcke */
 | 
|---|
 | 735 | 
 | 
|---|
 | 736 | /* Err, make_and_fill_dirs, init_array, clear_array, comp_array,
 | 
|---|
 | 737 |    try_close, try_unlink, Remove, get_mode, check, open_alot,
 | 
|---|
 | 738 |    close_alot, clean_up_the_mess.
 | 
|---|
 | 739 | */
 | 
|---|
 | 740 | 
 | 
|---|
 | 741 | /***********************************************************************
 | 
|---|
 | 742 |  *                              EXTENDED FIONS                         *
 | 
|---|
 | 743 |  **********************************************************************/
 | 
|---|
 | 744 | /* First extended functions (i.e. not oldfashioned monixcalls.
 | 
|---|
 | 745 |    e(), nlcr(), octal.*/
 | 
|---|
 | 746 | 
 | 
|---|
 | 747 | void e(string)
 | 
|---|
 | 748 | char *string;
 | 
|---|
 | 749 | {
 | 
|---|
 | 750 |   printf("Error: %s ", string);
 | 
|---|
 | 751 | }
 | 
|---|
 | 752 | 
 | 
|---|
 | 753 | void nlcr()
 | 
|---|
 | 754 | {
 | 
|---|
 | 755 |   printf("\n");
 | 
|---|
 | 756 | }
 | 
|---|
 | 757 | 
 | 
|---|
 | 758 | void str(s)
 | 
|---|
 | 759 | char *s;
 | 
|---|
 | 760 | {
 | 
|---|
 | 761 |   printf(s);
 | 
|---|
 | 762 | }
 | 
|---|
 | 763 | 
 | 
|---|
 | 764 | /*****************************************************************************
 | 
|---|
 | 765 | *                                                                            *
 | 
|---|
 | 766 | *                               ERR(or) messages                             *
 | 
|---|
 | 767 | *                                                                            *
 | 
|---|
 | 768 | *****************************************************************************/
 | 
|---|
 | 769 | void err(number, scall, name)
 | 
|---|
 | 770 |  /* Give nice error messages */
 | 
|---|
 | 771 | 
 | 
|---|
 | 772 | char *scall, *name;
 | 
|---|
 | 773 | int number;
 | 
|---|
 | 774 | 
 | 
|---|
 | 775 | {
 | 
|---|
 | 776 |   errct++;
 | 
|---|
 | 777 |   if (errct > MAXERR) {
 | 
|---|
 | 778 |         printf("Too many errors;  test aborted\n");
 | 
|---|
 | 779 |         quit();
 | 
|---|
 | 780 |   }
 | 
|---|
 | 781 |   e("");
 | 
|---|
 | 782 |   str("\t");
 | 
|---|
 | 783 |   switch (number) {
 | 
|---|
 | 784 |       case 0:
 | 
|---|
 | 785 |         str(scall);
 | 
|---|
 | 786 |         str(": illegal initial value.");
 | 
|---|
 | 787 |         break;
 | 
|---|
 | 788 |       case 1:
 | 
|---|
 | 789 |         str(scall);
 | 
|---|
 | 790 |         str(": ");
 | 
|---|
 | 791 |         str(name);
 | 
|---|
 | 792 |         str(" value returned.");
 | 
|---|
 | 793 |         break;
 | 
|---|
 | 794 |       case 2:
 | 
|---|
 | 795 |         str(scall);
 | 
|---|
 | 796 |         str(": accepting illegal ");
 | 
|---|
 | 797 |         str(name);
 | 
|---|
 | 798 |         str(".");
 | 
|---|
 | 799 |         break;
 | 
|---|
 | 800 |       case 3:
 | 
|---|
 | 801 |         str(scall);
 | 
|---|
 | 802 |         str(": accepting non-existing file.");
 | 
|---|
 | 803 |         break;
 | 
|---|
 | 804 |       case 4:
 | 
|---|
 | 805 |         str(scall);
 | 
|---|
 | 806 |         str(": could search non-searchable dir (");
 | 
|---|
 | 807 |         str(name);
 | 
|---|
 | 808 |         str(").");
 | 
|---|
 | 809 |         break;
 | 
|---|
 | 810 |       case 5:
 | 
|---|
 | 811 |         str(scall);
 | 
|---|
 | 812 |         str(": cannot ");
 | 
|---|
 | 813 |         str(scall);
 | 
|---|
 | 814 |         str(" ");
 | 
|---|
 | 815 |         str(name);
 | 
|---|
 | 816 |         str(".");
 | 
|---|
 | 817 |         break;
 | 
|---|
 | 818 |       case 7:
 | 
|---|
 | 819 |         str(scall);
 | 
|---|
 | 820 |         str(": incorrect ");
 | 
|---|
 | 821 |         str(name);
 | 
|---|
 | 822 |         str(".");
 | 
|---|
 | 823 |         break;
 | 
|---|
 | 824 |       case 8:
 | 
|---|
 | 825 |         str(scall);
 | 
|---|
 | 826 |         str(": wrong values.");
 | 
|---|
 | 827 |         break;
 | 
|---|
 | 828 |       case 9:
 | 
|---|
 | 829 |         str(scall);
 | 
|---|
 | 830 |         str(": accepting too many ");
 | 
|---|
 | 831 |         str(name);
 | 
|---|
 | 832 |         str(" files.");
 | 
|---|
 | 833 |         break;
 | 
|---|
 | 834 |       case 10:
 | 
|---|
 | 835 |         str(scall);
 | 
|---|
 | 836 |         str(": even a superuser can't do anything!");
 | 
|---|
 | 837 |         break;
 | 
|---|
 | 838 |       case 11:
 | 
|---|
 | 839 |         str(scall);
 | 
|---|
 | 840 |         str(": could ");
 | 
|---|
 | 841 |         str(name);
 | 
|---|
 | 842 |         str(".");
 | 
|---|
 | 843 |         break;
 | 
|---|
 | 844 |       case 12:
 | 
|---|
 | 845 |         str(scall);
 | 
|---|
 | 846 |         str(": could write in non-writable dir (");
 | 
|---|
 | 847 |         str(name);
 | 
|---|
 | 848 |         str(").");
 | 
|---|
 | 849 |         break;
 | 
|---|
 | 850 |       case 13:
 | 
|---|
 | 851 |         str(scall);
 | 
|---|
 | 852 |         str(": wrong filedes returned (");
 | 
|---|
 | 853 |         str(name);
 | 
|---|
 | 854 |         str(").");
 | 
|---|
 | 855 |         break;
 | 
|---|
 | 856 |       case 100:
 | 
|---|
 | 857 |         str(scall);             /* very common */
 | 
|---|
 | 858 |         str(": ");
 | 
|---|
 | 859 |         str(name);
 | 
|---|
 | 860 |         str(".");
 | 
|---|
 | 861 |         break;
 | 
|---|
 | 862 |       default:  str("errornumber does not exist!\n");
 | 
|---|
 | 863 |   }
 | 
|---|
 | 864 |   nlcr();
 | 
|---|
 | 865 | }                               /* err */
 | 
|---|
 | 866 | 
 | 
|---|
 | 867 | /*****************************************************************************
 | 
|---|
 | 868 | *                                                                            *
 | 
|---|
 | 869 | *                          MAKE_AND_FILL_DIRS                                *
 | 
|---|
 | 870 | *                                                                            *
 | 
|---|
 | 871 | *****************************************************************************/
 | 
|---|
 | 872 | 
 | 
|---|
 | 873 | void make_and_fill_dirs()
 | 
|---|
 | 874 |  /* Create 8 dir.'s: "d---", "d--x", "d-w-", "d-wx", "dr--", "dr-x",     *
 | 
|---|
 | 875 |   * "drw-", "drwx".                                     * Then create 8 files
 | 
|---|
 | 876 |   * in "drwx", and some needed files in other dirs.  */
 | 
|---|
 | 877 | {
 | 
|---|
 | 878 |   int mode, i;
 | 
|---|
 | 879 | 
 | 
|---|
 | 880 |   for (i = 0; i < 8; i++) {
 | 
|---|
 | 881 |         mkdir(dir[i], 0700);
 | 
|---|
 | 882 |         chown(dir[i], USER_ID, GROUP_ID);
 | 
|---|
 | 883 |   }
 | 
|---|
 | 884 |   setuid(USER_ID);
 | 
|---|
 | 885 |   setgid(GROUP_ID);
 | 
|---|
 | 886 | 
 | 
|---|
 | 887 |   for (mode = 0; mode < 8; mode++) put_file_in_dir("drwx", mode);
 | 
|---|
 | 888 | 
 | 
|---|
 | 889 |   put_file_in_dir("d-wx", RWX);
 | 
|---|
 | 890 |   put_file_in_dir("dr-x", RWX);
 | 
|---|
 | 891 |   put_file_in_dir("drw-", RWX);
 | 
|---|
 | 892 | 
 | 
|---|
 | 893 |   chmod_8_dirs(8);              /* 8 means; 8 different modes */
 | 
|---|
 | 894 | 
 | 
|---|
 | 895 | }                               /* make_and_fill_dirs */
 | 
|---|
 | 896 | 
 | 
|---|
 | 897 | void put_file_in_dir(dirname, mode)
 | 
|---|
 | 898 | char *dirname;
 | 
|---|
 | 899 | int mode;
 | 
|---|
 | 900 |  /* Fill directory 'dirname' with file with mode 'mode'.   */
 | 
|---|
 | 901 | {
 | 
|---|
 | 902 |   int nr;
 | 
|---|
 | 903 | 
 | 
|---|
 | 904 |   if (chdir(dirname) != OK)
 | 
|---|
 | 905 |         err(5, CHDIR, "to dirname (put_f_in_dir)");
 | 
|---|
 | 906 |   else {
 | 
|---|
 | 907 |         /* Creat the file */
 | 
|---|
 | 908 |         if ((nr = creat(fnames[mode], mode * 0100)) < 0)
 | 
|---|
 | 909 |                 err(13, CREAT, fnames[mode]);
 | 
|---|
 | 910 |         else
 | 
|---|
 | 911 |                 try_close(nr, fnames[mode]);
 | 
|---|
 | 912 | 
 | 
|---|
 | 913 |         if (chdir("..") != OK)
 | 
|---|
 | 914 |                 err(5, CHDIR, "to previous dir (put_f_in_dir)");
 | 
|---|
 | 915 |   }
 | 
|---|
 | 916 | }                               /* put_file_in_dir */
 | 
|---|
 | 917 | 
 | 
|---|
 | 918 | /*****************************************************************************
 | 
|---|
 | 919 | *                                                                            *
 | 
|---|
 | 920 | *                               MISCELLANEOUS                                *
 | 
|---|
 | 921 | *                                                                            *
 | 
|---|
 | 922 | *(all about arrays, 'try_close', 'try_unlink', 'Remove', 'get_mode')*
 | 
|---|
 | 923 | *                                                                            *
 | 
|---|
 | 924 | *****************************************************************************/
 | 
|---|
 | 925 | 
 | 
|---|
 | 926 | void init_array(a)
 | 
|---|
 | 927 | char *a;
 | 
|---|
 | 928 | {
 | 
|---|
 | 929 |   int i;
 | 
|---|
 | 930 | 
 | 
|---|
 | 931 |   i = 0;
 | 
|---|
 | 932 |   while (i++ < ARSIZE) *a++ = 'a' + (i % 26);
 | 
|---|
 | 933 | }                               /* init_array */
 | 
|---|
 | 934 | 
 | 
|---|
 | 935 | void clear_array(b)
 | 
|---|
 | 936 | char *b;
 | 
|---|
 | 937 | {
 | 
|---|
 | 938 |   int i;
 | 
|---|
 | 939 | 
 | 
|---|
 | 940 |   i = 0;
 | 
|---|
 | 941 |   while (i++ < ARSIZE) *b++ = '0';
 | 
|---|
 | 942 | 
 | 
|---|
 | 943 | }                               /* clear_array */
 | 
|---|
 | 944 | 
 | 
|---|
 | 945 | int comp_array(a, b, range)
 | 
|---|
 | 946 | char *a, *b;
 | 
|---|
 | 947 | int range;
 | 
|---|
 | 948 | {
 | 
|---|
 | 949 |   if ((range < 0) || (range > ARSIZE)) {
 | 
|---|
 | 950 |         err(100, "comp_array", "illegal range");
 | 
|---|
 | 951 |         return(FAIL);
 | 
|---|
 | 952 |   } else {
 | 
|---|
 | 953 |         while (range-- && (*a++ == *b++));
 | 
|---|
 | 954 |         if (*--a == *--b)
 | 
|---|
 | 955 |                 return(OK);
 | 
|---|
 | 956 |         else
 | 
|---|
 | 957 |                 return(FAIL);
 | 
|---|
 | 958 |   }
 | 
|---|
 | 959 | }                               /* comp_array */
 | 
|---|
 | 960 | 
 | 
|---|
 | 961 | void try_close(filedes, name)
 | 
|---|
 | 962 | int filedes;
 | 
|---|
 | 963 | char *name;
 | 
|---|
 | 964 | {
 | 
|---|
 | 965 |   if (close(filedes) != OK) err(5, CLOSE, name);
 | 
|---|
 | 966 | }                               /* try_close */
 | 
|---|
 | 967 | 
 | 
|---|
 | 968 | void try_unlink(fname)
 | 
|---|
 | 969 | char *fname;
 | 
|---|
 | 970 | {
 | 
|---|
 | 971 |   if (unlink(fname) != 0) err(5, UNLINK, fname);
 | 
|---|
 | 972 | }                               /* try_unlink */
 | 
|---|
 | 973 | 
 | 
|---|
 | 974 | void Remove(fdes, fname)
 | 
|---|
 | 975 | int fdes;
 | 
|---|
 | 976 | char *fname;
 | 
|---|
 | 977 | {
 | 
|---|
 | 978 |   try_close(fdes, fname);
 | 
|---|
 | 979 |   try_unlink(fname);
 | 
|---|
 | 980 | }                               /* Remove */
 | 
|---|
 | 981 | 
 | 
|---|
 | 982 | int get_mode(name)
 | 
|---|
 | 983 | char *name;
 | 
|---|
 | 984 | {
 | 
|---|
 | 985 |   struct stat stbf1;
 | 
|---|
 | 986 | 
 | 
|---|
 | 987 |   if (stat(name, &stbf1) != OK) {
 | 
|---|
 | 988 |         err(5, STAT, name);
 | 
|---|
 | 989 |         return(stbf1.st_mode);  /* return a mode which will cause *
 | 
|---|
 | 990 |                                  * error in the calling function  *
 | 
|---|
 | 991 |                                  * (file/dir bit)                 */
 | 
|---|
 | 992 |   } else
 | 
|---|
 | 993 |         return(stbf1.st_mode & 07777);  /* take last 4 bits */
 | 
|---|
 | 994 | }                               /* get_mode */
 | 
|---|
 | 995 | 
 | 
|---|
 | 996 | /*****************************************************************************
 | 
|---|
 | 997 | *                                                                            *
 | 
|---|
 | 998 | *                                  CHECK                                     *
 | 
|---|
 | 999 | *                                                                            *
 | 
|---|
 | 1000 | *****************************************************************************/
 | 
|---|
 | 1001 | 
 | 
|---|
 | 1002 | void check(scall, number)
 | 
|---|
 | 1003 | int number;
 | 
|---|
 | 1004 | char *scall;
 | 
|---|
 | 1005 | {
 | 
|---|
 | 1006 |   if (errno != number) {
 | 
|---|
 | 1007 |         e(NIL);
 | 
|---|
 | 1008 |         str("\t");
 | 
|---|
 | 1009 |         str(scall);
 | 
|---|
 | 1010 |         str(": bad errno-value: ");
 | 
|---|
 | 1011 |         put(errno);
 | 
|---|
 | 1012 |         str(" should have been: ");
 | 
|---|
 | 1013 |         put(number);
 | 
|---|
 | 1014 |         nlcr();
 | 
|---|
 | 1015 |   }
 | 
|---|
 | 1016 | }                               /* check */
 | 
|---|
 | 1017 | 
 | 
|---|
 | 1018 | void put(nr)
 | 
|---|
 | 1019 | int nr;
 | 
|---|
 | 1020 | {
 | 
|---|
 | 1021 |   switch (nr) {
 | 
|---|
 | 1022 |       case 0:   str("unused");          break;
 | 
|---|
 | 1023 |       case 1:   str("EPERM");           break;
 | 
|---|
 | 1024 |       case 2:   str("ENOENT");          break;
 | 
|---|
 | 1025 |       case 3:   str("ESRCH");           break;
 | 
|---|
 | 1026 |       case 4:   str("EINTR");           break;
 | 
|---|
 | 1027 |       case 5:   str("EIO");             break;
 | 
|---|
 | 1028 |       case 6:   str("ENXIO");           break;
 | 
|---|
 | 1029 |       case 7:   str("E2BIG");           break;
 | 
|---|
 | 1030 |       case 8:   str("ENOEXEC");         break;
 | 
|---|
 | 1031 |       case 9:   str("EBADF");           break;
 | 
|---|
 | 1032 |       case 10:  str("ECHILD");          break;
 | 
|---|
 | 1033 |       case 11:  str("EAGAIN");          break;
 | 
|---|
 | 1034 |       case 12:  str("ENOMEM");          break;
 | 
|---|
 | 1035 |       case 13:  str("EACCES");          break;
 | 
|---|
 | 1036 |       case 14:  str("EFAULT");          break;
 | 
|---|
 | 1037 |       case 15:  str("ENOTBLK");         break;
 | 
|---|
 | 1038 |       case 16:  str("EBUSY");           break;
 | 
|---|
 | 1039 |       case 17:  str("EEXIST");          break;
 | 
|---|
 | 1040 |       case 18:  str("EXDEV");           break;
 | 
|---|
 | 1041 |       case 19:  str("ENODEV");          break;
 | 
|---|
 | 1042 |       case 20:  str("ENOTDIR");         break;
 | 
|---|
 | 1043 |       case 21:  str("EISDIR");          break;
 | 
|---|
 | 1044 |       case 22:  str("EINVAL");          break;
 | 
|---|
 | 1045 |       case 23:  str("ENFILE");          break;
 | 
|---|
 | 1046 |       case 24:  str("EMFILE");          break;
 | 
|---|
 | 1047 |       case 25:  str("ENOTTY");          break;
 | 
|---|
 | 1048 |       case 26:  str("ETXTBSY");         break;
 | 
|---|
 | 1049 |       case 27:  str("EFBIG");           break;
 | 
|---|
 | 1050 |       case 28:  str("ENOSPC");          break;
 | 
|---|
 | 1051 |       case 29:  str("ESPIPE");          break;
 | 
|---|
 | 1052 |       case 30:  str("EROFS");           break;
 | 
|---|
 | 1053 |       case 31:  str("EMLINK");          break;
 | 
|---|
 | 1054 |       case 32:  str("EPIPE");           break;
 | 
|---|
 | 1055 |       case 33:  str("EDOM");            break;
 | 
|---|
 | 1056 |       case 34:  str("ERANGE");          break;
 | 
|---|
 | 1057 |   }
 | 
|---|
 | 1058 | }
 | 
|---|
 | 1059 | 
 | 
|---|
 | 1060 | /*****************************************************************************
 | 
|---|
 | 1061 | *                                                                            *
 | 
|---|
 | 1062 | *                                ALOT-functions                              *
 | 
|---|
 | 1063 | *                                                                            *
 | 
|---|
 | 1064 | *****************************************************************************/
 | 
|---|
 | 1065 | 
 | 
|---|
 | 1066 | int open_alot()
 | 
|---|
 | 1067 | {
 | 
|---|
 | 1068 |   int i;
 | 
|---|
 | 1069 | 
 | 
|---|
 | 1070 |   for (i = 0; i < MAXOPEN; i++)
 | 
|---|
 | 1071 |         if (open(file[i], R) == FAIL) break;
 | 
|---|
 | 1072 |   if (i == 0) err(5, "open_alot", "at all");
 | 
|---|
 | 1073 |   return(i);
 | 
|---|
 | 1074 | }                               /* open_alot */
 | 
|---|
 | 1075 | 
 | 
|---|
 | 1076 | int close_alot(number)
 | 
|---|
 | 1077 | int number;
 | 
|---|
 | 1078 | {
 | 
|---|
 | 1079 |   int i, count = 0;
 | 
|---|
 | 1080 | 
 | 
|---|
 | 1081 |   if (number > MAXOPEN)
 | 
|---|
 | 1082 |         err(5, "close_alot", "accept this argument");
 | 
|---|
 | 1083 |   else
 | 
|---|
 | 1084 |         for (i = FF; i < number + FF; i++)
 | 
|---|
 | 1085 |                 if (close(i) != OK) count++;
 | 
|---|
 | 1086 | 
 | 
|---|
 | 1087 |   return(number - count);       /* return number of closed files */
 | 
|---|
 | 1088 | }                               /* close_alot */
 | 
|---|
 | 1089 | 
 | 
|---|
 | 1090 | /*****************************************************************************
 | 
|---|
 | 1091 | *                                                                            *
 | 
|---|
 | 1092 | *                         CLEAN UP THE MESS                                  *
 | 
|---|
 | 1093 | *                                                                            *
 | 
|---|
 | 1094 | *****************************************************************************/
 | 
|---|
 | 1095 | 
 | 
|---|
 | 1096 | void clean_up_the_mess()
 | 
|---|
 | 1097 | {
 | 
|---|
 | 1098 |   int i;
 | 
|---|
 | 1099 |   char dirname[6];
 | 
|---|
 | 1100 | 
 | 
|---|
 | 1101 |   /* First remove 'a lot' files */
 | 
|---|
 | 1102 |   for (i = 0; i < MAXOPEN; i++) try_unlink(file[i]);
 | 
|---|
 | 1103 | 
 | 
|---|
 | 1104 |   /* Unlink the files in dir 'drwx' */
 | 
|---|
 | 1105 |   if (chdir("drwx") != OK)
 | 
|---|
 | 1106 |         err(5, CHDIR, "to 'drwx'");
 | 
|---|
 | 1107 |   else {
 | 
|---|
 | 1108 |         for (i = 0; i < 8; i++) try_unlink(fnames[i]);
 | 
|---|
 | 1109 |         if (chdir("..") != OK) err(5, CHDIR, "to '..'");
 | 
|---|
 | 1110 |   }
 | 
|---|
 | 1111 | 
 | 
|---|
 | 1112 |   /* Before unlinking files in some dirs, make them writable */
 | 
|---|
 | 1113 |   chmod_8_dirs(RWX);
 | 
|---|
 | 1114 | 
 | 
|---|
 | 1115 |   /* Unlink files in other dirs */
 | 
|---|
 | 1116 |   try_unlink("d-wx/rwx");
 | 
|---|
 | 1117 |   try_unlink("dr-x/rwx");
 | 
|---|
 | 1118 |   try_unlink("drw-/rwx");
 | 
|---|
 | 1119 | 
 | 
|---|
 | 1120 |   /* Unlink dirs */
 | 
|---|
 | 1121 |   for (i = 0; i < 8; i++) {
 | 
|---|
 | 1122 |         strcpy(dirname, "d");
 | 
|---|
 | 1123 |         strcat(dirname, fnames[i]);
 | 
|---|
 | 1124 | 
 | 
|---|
 | 1125 |         /* 'dirname' contains the directoryname */
 | 
|---|
 | 1126 |         rmdir(dirname);
 | 
|---|
 | 1127 |   }
 | 
|---|
 | 1128 | 
 | 
|---|
 | 1129 |   /* FINISH */
 | 
|---|
 | 1130 | }                               /* clean_up_the_mess */
 | 
|---|
 | 1131 | 
 | 
|---|
 | 1132 | void chmod_8_dirs(sw)
 | 
|---|
 | 1133 | int sw;                         /* if switch == 8, give all different
 | 
|---|
 | 1134 |                          * mode,else the same mode */
 | 
|---|
 | 1135 | {
 | 
|---|
 | 1136 |   int mode;
 | 
|---|
 | 1137 |   int i;
 | 
|---|
 | 1138 | 
 | 
|---|
 | 1139 |   if (sw == 8)
 | 
|---|
 | 1140 |         mode = 0;
 | 
|---|
 | 1141 |   else
 | 
|---|
 | 1142 |         mode = sw;
 | 
|---|
 | 1143 | 
 | 
|---|
 | 1144 |   for (i = 0; i < 8; i++) {
 | 
|---|
 | 1145 |         chmod(dir[i], 040000 + mode * 0100);
 | 
|---|
 | 1146 |         if (sw == 8) mode++;
 | 
|---|
 | 1147 |   }
 | 
|---|
 | 1148 | }
 | 
|---|
 | 1149 | 
 | 
|---|
 | 1150 | void quit()
 | 
|---|
 | 1151 | {
 | 
|---|
 | 1152 | 
 | 
|---|
 | 1153 |   chdir("..");
 | 
|---|
 | 1154 |   system("rm -rf DIR*");
 | 
|---|
 | 1155 | 
 | 
|---|
 | 1156 |   if (errct == 0) {
 | 
|---|
 | 1157 |         printf("ok\n");
 | 
|---|
 | 1158 |         exit(0);
 | 
|---|
 | 1159 |   } else {
 | 
|---|
 | 1160 |         printf("%d errors\n", errct);
 | 
|---|
 | 1161 |         exit(1);
 | 
|---|
 | 1162 |   }
 | 
|---|
 | 1163 | }
 | 
|---|