1 /* test33: access() Author: Jan-Mark Wams (jms@cs.vu.nl) */
18 #define System(cmd) if (system(cmd) != 0) printf("``%s'' failed\n", cmd)
19 #define Chdir(dir) if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
20 #define Stat(a,b) if (stat(a,b) != 0) printf("Can't stat %s\n", a)
21 #define Chmod(a,b) if (chmod(a,b) != 0) printf("Can't chmod %s\n", a)
22 #define Mkfifo(f) if (mkfifo(f,0777)!=0) printf("Can't make fifo %s\n", f)
26 int superuser
; /* nonzero if uid == euid (euid == 0 always) */
27 char MaxName
[NAME_MAX
+ 1]; /* Name of maximum length */
28 char MaxPath
[PATH_MAX
]; /* Same for path */
29 char ToLongName
[NAME_MAX
+ 2]; /* Name of maximum +1 length */
30 char ToLongPath
[PATH_MAX
+ 1]; /* Same for path, both too long */
32 _PROTOTYPE(void main
, (int argc
, char *argv
[]));
33 _PROTOTYPE(void test33a
, (void));
34 _PROTOTYPE(void test33b
, (void));
35 _PROTOTYPE(void test33c
, (void));
36 _PROTOTYPE(void test33d
, (void));
37 _PROTOTYPE(void test_access
, (void));
38 _PROTOTYPE(void makelongnames
, (void));
39 _PROTOTYPE(void e
, (int number
));
40 _PROTOTYPE(void quit
, (void));
49 if (argc
== 2) m
= atoi(argv
[1]);
54 printf("must be setuid root; test aborted\n");
58 printf("must be setuid root logged in as someone else; test aborted\n");
63 System("rm -rf DIR_33; mkdir DIR_33");
66 superuser
= (getuid() == 0);
68 for (i
= 0; i
< ITERATIONS
; i
++) {
69 if (m
& 0001) test33a();
70 if (m
& 0002) test33b();
71 if (m
& 0004) test33c();
72 if (m
& 0010) test33d();
78 { /* Test normal operation. */
79 int stat_loc
; /* For the wait(&stat_loc) call. */
82 System("rm -rf ../DIR_33/*");
84 /* To test normal access first make some files for real uid. */
86 case -1: printf("Can't fork\n"); break;
89 setuid(getuid()); /* (Re)set the effective ids to the
92 System("> rwx; chmod 700 rwx");
93 System("> rw_; chmod 600 rw_");
94 System("> r_x; chmod 500 r_x");
95 System("> r__; chmod 400 r__");
96 System("> _wx; chmod 300 _wx");
97 System("> _w_; chmod 200 _w_");
98 System("> __x; chmod 100 __x");
99 System("> ___; chmod 000 ___");
104 if (stat_loc
!= 0) e(1);/* Alarm? */
108 /* Let's test access() on directorys. */
110 case -1: printf("Can't fork\n"); break;
113 setuid(getuid()); /* (Re)set the effective ids to the
116 System("rm -rf [_r][_w][_x]");
117 System("mkdir rwx; chmod 700 rwx");
118 System("mkdir rw_; chmod 600 rw_");
119 System("mkdir r_x; chmod 500 r_x");
120 System("mkdir r__; chmod 400 r__");
121 System("mkdir _wx; chmod 300 _wx");
122 System("mkdir _w_; chmod 200 _w_");
123 System("mkdir __x; chmod 100 __x");
124 System("mkdir ___; chmod 000 ___");
129 if (stat_loc
!= 0) e(2);/* Alarm? */
134 case -1: printf("Can't fork\n"); break;
137 setuid(getuid()); /* (Re)set the effective ids to the
140 System("rmdir [_r][_w][_x]");
142 System("chmod 700 rwx");
144 System("chmod 600 rw_");
146 System("chmod 500 r_x");
148 System("chmod 400 r__");
150 System("chmod 300 _wx");
152 System("chmod 200 _w_");
154 System("chmod 100 __x");
156 System("chmod 000 ___");
161 if (stat_loc
!= 0) e(3);/* Alarm? */
165 /* Remove all the fifos. */
167 case -1: printf("Can't fork\n"); break;
172 System("rm -rf [_r][_w][_x]");
177 if (stat_loc
!= 0) e(4);/* Alarm? */
183 int stat_loc
; /* For the wait(&stat_loc) call. */
186 System("rm -rf ../DIR_33/*");
189 case -1: printf("Can't fork\n"); break;
193 /* (Re)set the effective ids to the real ids. */
196 System("> ______rwx; chmod 007 ______rwx");
197 System("> ________x; chmod 001 ________x");
198 System("> _________; chmod 000 _________");
203 if (stat_loc
!= 0) e(1);/* Alarm? */
206 /* If we are superuser, we have access to all. */
207 /* Well, almost, execution access might need at least one X bit. */
209 if (access("_________", R_OK
) != 0) e(2);
210 if (access("_________", W_OK
) != 0) e(3);
211 if (access("________x", R_OK
) != 0) e(4);
212 if (access("________x", W_OK
) != 0) e(5);
213 if (access("________x", X_OK
) != 0) e(6);
214 if (access("______rwx", R_OK
) != 0) e(7);
215 if (access("______rwx", W_OK
) != 0) e(8);
216 if (access("______rwx", X_OK
) != 0) e(9);
219 if (access("_________", R_OK
) != -1) e(10);
220 if (errno
!= EACCES
) e(11);
221 if (access("_________", W_OK
) != -1) e(12);
222 if (errno
!= EACCES
) e(13);
223 if (access("_________", X_OK
) != -1) e(14);
224 if (errno
!= EACCES
) e(15);
225 if (access("________x", R_OK
) != -1) e(16);
226 if (errno
!= EACCES
) e(17);
227 if (access("________x", W_OK
) != -1) e(18);
228 if (errno
!= EACCES
) e(19);
229 if (access("________x", X_OK
) != -1) e(20);
230 if (errno
!= EACCES
) e(21);
231 if (access("______rwx", R_OK
) != -1) e(22);
232 if (errno
!= EACCES
) e(23);
233 if (access("______rwx", W_OK
) != -1) e(24);
234 if (errno
!= EACCES
) e(25);
235 if (access("______rwx", X_OK
) != -1) e(26);
236 if (errno
!= EACCES
) e(27);
239 /* If the real uid != effective uid. */
241 System("rm -rf [_r][_w][_x]");
259 if (access("rwx", F_OK
) != 0) e(28);
260 if (access("rwx", R_OK
) != -1) e(29);
261 if (errno
!= EACCES
) e(30);
262 if (access("rwx", W_OK
) != -1) e(31);
263 if (errno
!= EACCES
) e(32);
264 if (access("rwx", X_OK
) != -1) e(33);
265 if (errno
!= EACCES
) e(34);
267 if (access("rw_", F_OK
) != 0) e(35);
268 if (access("rw_", R_OK
) != -1) e(36);
269 if (errno
!= EACCES
) e(37);
270 if (access("rw_", W_OK
) != -1) e(38);
271 if (errno
!= EACCES
) e(39);
272 if (access("rw_", X_OK
) != -1) e(40);
273 if (errno
!= EACCES
) e(41);
275 if (access("r_x", F_OK
) != 0) e(42);
276 if (access("r_x", R_OK
) != -1) e(43);
277 if (errno
!= EACCES
) e(44);
278 if (access("r_x", W_OK
) != -1) e(45);
279 if (errno
!= EACCES
) e(46);
280 if (access("r_x", X_OK
) != -1) e(47);
281 if (errno
!= EACCES
) e(48);
283 if (access("r__", F_OK
) != 0) e(49);
284 if (access("r__", R_OK
) != -1) e(50);
285 if (errno
!= EACCES
) e(51);
286 if (access("r__", W_OK
) != -1) e(52);
287 if (errno
!= EACCES
) e(53);
288 if (access("r__", X_OK
) != -1) e(54);
289 if (errno
!= EACCES
) e(55);
291 if (access("_wx", F_OK
) != 0) e(56);
292 if (access("_wx", R_OK
) != -1) e(57);
293 if (errno
!= EACCES
) e(58);
294 if (access("_wx", W_OK
) != -1) e(59);
295 if (errno
!= EACCES
) e(60);
296 if (access("_wx", X_OK
) != -1) e(61);
297 if (errno
!= EACCES
) e(62);
299 if (access("_w_", F_OK
) != 0) e(63);
300 if (access("_w_", R_OK
) != -1) e(64);
301 if (errno
!= EACCES
) e(65);
302 if (access("_w_", W_OK
) != -1) e(66);
303 if (errno
!= EACCES
) e(67);
304 if (access("_w_", X_OK
) != -1) e(68);
305 if (errno
!= EACCES
) e(69);
307 if (access("__x", F_OK
) != 0) e(70);
308 if (access("__x", R_OK
) != -1) e(71);
309 if (errno
!= EACCES
) e(72);
310 if (access("__x", W_OK
) != -1) e(73);
311 if (errno
!= EACCES
) e(74);
312 if (access("__x", X_OK
) != -1) e(75);
313 if (errno
!= EACCES
) e(76);
315 if (access("___", F_OK
) != 0) e(77);
316 if (access("___", R_OK
) != -1) e(78);
317 if (errno
!= EACCES
) e(79);
318 if (access("___", W_OK
) != -1) e(80);
319 if (errno
!= EACCES
) e(81);
320 if (access("___", X_OK
) != -1) e(82);
321 if (errno
!= EACCES
) e(83);
323 System("rm -rf [_r][_w][_x]");
328 { /* Test errors returned. */
332 System("rm -rf ../DIR_33/*");
334 /* Test what access() does with non existing files. */
335 System("rm -rf nonexist");
336 if (access("noexist", F_OK
) != -1) e(1);
337 if (errno
!= ENOENT
) e(2);
338 if (access("noexist", R_OK
) != -1) e(3);
339 if (errno
!= ENOENT
) e(4);
340 if (access("noexist", W_OK
) != -1) e(5);
341 if (errno
!= ENOENT
) e(6);
342 if (access("noexist", X_OK
) != -1) e(7);
343 if (errno
!= ENOENT
) e(8);
344 if (access("noexist", R_OK
| W_OK
) != -1) e(9);
345 if (errno
!= ENOENT
) e(10);
346 if (access("noexist", R_OK
| X_OK
) != -1) e(11);
347 if (errno
!= ENOENT
) e(12);
348 if (access("noexist", W_OK
| X_OK
) != -1) e(13);
349 if (errno
!= ENOENT
) e(14);
350 if (access("noexist", R_OK
| W_OK
| X_OK
) != -1) e(15);
351 if (errno
!= ENOENT
) e(16);
353 /* Test access on a nonsearchable path. */
354 if (mkdir("nosearch", 0777) != 0) e(1000);
355 if ( (i
= creat("nosearch/file", 0666)) < 0) e(1001);
356 if (close(i
) < 0) e(1002);
357 if ( (i
= creat("file", 0666) < 0)) e(1003);
358 if (close(i
) < 0) e(1004);
359 if (chmod("nosearch/file", 05777) < 0) e(1005);
360 if (chmod("file", 05777) < 0) e(1006);
361 if (chmod("nosearch", 0677) != 0) e(1007);
362 if (access("nosearch/file", F_OK
) != 0) e(17);
364 /* Test ToLongName and ToLongPath */
365 #ifdef _POSIX_NO_TRUNC
366 # if _POSIX_NO_TRUNC - 0 != -1
367 if (access(ToLongName
, F_OK
) != -1) e(23);
368 if (errno
!= ENAMETOOLONG
) e(24);
370 if (close(creat(ToLongName
, 0777)) != 0) e(25);
371 if (access(ToLongName
, F_OK
) != 0) e(26);
374 # include "error, this case requires dynamic checks and is not handled"
376 ToLongPath
[PATH_MAX
- 2] = '/';
377 ToLongPath
[PATH_MAX
- 1] = 'a';
378 if (access(ToLongPath
, F_OK
) != -1) e(27);
379 if (errno
!= ENAMETOOLONG
) e(28);
380 ToLongPath
[PATH_MAX
- 1] = '/';
382 /* Test empty strings. */
383 if (access("", F_OK
) != -1) e(29);
384 if (errno
!= ENOENT
) e(30);
385 System("rm -rf idonotexist");
386 if (access("idonotexist", F_OK
) != -1) e(31);
387 if (errno
!= ENOENT
) e(32);
389 /* Test non directorys in prefix of path. */
390 if (access("/etc/passwd/dir/foo", F_OK
) != -1) e(33);
391 if (errno
!= ENOTDIR
) e(34);
392 System("rm -rf nodir; > nodir");
393 if (access("nodir/foo", F_OK
) != -1) e(35);
394 if (errno
!= ENOTDIR
) e(36);
396 /* Test if invalid amode arguments are signaled. */
398 Chmod("allmod", 05777);
399 for (i
= -1025; i
< 1025; i
++) {
400 if ((mode_t
) i
!= F_OK
&& ((mode_t
) i
& ~(R_OK
| W_OK
| X_OK
)) != 0) {
401 if (access("allmod", (mode_t
) i
) != -1) e(37);
402 if (errno
!= EINVAL
) e(38);
404 if (access("allmod", (mode_t
) i
) != 0) e(39);
409 { /* Test access() flags. */
410 #define EXCLUDE(a,b) (((a)^(b)) == ((a)|(b)))
412 System("rm -rf ../DIR_33/*");
414 /* The test are rather strong, stronger that POSIX specifies. */
415 /* The should be OR able, this test tests if all the 1 bits */
416 /* Are in diferent places. This should be what one wants. */
417 if (!EXCLUDE(R_OK
, W_OK
| X_OK
)) e(1);
418 if (!EXCLUDE(W_OK
, R_OK
| X_OK
)) e(2);
419 if (!EXCLUDE(X_OK
, R_OK
| W_OK
)) e(3);
420 if (F_OK
== R_OK
) e(4);
421 if (F_OK
== W_OK
) e(5);
422 if (F_OK
== X_OK
) e(6);
423 if (F_OK
== (R_OK
| W_OK
)) e(7);
424 if (F_OK
== (W_OK
| X_OK
)) e(8);
425 if (F_OK
== (R_OK
| X_OK
)) e(9);
426 if (F_OK
== (R_OK
| W_OK
| X_OK
)) e(10);
430 { /* Test all [_r][_w][_x] files. */
432 /* Test normal access. */
433 if (access("rwx", F_OK
) != 0) e(11);
434 if (access("rwx", R_OK
) != 0) e(12);
435 if (access("rwx", W_OK
) != 0) e(13);
436 if (access("rwx", X_OK
) != 0) e(14);
437 if (access("rwx", R_OK
| W_OK
) != 0) e(15);
438 if (access("rwx", R_OK
| X_OK
) != 0) e(16);
439 if (access("rwx", W_OK
| X_OK
) != 0) e(17);
440 if (access("rwx", R_OK
| W_OK
| X_OK
) != 0) e(18);
442 if (access("rw_", F_OK
) != 0) e(19);
443 if (access("rw_", R_OK
) != 0) e(20);
444 if (access("rw_", W_OK
) != 0) e(21);
445 if (access("rw_", X_OK
) != -1) e(22);
446 if (errno
!= EACCES
) e(23);
447 if (access("rw_", R_OK
| W_OK
) != 0) e(24);
448 if (access("rw_", R_OK
| X_OK
) != -1) e(25);
449 if (errno
!= EACCES
) e(26);
450 if (access("rw_", W_OK
| X_OK
) != -1) e(27);
451 if (errno
!= EACCES
) e(28);
452 if (access("rw_", R_OK
| W_OK
| X_OK
) != -1) e(29);
453 if (errno
!= EACCES
) e(30);
455 if (access("r_x", F_OK
) != 0) e(31);
456 if (access("r_x", R_OK
) != 0) e(32);
457 if (access("r_x", W_OK
) != -1) e(33);
458 if (errno
!= EACCES
) e(34);
459 if (access("r_x", X_OK
) != 0) e(35);
460 if (access("r_x", R_OK
| W_OK
) != -1) e(36);
461 if (errno
!= EACCES
) e(37);
462 if (access("r_x", R_OK
| X_OK
) != 0) e(38);
463 if (access("r_x", W_OK
| X_OK
) != -1) e(39);
464 if (errno
!= EACCES
) e(40);
465 if (access("r_x", R_OK
| W_OK
| X_OK
) != -1) e(41);
466 if (errno
!= EACCES
) e(42);
468 if (access("r__", F_OK
) != 0) e(43);
469 if (access("r__", R_OK
) != 0) e(44);
470 if (access("r__", W_OK
) != -1) e(45);
471 if (errno
!= EACCES
) e(46);
472 if (access("r__", X_OK
) != -1) e(47);
473 if (errno
!= EACCES
) e(48);
474 if (access("r__", R_OK
| W_OK
) != -1) e(49);
475 if (errno
!= EACCES
) e(50);
476 if (access("r__", R_OK
| X_OK
) != -1) e(51);
477 if (errno
!= EACCES
) e(52);
478 if (access("r__", W_OK
| X_OK
) != -1) e(53);
479 if (errno
!= EACCES
) e(54);
480 if (access("r__", R_OK
| W_OK
| X_OK
) != -1) e(55);
481 if (errno
!= EACCES
) e(56);
483 if (access("_wx", F_OK
) != 0) e(57);
484 if (access("_wx", R_OK
) != -1) e(58);
485 if (errno
!= EACCES
) e(59);
486 if (access("_wx", W_OK
) != 0) e(60);
487 if (access("_wx", X_OK
) != 0) e(61);
488 if (access("_wx", R_OK
| W_OK
) != -1) e(62);
489 if (errno
!= EACCES
) e(63);
490 if (access("_wx", R_OK
| X_OK
) != -1) e(64);
491 if (errno
!= EACCES
) e(65);
492 if (access("_wx", W_OK
| X_OK
) != 0) e(66);
493 if (access("_wx", R_OK
| W_OK
| X_OK
) != -1) e(67);
494 if (errno
!= EACCES
) e(68);
496 if (access("_w_", F_OK
) != 0) e(69);
497 if (access("_w_", R_OK
) != -1) e(70);
498 if (errno
!= EACCES
) e(71);
499 if (access("_w_", W_OK
) != 0) e(72);
500 if (access("_w_", X_OK
) != -1) e(73);
501 if (errno
!= EACCES
) e(74);
502 if (access("_w_", R_OK
| W_OK
) != -1) e(75);
503 if (errno
!= EACCES
) e(76);
504 if (access("_w_", R_OK
| X_OK
) != -1) e(77);
505 if (errno
!= EACCES
) e(78);
506 if (access("_w_", W_OK
| X_OK
) != -1) e(79);
507 if (errno
!= EACCES
) e(80);
508 if (access("_w_", R_OK
| W_OK
| X_OK
) != -1) e(81);
509 if (errno
!= EACCES
) e(82);
511 if (access("__x", F_OK
) != 0) e(83);
512 if (access("__x", R_OK
) != -1) e(84);
513 if (errno
!= EACCES
) e(85);
514 if (access("__x", W_OK
) != -1) e(86);
515 if (errno
!= EACCES
) e(87);
516 if (access("__x", X_OK
) != 0) e(88);
517 if (access("__x", R_OK
| W_OK
) != -1) e(89);
518 if (errno
!= EACCES
) e(90);
519 if (access("__x", R_OK
| X_OK
) != -1) e(91);
520 if (errno
!= EACCES
) e(92);
521 if (access("__x", W_OK
| X_OK
) != -1) e(93);
522 if (errno
!= EACCES
) e(94);
523 if (access("__x", R_OK
| W_OK
| X_OK
) != -1) e(95);
524 if (errno
!= EACCES
) e(96);
526 if (access("___", F_OK
) != 0) e(97);
527 if (access("___", R_OK
) != -1) e(98);
528 if (errno
!= EACCES
) e(99);
529 if (access("___", W_OK
) != -1) e(100);
530 if (errno
!= EACCES
) e(101);
531 if (access("___", X_OK
) != -1) e(102);
532 if (errno
!= EACCES
) e(103);
533 if (access("___", R_OK
| W_OK
) != -1) e(104);
534 if (errno
!= EACCES
) e(105);
535 if (access("___", R_OK
| X_OK
) != -1) e(106);
536 if (errno
!= EACCES
) e(107);
537 if (access("___", W_OK
| X_OK
) != -1) e(108);
538 if (errno
!= EACCES
) e(109);
539 if (access("___", R_OK
| W_OK
| X_OK
) != -1) e(110);
540 if (errno
!= EACCES
) e(111);
543 /* Test root access don't test X_OK on [_r][_w]_ files. */
544 if (access("rwx", F_OK
) != 0) e(112);
545 if (access("rwx", R_OK
) != 0) e(113);
546 if (access("rwx", W_OK
) != 0) e(114);
547 if (access("rwx", X_OK
) != 0) e(115);
548 if (access("rwx", R_OK
| W_OK
) != 0) e(116);
549 if (access("rwx", R_OK
| X_OK
) != 0) e(117);
550 if (access("rwx", W_OK
| X_OK
) != 0) e(118);
551 if (access("rwx", R_OK
| W_OK
| X_OK
) != 0) e(119);
553 if (access("rw_", F_OK
) != 0) e(120);
554 if (access("rw_", R_OK
) != 0) e(121);
555 if (access("rw_", W_OK
) != 0) e(122);
556 if (access("rw_", R_OK
| W_OK
) != 0) e(123);
558 if (access("r_x", F_OK
) != 0) e(124);
559 if (access("r_x", R_OK
) != 0) e(125);
560 if (access("r_x", W_OK
) != 0) e(126);
561 if (access("r_x", X_OK
) != 0) e(127);
562 if (access("r_x", R_OK
| W_OK
) != 0) e(128);
563 if (access("r_x", R_OK
| X_OK
) != 0) e(129);
564 if (access("r_x", W_OK
| X_OK
) != 0) e(130);
565 if (access("r_x", R_OK
| W_OK
| X_OK
) != 0) e(131);
567 if (access("r__", F_OK
) != 0) e(132);
568 if (access("r__", R_OK
) != 0) e(133);
569 if (access("r__", W_OK
) != 0) e(134);
570 if (access("r__", R_OK
| W_OK
) != 0) e(135);
572 if (access("_wx", F_OK
) != 0) e(136);
573 if (access("_wx", R_OK
) != 0) e(137);
574 if (access("_wx", W_OK
) != 0) e(138);
575 if (access("_wx", X_OK
) != 0) e(139);
576 if (access("_wx", R_OK
| W_OK
) != 0) e(140);
577 if (access("_wx", R_OK
| X_OK
) != 0) e(141);
578 if (access("_wx", W_OK
| X_OK
) != 0) e(142);
579 if (access("_wx", R_OK
| W_OK
| X_OK
) != 0) e(143);
581 if (access("_w_", F_OK
) != 0) e(144);
582 if (access("_w_", R_OK
) != 0) e(145);
583 if (access("_w_", W_OK
) != 0) e(146);
584 if (access("_w_", R_OK
| W_OK
) != 0) e(147);
586 if (access("__x", F_OK
) != 0) e(148);
587 if (access("__x", R_OK
) != 0) e(149);
588 if (access("__x", W_OK
) != 0) e(150);
589 if (access("__x", X_OK
) != 0) e(151);
590 if (access("__x", R_OK
| W_OK
) != 0) e(152);
591 if (access("__x", R_OK
| X_OK
) != 0) e(153);
592 if (access("__x", W_OK
| X_OK
) != 0) e(154);
593 if (access("__x", R_OK
| W_OK
| X_OK
) != 0) e(155);
595 if (access("___", F_OK
) != 0) e(156);
596 if (access("___", R_OK
) != 0) e(157);
597 if (access("___", W_OK
) != 0) e(158);
598 if (access("___", R_OK
| W_OK
) != 0) e(159);
606 memset(MaxName
, 'a', NAME_MAX
);
607 MaxName
[NAME_MAX
] = '\0';
608 for (i
= 0; i
< PATH_MAX
- 1; i
++) { /* idem path */
612 MaxPath
[PATH_MAX
- 1] = '\0';
614 strcpy(ToLongName
, MaxName
); /* copy them Max to ToLong */
615 strcpy(ToLongPath
, MaxPath
);
617 ToLongName
[NAME_MAX
] = 'a';
618 ToLongName
[NAME_MAX
+ 1] = '\0'; /* extend ToLongName by one too many */
619 ToLongPath
[PATH_MAX
- 1] = '/';
620 ToLongPath
[PATH_MAX
] = '\0'; /* inc ToLongPath by one */
626 int err_num
= errno
; /* Save in case printf clobbers it. */
628 printf("Subtest %d, error %d errno=%d: ", subtest
, n
, errno
);
631 if (errct
++ > MAX_ERROR
) {
632 printf("Too many errors; test aborted\n");
634 system("rm -rf DIR*");
643 System("rm -rf DIR_33");
649 printf("%d errors\n", errct
);