xref: /minix/minix/tests/test21.c (revision 433d6423)
1*433d6423SLionel Sambuc /* POSIX test program (21).			Author: Andy Tanenbaum */
2*433d6423SLionel Sambuc 
3*433d6423SLionel Sambuc /* The following POSIX calls are tested:
4*433d6423SLionel Sambuc  *
5*433d6423SLionel Sambuc  *	rename(),  mkdir(),  rmdir()
6*433d6423SLionel Sambuc  */
7*433d6423SLionel Sambuc 
8*433d6423SLionel Sambuc #include <sys/types.h>
9*433d6423SLionel Sambuc #include <sys/stat.h>
10*433d6423SLionel Sambuc #include <errno.h>
11*433d6423SLionel Sambuc #include <fcntl.h>
12*433d6423SLionel Sambuc #include <limits.h>
13*433d6423SLionel Sambuc #include <stdlib.h>
14*433d6423SLionel Sambuc #include <string.h>
15*433d6423SLionel Sambuc #include <unistd.h>
16*433d6423SLionel Sambuc #include <stdio.h>
17*433d6423SLionel Sambuc 
18*433d6423SLionel Sambuc #define ITERATIONS        1
19*433d6423SLionel Sambuc int max_error = 3;
20*433d6423SLionel Sambuc #include "common.h"
21*433d6423SLionel Sambuc 
22*433d6423SLionel Sambuc 
23*433d6423SLionel Sambuc 
24*433d6423SLionel Sambuc int main(int argc, char *argv []);
25*433d6423SLionel Sambuc void test21a(void);
26*433d6423SLionel Sambuc void test21b(void);
27*433d6423SLionel Sambuc void test21c(void);
28*433d6423SLionel Sambuc void test21d(void);
29*433d6423SLionel Sambuc void test21e(void);
30*433d6423SLionel Sambuc void test21f(void);
31*433d6423SLionel Sambuc void test21g(void);
32*433d6423SLionel Sambuc void test21h(void);
33*433d6423SLionel Sambuc void test21i(void);
34*433d6423SLionel Sambuc void test21k(void);
35*433d6423SLionel Sambuc void test21l(void);
36*433d6423SLionel Sambuc void test21m(void);
37*433d6423SLionel Sambuc void test21n(void);
38*433d6423SLionel Sambuc void test21o(void);
39*433d6423SLionel Sambuc int get_link(char *name);
40*433d6423SLionel Sambuc 
main(argc,argv)41*433d6423SLionel Sambuc int main(argc, argv)
42*433d6423SLionel Sambuc int argc;
43*433d6423SLionel Sambuc char *argv[];
44*433d6423SLionel Sambuc {
45*433d6423SLionel Sambuc 
46*433d6423SLionel Sambuc   int i, m = 0xFFFF;
47*433d6423SLionel Sambuc 
48*433d6423SLionel Sambuc   start(21);
49*433d6423SLionel Sambuc 
50*433d6423SLionel Sambuc   if (argc == 2) m = atoi(argv[1]);
51*433d6423SLionel Sambuc 
52*433d6423SLionel Sambuc   for (i = 0; i < ITERATIONS; i++) {
53*433d6423SLionel Sambuc 	if (m & 00001) test21a();
54*433d6423SLionel Sambuc 	if (m & 00002) test21b();
55*433d6423SLionel Sambuc 	if (m & 00004) test21c();
56*433d6423SLionel Sambuc 	if (m & 00010) test21d();
57*433d6423SLionel Sambuc 	if (m & 00020) test21e();
58*433d6423SLionel Sambuc 	if (m & 00040) test21f();
59*433d6423SLionel Sambuc 	if (m & 01000) test21g();
60*433d6423SLionel Sambuc 	if (m & 00200) test21h();
61*433d6423SLionel Sambuc 	if (m & 00400) test21i();
62*433d6423SLionel Sambuc 	if (m & 01000) test21k();
63*433d6423SLionel Sambuc 	if (m & 02000) test21l();
64*433d6423SLionel Sambuc 	if (m & 04000) test21m();
65*433d6423SLionel Sambuc 	if (m & 010000) test21n();
66*433d6423SLionel Sambuc 	if (m & 020000) test21o();
67*433d6423SLionel Sambuc   }
68*433d6423SLionel Sambuc   quit();
69*433d6423SLionel Sambuc 
70*433d6423SLionel Sambuc   return(-1);	/* Unreachable */
71*433d6423SLionel Sambuc }
72*433d6423SLionel Sambuc 
test21a()73*433d6423SLionel Sambuc void test21a()
74*433d6423SLionel Sambuc {
75*433d6423SLionel Sambuc /* Test rename(). */
76*433d6423SLionel Sambuc 
77*433d6423SLionel Sambuc   int fd, fd2;
78*433d6423SLionel Sambuc   char buf[PATH_MAX+1], buf1[PATH_MAX+1], buf2[PATH_MAX+1];
79*433d6423SLionel Sambuc   struct stat stat1, stat2;
80*433d6423SLionel Sambuc 
81*433d6423SLionel Sambuc   subtest = 1;
82*433d6423SLionel Sambuc 
83*433d6423SLionel Sambuc   unlink("A1");			/* get rid of it if it exists */
84*433d6423SLionel Sambuc   unlink("A2");			/* get rid of it if it exists */
85*433d6423SLionel Sambuc   unlink("A3");			/* get rid of it if it exists */
86*433d6423SLionel Sambuc   unlink("A4");			/* get rid of it if it exists */
87*433d6423SLionel Sambuc   unlink("A5");			/* get rid of it if it exists */
88*433d6423SLionel Sambuc   unlink("A6");			/* get rid of it if it exists */
89*433d6423SLionel Sambuc   unlink("A7");			/* get rid of it if it exists */
90*433d6423SLionel Sambuc 
91*433d6423SLionel Sambuc   /* Basic test.  Rename A1 to A2 and then A2 to A3. */
92*433d6423SLionel Sambuc   if ( (fd=creat("A1", 0666)) < 0) e(1);
93*433d6423SLionel Sambuc   if (write(fd, buf, 20) != 20) e(2);
94*433d6423SLionel Sambuc   if (close(fd) < 0) e(3);
95*433d6423SLionel Sambuc   if (rename("A1", "A2") < 0) e(4);
96*433d6423SLionel Sambuc   if ( (fd=open("A2", O_RDONLY)) < 0) e(5);
97*433d6423SLionel Sambuc   if (rename("A2", "A3") < 0) e(6);
98*433d6423SLionel Sambuc   if ( (fd2=open("A3", O_RDONLY)) < 0) e(7);
99*433d6423SLionel Sambuc   if (close(fd) != 0) e(8);
100*433d6423SLionel Sambuc   if (close(fd2) != 0) e(9);
101*433d6423SLionel Sambuc   if (unlink("A3") != 0) e(10);
102*433d6423SLionel Sambuc 
103*433d6423SLionel Sambuc   /* Now get the absolute path name of the current directory using getcwd()
104*433d6423SLionel Sambuc    * and use it to test RENAME using different combinations of relative and
105*433d6423SLionel Sambuc    * absolute path names.
106*433d6423SLionel Sambuc    */
107*433d6423SLionel Sambuc   if (getcwd(buf, PATH_MAX) == (char *) NULL) e(11);
108*433d6423SLionel Sambuc   if ( (fd = creat("A4", 0666)) < 0) e(12);
109*433d6423SLionel Sambuc   if (write(fd, buf, 30) != 30) e(13);
110*433d6423SLionel Sambuc   if (close(fd) != 0) e(14);
111*433d6423SLionel Sambuc   strcpy(buf1, buf);
112*433d6423SLionel Sambuc   strcat(buf1, "/A4");
113*433d6423SLionel Sambuc   if (rename(buf1, "A5") != 0) e(15);	/* rename(absolute, relative) */
114*433d6423SLionel Sambuc   if (access("A5", 6) != 0) e(16);	/* use access to see if file exists */
115*433d6423SLionel Sambuc   strcpy(buf2, buf);
116*433d6423SLionel Sambuc   strcat(buf2, "/A6");
117*433d6423SLionel Sambuc   if (rename("A5", buf2) != 0) e(17);	/* rename(relative, absolute) */
118*433d6423SLionel Sambuc   if (access("A6", 6) != 0) e(18);
119*433d6423SLionel Sambuc   if (access(buf2, 6) != 0) e(19);
120*433d6423SLionel Sambuc   strcpy(buf1, buf);
121*433d6423SLionel Sambuc   strcat(buf1, "/A6");
122*433d6423SLionel Sambuc   strcpy(buf2, buf);
123*433d6423SLionel Sambuc   strcat(buf2, "/A7");
124*433d6423SLionel Sambuc   if (rename(buf1, buf2) != 0) e(20);	/* rename(absolute, absolute) */
125*433d6423SLionel Sambuc   if (access("A7", 6) != 0) e(21);
126*433d6423SLionel Sambuc   if (access(buf2, 6) != 0) e(22);
127*433d6423SLionel Sambuc 
128*433d6423SLionel Sambuc   /* Try renaming using names like "./A8" */
129*433d6423SLionel Sambuc   if (rename("A7", "./A8") != 0) e(23);
130*433d6423SLionel Sambuc   if (access("A8", 6) != 0) e(24);
131*433d6423SLionel Sambuc   if (rename("./A8", "A9") != 0) e(25);
132*433d6423SLionel Sambuc   if (access("A9", 6) != 0) e(26);
133*433d6423SLionel Sambuc   if (rename("./A9", "./A10") != 0) e(27);
134*433d6423SLionel Sambuc   if (access("A10", 6) != 0) e(28);
135*433d6423SLionel Sambuc   if (access("./A10", 6) != 0) e(29);
136*433d6423SLionel Sambuc   if (unlink("A10") != 0) e(30);
137*433d6423SLionel Sambuc 
138*433d6423SLionel Sambuc   /* Now see if directories can be renamed. */
139*433d6423SLionel Sambuc   if (system("rm -rf ?uzzy scsi") != 0) e(31);
140*433d6423SLionel Sambuc   if (system("mkdir fuzzy") != 0) e(32);
141*433d6423SLionel Sambuc   if (rename("fuzzy", "wuzzy") != 0) e(33);
142*433d6423SLionel Sambuc   if ( (fd=creat("wuzzy/was_a_bear", 0666)) < 0) e(34);
143*433d6423SLionel Sambuc   if (access("wuzzy/was_a_bear", 6) != 0) e(35);
144*433d6423SLionel Sambuc   if (unlink("wuzzy/was_a_bear") != 0) e(36);
145*433d6423SLionel Sambuc   if (close(fd) != 0) e(37);
146*433d6423SLionel Sambuc   if (rename("wuzzy", "buzzy") != 0) e(38);
147*433d6423SLionel Sambuc   if (system("rmdir buzzy") != 0) e(39);
148*433d6423SLionel Sambuc 
149*433d6423SLionel Sambuc   /* Now start testing the case that 'new' exists. */
150*433d6423SLionel Sambuc   if ( (fd = creat("horse", 0666)) < 0) e(40);
151*433d6423SLionel Sambuc   if ( (fd2 = creat("sheep", 0666)) < 0) e(41);
152*433d6423SLionel Sambuc   if (write(fd, buf, PATH_MAX) != PATH_MAX) e(42);
153*433d6423SLionel Sambuc   if (write(fd2, buf, 23) != 23) e(43);
154*433d6423SLionel Sambuc   if (stat("horse", &stat1) != 0) e(44);
155*433d6423SLionel Sambuc   if (rename("horse", "sheep") != 0) e(45);
156*433d6423SLionel Sambuc   if (stat("sheep", &stat2) != 0) e(46);
157*433d6423SLionel Sambuc   if (stat1.st_dev != stat2.st_dev) e(47);
158*433d6423SLionel Sambuc   if (stat1.st_ino != stat2.st_ino) e(48);
159*433d6423SLionel Sambuc   if (stat2.st_size != PATH_MAX) e(49);
160*433d6423SLionel Sambuc   if (access("horse", 6) == 0) e(50);
161*433d6423SLionel Sambuc   if (close(fd) != 0) e(51);
162*433d6423SLionel Sambuc   if (close(fd2) != 0) e(52);
163*433d6423SLionel Sambuc   if (rename("sheep", "sheep") != 0) e(53);
164*433d6423SLionel Sambuc   if (unlink("sheep") != 0) e(54);
165*433d6423SLionel Sambuc 
166*433d6423SLionel Sambuc   /* Now try renaming something to a directory that already exists. */
167*433d6423SLionel Sambuc   if (system("mkdir fuzzy wuzzy") != 0) e(55);
168*433d6423SLionel Sambuc   if ( (fd = creat("fuzzy/was_a_bear", 0666)) < 0) e(56);
169*433d6423SLionel Sambuc   if (close(fd) != 0) e(57);
170*433d6423SLionel Sambuc   if (rename("fuzzy", "wuzzy") != 0) e(58);	/* 'new' is empty dir */
171*433d6423SLionel Sambuc   if (system("mkdir scsi") != 0) e(59);
172*433d6423SLionel Sambuc   if (rename("scsi", "wuzzy") == 0) e(60);	/* 'new' is full dir */
173*433d6423SLionel Sambuc   if (errno != EEXIST && errno != ENOTEMPTY) e(61);
174*433d6423SLionel Sambuc 
175*433d6423SLionel Sambuc   /* Test 14 character names--always tricky. */
176*433d6423SLionel Sambuc   if (rename("wuzzy/was_a_bear", "wuzzy/was_not_a_bear") != 0) e(62);
177*433d6423SLionel Sambuc   if (access("wuzzy/was_not_a_bear", 6) != 0) e(63);
178*433d6423SLionel Sambuc   if (rename("wuzzy/was_not_a_bear", "wuzzy/was_not_a_duck") != 0) e(64);
179*433d6423SLionel Sambuc   if (access("wuzzy/was_not_a_duck", 6) != 0) e(65);
180*433d6423SLionel Sambuc   if (rename("wuzzy/was_not_a_duck", "wuzzy/was_a_bird") != 0) e(65);
181*433d6423SLionel Sambuc   if (access("wuzzy/was_a_bird", 6) != 0) e(66);
182*433d6423SLionel Sambuc 
183*433d6423SLionel Sambuc   /* Test moves between directories. */
184*433d6423SLionel Sambuc   if (rename("wuzzy/was_a_bird", "beast") != 0) e(67);
185*433d6423SLionel Sambuc   if (access("beast", 6) != 0) e(68);
186*433d6423SLionel Sambuc   if (rename("beast", "wuzzy/was_a_cat") != 0) e(69);
187*433d6423SLionel Sambuc   if (access("wuzzy/was_a_cat", 6) != 0) e(70);
188*433d6423SLionel Sambuc 
189*433d6423SLionel Sambuc   /* Test error conditions. 'scsi' and 'wuzzy/was_a_cat' exist now. */
190*433d6423SLionel Sambuc   if (rename("wuzzy/was_a_cat", "wuzzy/was_a_dog") != 0) e(71);
191*433d6423SLionel Sambuc   if (access("wuzzy/was_a_dog", 6) != 0) e(72);
192*433d6423SLionel Sambuc   if (chmod("wuzzy", 0) != 0) e(73);
193*433d6423SLionel Sambuc 
194*433d6423SLionel Sambuc   errno = 0;
195*433d6423SLionel Sambuc   if (rename("wuzzy/was_a_dog", "wuzzy/was_a_pig") != -1) e(74);
196*433d6423SLionel Sambuc   if (errno != EACCES) e(75);
197*433d6423SLionel Sambuc 
198*433d6423SLionel Sambuc   errno = 0;
199*433d6423SLionel Sambuc   if (rename("wuzzy/was_a_dog", "doggie") != -1) e(76);
200*433d6423SLionel Sambuc   if (errno != EACCES) e(77);
201*433d6423SLionel Sambuc 
202*433d6423SLionel Sambuc   errno = 0;
203*433d6423SLionel Sambuc   if ( (fd = creat("beast", 0666)) < 0) e(78);
204*433d6423SLionel Sambuc   if (close(fd) != 0) e(79);
205*433d6423SLionel Sambuc   if (rename("beast", "wuzzy/was_a_twit") != -1) e(80);
206*433d6423SLionel Sambuc   if (errno != EACCES) e(81);
207*433d6423SLionel Sambuc 
208*433d6423SLionel Sambuc   errno = 0;
209*433d6423SLionel Sambuc   if (rename("beast", "wuzzy") != -1) e(82);
210*433d6423SLionel Sambuc   if (errno != EISDIR) e(83);
211*433d6423SLionel Sambuc 
212*433d6423SLionel Sambuc   errno = 0;
213*433d6423SLionel Sambuc   if (rename("beest", "baste") != -1) e(84);
214*433d6423SLionel Sambuc   if (errno != ENOENT) e(85);
215*433d6423SLionel Sambuc 
216*433d6423SLionel Sambuc   errno = 0;
217*433d6423SLionel Sambuc   if (rename("wuzzy", "beast") != -1) e(86);
218*433d6423SLionel Sambuc   if (errno != ENOTDIR) e(87);
219*433d6423SLionel Sambuc 
220*433d6423SLionel Sambuc   /* Test prefix rule. */
221*433d6423SLionel Sambuc   errno = 0;
222*433d6423SLionel Sambuc   if (chmod("wuzzy", 0777) != 0) e(88);
223*433d6423SLionel Sambuc   if (unlink("wuzzy/was_a_dog") != 0) e(89);
224*433d6423SLionel Sambuc   strcpy(buf1, buf);
225*433d6423SLionel Sambuc   strcat(buf1, "/wuzzy");
226*433d6423SLionel Sambuc   if (rename(buf, buf1) != -1) e(90);
227*433d6423SLionel Sambuc   if (errno != EINVAL) e(91);
228*433d6423SLionel Sambuc 
229*433d6423SLionel Sambuc   if (system("rm -rf wuzzy beast scsi") != 0) e(92);
230*433d6423SLionel Sambuc }
231*433d6423SLionel Sambuc 
232*433d6423SLionel Sambuc 
233*433d6423SLionel Sambuc 
test21b()234*433d6423SLionel Sambuc void test21b()
235*433d6423SLionel Sambuc {
236*433d6423SLionel Sambuc /* Test mkdir() and rmdir(). */
237*433d6423SLionel Sambuc 
238*433d6423SLionel Sambuc   int i;
239*433d6423SLionel Sambuc   char name[3];
240*433d6423SLionel Sambuc   struct stat statbuf;
241*433d6423SLionel Sambuc 
242*433d6423SLionel Sambuc   subtest = 2;
243*433d6423SLionel Sambuc 
244*433d6423SLionel Sambuc   /* Simple stuff. */
245*433d6423SLionel Sambuc   if (mkdir("D1", 0700) != 0) e(1);
246*433d6423SLionel Sambuc   if (stat("D1", &statbuf) != 0) e(2);
247*433d6423SLionel Sambuc   if (!S_ISDIR(statbuf.st_mode)) e(3);
248*433d6423SLionel Sambuc   if ( (statbuf.st_mode & 0777) != 0700) e(4);
249*433d6423SLionel Sambuc   if (rmdir("D1") != 0) e(5);
250*433d6423SLionel Sambuc 
251*433d6423SLionel Sambuc   /* Make and remove 40 directories.  By doing so, the directory has to
252*433d6423SLionel Sambuc    * grow to 2 blocks.  That presents plenty of opportunity for bugs.
253*433d6423SLionel Sambuc    */
254*433d6423SLionel Sambuc   name[0] = 'D';
255*433d6423SLionel Sambuc   name[2] = '\0';
256*433d6423SLionel Sambuc   for (i = 0; i < 40; i++) {
257*433d6423SLionel Sambuc 	name[1] = 'A' + i;
258*433d6423SLionel Sambuc 	if (mkdir(name, 0700 + i%7) != 0) e(10+i);	/* for simplicity */
259*433d6423SLionel Sambuc   }
260*433d6423SLionel Sambuc   for (i = 0; i < 40; i++) {
261*433d6423SLionel Sambuc 	name[1] = 'A' + i;
262*433d6423SLionel Sambuc 	if (rmdir(name) != 0) e(50+i);
263*433d6423SLionel Sambuc   }
264*433d6423SLionel Sambuc }
265*433d6423SLionel Sambuc 
test21c()266*433d6423SLionel Sambuc void test21c()
267*433d6423SLionel Sambuc {
268*433d6423SLionel Sambuc /* Test mkdir() and rmdir(). */
269*433d6423SLionel Sambuc 
270*433d6423SLionel Sambuc   subtest = 3;
271*433d6423SLionel Sambuc 
272*433d6423SLionel Sambuc   if (mkdir("D1", 0777) != 0) e(1);
273*433d6423SLionel Sambuc   if (mkdir("D1/D2", 0777) != 0) e(2);
274*433d6423SLionel Sambuc   if (mkdir("D1/D2/D3", 0777) != 0) e(3);
275*433d6423SLionel Sambuc   if (mkdir("D1/D2/D3/D4", 0777) != 0) e(4);
276*433d6423SLionel Sambuc   if (mkdir("D1/D2/D3/D4/D5", 0777) != 0) e(5);
277*433d6423SLionel Sambuc   if (mkdir("D1/D2/D3/D4/D5/D6", 0777) != 0) e(6);
278*433d6423SLionel Sambuc   if (mkdir("D1/D2/D3/D4/D5/D6/D7", 0777) != 0) e(7);
279*433d6423SLionel Sambuc   if (mkdir("D1/D2/D3/D4/D5/D6/D7/D8", 0777) != 0) e(8);
280*433d6423SLionel Sambuc   if (mkdir("D1/D2/D3/D4/D5/D6/D7/D8/D9", 0777) != 0) e(9);
281*433d6423SLionel Sambuc   if (access("D1/D2/D3/D4/D5/D6/D7/D8/D9", 7) != 0) e(10);
282*433d6423SLionel Sambuc   if (rmdir("D1/D2/D3/D4/D5/D6/D7/D8/D9") != 0) e(11);
283*433d6423SLionel Sambuc   if (rmdir("D1/D2/D3/D4/D5/D6/D7/D8") != 0) e(12);
284*433d6423SLionel Sambuc   if (rmdir("D1/D2/D3/D4/D5/D6/D7") != 0) e(13);
285*433d6423SLionel Sambuc   if (rmdir("D1/D2/D3/D4/D5/D6") != 0) e(11);
286*433d6423SLionel Sambuc   if (rmdir("D1/D2/D3/D4/D5") != 0) e(13);
287*433d6423SLionel Sambuc   if (rmdir("D1/D2/D3/D4") != 0) e(14);
288*433d6423SLionel Sambuc   if (rmdir("D1/D2/D3") != 0) e(15);
289*433d6423SLionel Sambuc   if (rmdir("D1/D2") != 0) e(16);
290*433d6423SLionel Sambuc   if (rmdir("D1") != 0) e(17);
291*433d6423SLionel Sambuc }
292*433d6423SLionel Sambuc 
test21d()293*433d6423SLionel Sambuc void test21d()
294*433d6423SLionel Sambuc {
295*433d6423SLionel Sambuc /* Test making directories with files and directories in them. */
296*433d6423SLionel Sambuc 
297*433d6423SLionel Sambuc   int fd1, fd2, fd3, fd4, fd5, fd6, fd7, fd8, fd9;
298*433d6423SLionel Sambuc 
299*433d6423SLionel Sambuc   subtest = 4;
300*433d6423SLionel Sambuc 
301*433d6423SLionel Sambuc   if (mkdir("D1", 0777) != 0) e(1);
302*433d6423SLionel Sambuc   if (mkdir("D1/D2", 0777) != 0) e(2);
303*433d6423SLionel Sambuc   if (mkdir("./D1/D3", 0777) != 0) e(3);
304*433d6423SLionel Sambuc   if (mkdir("././D1/D4", 0777) != 0) e(4);
305*433d6423SLionel Sambuc   if ( (fd1 = creat("D1/D2/x", 0700)) < 0) e(5);
306*433d6423SLionel Sambuc   if ( (fd2 = creat("D1/D2/y", 0700)) < 0) e(6);
307*433d6423SLionel Sambuc   if ( (fd3 = creat("D1/D2/z", 0700)) < 0) e(7);
308*433d6423SLionel Sambuc   if ( (fd4 = creat("D1/D3/x", 0700)) < 0) e(8);
309*433d6423SLionel Sambuc   if ( (fd5 = creat("D1/D3/y", 0700)) < 0) e(9);
310*433d6423SLionel Sambuc   if ( (fd6 = creat("D1/D3/z", 0700)) < 0) e(10);
311*433d6423SLionel Sambuc   if ( (fd7 = creat("D1/D4/x", 0700)) < 0) e(11);
312*433d6423SLionel Sambuc   if ( (fd8 = creat("D1/D4/y", 0700)) < 0) e(12);
313*433d6423SLionel Sambuc   if ( (fd9 = creat("D1/D4/z", 0700)) < 0) e(13);
314*433d6423SLionel Sambuc   if (unlink("D1/D2/z") != 0) e(14);
315*433d6423SLionel Sambuc   if (unlink("D1/D2/y") != 0) e(15);
316*433d6423SLionel Sambuc   if (unlink("D1/D2/x") != 0) e(16);
317*433d6423SLionel Sambuc   if (unlink("D1/D3/x") != 0) e(17);
318*433d6423SLionel Sambuc   if (unlink("D1/D3/z") != 0) e(18);
319*433d6423SLionel Sambuc   if (unlink("D1/D3/y") != 0) e(19);
320*433d6423SLionel Sambuc   if (unlink("D1/D4/y") != 0) e(20);
321*433d6423SLionel Sambuc   if (unlink("D1/D4/z") != 0) e(21);
322*433d6423SLionel Sambuc   if (unlink("D1/D4/x") != 0) e(22);
323*433d6423SLionel Sambuc   if (rmdir("D1/D2") != 0) e(23);
324*433d6423SLionel Sambuc   if (rmdir("D1/D3") != 0) e(24);
325*433d6423SLionel Sambuc   if (rmdir("D1/D4") != 0) e(25);
326*433d6423SLionel Sambuc   if (rmdir("D1") != 0) e(26);
327*433d6423SLionel Sambuc   if (close(fd1) != 0) e(27);
328*433d6423SLionel Sambuc   if (close(fd2) != 0) e(28);
329*433d6423SLionel Sambuc   if (close(fd3) != 0) e(29);
330*433d6423SLionel Sambuc   if (close(fd4) != 0) e(30);
331*433d6423SLionel Sambuc   if (close(fd5) != 0) e(31);
332*433d6423SLionel Sambuc   if (close(fd6) != 0) e(32);
333*433d6423SLionel Sambuc   if (close(fd7) != 0) e(33);
334*433d6423SLionel Sambuc   if (close(fd8) != 0) e(34);
335*433d6423SLionel Sambuc   if (close(fd9) != 0) e(35);
336*433d6423SLionel Sambuc 
337*433d6423SLionel Sambuc }
338*433d6423SLionel Sambuc 
test21e()339*433d6423SLionel Sambuc void test21e()
340*433d6423SLionel Sambuc {
341*433d6423SLionel Sambuc /* Test error conditions. */
342*433d6423SLionel Sambuc 
343*433d6423SLionel Sambuc   subtest = 5;
344*433d6423SLionel Sambuc 
345*433d6423SLionel Sambuc   if (mkdir("D1", 0677) != 0) e(1);
346*433d6423SLionel Sambuc   errno = 0;
347*433d6423SLionel Sambuc   if (mkdir("D1/D2", 0777) != -1) e(2);
348*433d6423SLionel Sambuc   if (errno != EACCES) e(3);
349*433d6423SLionel Sambuc   if (chmod ("D1", 0577) != 0) e(4);
350*433d6423SLionel Sambuc   errno = 0;
351*433d6423SLionel Sambuc   if (mkdir("D1/D2", 0777) != -1) e(5);
352*433d6423SLionel Sambuc   if (errno != EACCES) e(6);
353*433d6423SLionel Sambuc   if (chmod ("D1", 0777) != 0) e(7);
354*433d6423SLionel Sambuc   errno = 0;
355*433d6423SLionel Sambuc   if (mkdir("D1", 0777) != -1) e(8);
356*433d6423SLionel Sambuc   if (errno != EEXIST) e(9);
357*433d6423SLionel Sambuc   errno = 0;
358*433d6423SLionel Sambuc   if (mkdir("D1/D2/x", 0777) != -1) e(14);
359*433d6423SLionel Sambuc   if (errno != ENOENT) e(15);
360*433d6423SLionel Sambuc 
361*433d6423SLionel Sambuc   /* A particularly nasty test is when the parent has mode 0.  Although
362*433d6423SLionel Sambuc    * this is unlikely to work, it had better not muck up the file system
363*433d6423SLionel Sambuc    */
364*433d6423SLionel Sambuc   if (mkdir("D1/D2", 0777) != 0) e(16);
365*433d6423SLionel Sambuc   if (chmod("D1", 0) != 0) e(17);
366*433d6423SLionel Sambuc   errno = 0;
367*433d6423SLionel Sambuc   if (rmdir("D1/D2") != -1) e(18);
368*433d6423SLionel Sambuc   if (errno != EACCES) e(19);
369*433d6423SLionel Sambuc   if (chmod("D1", 0777) != 0) e(20);
370*433d6423SLionel Sambuc   if (rmdir("D1/D2") != 0) e(21);
371*433d6423SLionel Sambuc   if (rmdir("D1") != 0) e(22);
372*433d6423SLionel Sambuc }
373*433d6423SLionel Sambuc 
test21f()374*433d6423SLionel Sambuc void test21f()
375*433d6423SLionel Sambuc {
376*433d6423SLionel Sambuc /* The rename() function affects the link count of all the files and
377*433d6423SLionel Sambuc  * directories it goes near.  Test to make sure it gets everything ok.
378*433d6423SLionel Sambuc  * There are four cases:
379*433d6423SLionel Sambuc  *
380*433d6423SLionel Sambuc  *   1. rename("d1/file1", "d1/file2");	- rename file without moving it
381*433d6423SLionel Sambuc  *   2. rename("d1/file1", "d2/file2");	- move a file to another dir
382*433d6423SLionel Sambuc  *   3. rename("d1/dir1", "d2/dir2");	- rename a dir without moving it
383*433d6423SLionel Sambuc  *   4. rename("d1/dir1", "d2/dir2");	- move a dir to another dir
384*433d6423SLionel Sambuc  *
385*433d6423SLionel Sambuc  * Furthermore, a distinction has to be made when the target file exists
386*433d6423SLionel Sambuc  * and when it does not exist, giving 8 cases in all.
387*433d6423SLionel Sambuc  */
388*433d6423SLionel Sambuc 
389*433d6423SLionel Sambuc   int fd, D1_before, D1_after, x_link, y_link;
390*433d6423SLionel Sambuc 
391*433d6423SLionel Sambuc   /* Test case 1: renaming a file within the same directory. */
392*433d6423SLionel Sambuc   subtest = 6;
393*433d6423SLionel Sambuc   if (mkdir("D1", 0777) != 0) e(1);
394*433d6423SLionel Sambuc   if ( (fd = creat("D1/x", 0777)) < 0) e(2);
395*433d6423SLionel Sambuc   if (close(fd) != 0) e(3);
396*433d6423SLionel Sambuc   D1_before = get_link("D1");
397*433d6423SLionel Sambuc   x_link = get_link("D1/x");
398*433d6423SLionel Sambuc   if (rename("D1/x", "D1/y") != 0) e(4);
399*433d6423SLionel Sambuc   y_link = get_link("D1/y");
400*433d6423SLionel Sambuc   D1_after = get_link("D1");
401*433d6423SLionel Sambuc   if (D1_before != 2) e(5);
402*433d6423SLionel Sambuc   if (D1_after != 2) e(6);
403*433d6423SLionel Sambuc   if (x_link != 1) e(7);
404*433d6423SLionel Sambuc   if (y_link != 1) e(8);
405*433d6423SLionel Sambuc   if (access("D1/y", 7) != 0) e(9);
406*433d6423SLionel Sambuc   if (unlink("D1/y") != 0) e(10);
407*433d6423SLionel Sambuc   if (rmdir("D1") != 0) e(11);
408*433d6423SLionel Sambuc }
409*433d6423SLionel Sambuc 
test21g()410*433d6423SLionel Sambuc void test21g()
411*433d6423SLionel Sambuc {
412*433d6423SLionel Sambuc   int fd, D1_before, D1_after, D2_before, D2_after, x_link, y_link;
413*433d6423SLionel Sambuc 
414*433d6423SLionel Sambuc   /* Test case 2: move a file to a new directory. */
415*433d6423SLionel Sambuc   subtest = 7;
416*433d6423SLionel Sambuc   if (mkdir("D1", 0777) != 0) e(1);
417*433d6423SLionel Sambuc   if (mkdir("D2", 0777) != 0) e(2);
418*433d6423SLionel Sambuc   if ( (fd = creat("D1/x", 0777)) < 0) e(3);
419*433d6423SLionel Sambuc   if (close(fd) != 0) e(4);
420*433d6423SLionel Sambuc   D1_before = get_link("D1");
421*433d6423SLionel Sambuc   D2_before = get_link("D2");
422*433d6423SLionel Sambuc   x_link = get_link("D1/x");
423*433d6423SLionel Sambuc   if (rename("D1/x", "D2/y") != 0) e(5);
424*433d6423SLionel Sambuc   y_link = get_link("D2/y");
425*433d6423SLionel Sambuc   D1_after = get_link("D1");
426*433d6423SLionel Sambuc   D2_after = get_link("D2");
427*433d6423SLionel Sambuc   if (D1_before != 2) e(6);
428*433d6423SLionel Sambuc   if (D2_before != 2) e(7);
429*433d6423SLionel Sambuc   if (D1_after != 2) e(8);
430*433d6423SLionel Sambuc   if (D2_after != 2) e(9);
431*433d6423SLionel Sambuc   if (x_link != 1) e(10);
432*433d6423SLionel Sambuc   if (y_link != 1) e(11);
433*433d6423SLionel Sambuc   if (access("D2/y", 7) != 0) e(12);
434*433d6423SLionel Sambuc   if (unlink("D2/y") != 0) e(13);
435*433d6423SLionel Sambuc   if (rmdir("D1") != 0) e(14);
436*433d6423SLionel Sambuc   if (rmdir("D2") != 0) e(15);
437*433d6423SLionel Sambuc }
438*433d6423SLionel Sambuc 
test21h()439*433d6423SLionel Sambuc void test21h()
440*433d6423SLionel Sambuc {
441*433d6423SLionel Sambuc   int D1_before, D1_after, x_link, y_link;
442*433d6423SLionel Sambuc 
443*433d6423SLionel Sambuc   /* Test case 3: renaming a directory within the same directory. */
444*433d6423SLionel Sambuc   subtest = 8;
445*433d6423SLionel Sambuc   if (mkdir("D1", 0777) != 0) e(1);
446*433d6423SLionel Sambuc   if (mkdir("D1/X", 0777) != 0) e(2);
447*433d6423SLionel Sambuc   D1_before = get_link("D1");
448*433d6423SLionel Sambuc   x_link = get_link("D1/X");
449*433d6423SLionel Sambuc   if (rename("D1/X", "D1/Y") != 0) e(3);
450*433d6423SLionel Sambuc   y_link = get_link("D1/Y");
451*433d6423SLionel Sambuc   D1_after = get_link("D1");
452*433d6423SLionel Sambuc   if (D1_before != 3) e(4);
453*433d6423SLionel Sambuc   if (D1_after != 3) e(5);
454*433d6423SLionel Sambuc   if (x_link != 2) e(6);
455*433d6423SLionel Sambuc   if (y_link != 2) e(7);
456*433d6423SLionel Sambuc   if (access("D1/Y", 7) != 0) e(8);
457*433d6423SLionel Sambuc   if (rmdir("D1/Y") != 0) e(9);
458*433d6423SLionel Sambuc   if (get_link("D1") != 2) e(10);
459*433d6423SLionel Sambuc   if (rmdir("D1") != 0) e(11);
460*433d6423SLionel Sambuc }
461*433d6423SLionel Sambuc 
test21i()462*433d6423SLionel Sambuc void test21i()
463*433d6423SLionel Sambuc {
464*433d6423SLionel Sambuc   int D1_before, D1_after, D2_before, D2_after, x_link, y_link;
465*433d6423SLionel Sambuc 
466*433d6423SLionel Sambuc   /* Test case 4: move a directory to a new directory. */
467*433d6423SLionel Sambuc   subtest = 9;
468*433d6423SLionel Sambuc   if (mkdir("D1", 0777) != 0) e(1);
469*433d6423SLionel Sambuc   if (mkdir("D2", 0777) != 0) e(2);
470*433d6423SLionel Sambuc   if (mkdir("D1/X", 0777) != 0) e(3);
471*433d6423SLionel Sambuc   D1_before = get_link("D1");
472*433d6423SLionel Sambuc   D2_before = get_link("D2");
473*433d6423SLionel Sambuc   x_link = get_link("D1/X");
474*433d6423SLionel Sambuc   if (rename("D1/X", "D2/Y") != 0) e(4);
475*433d6423SLionel Sambuc   y_link = get_link("D2/Y");
476*433d6423SLionel Sambuc   D1_after = get_link("D1");
477*433d6423SLionel Sambuc   D2_after = get_link("D2");
478*433d6423SLionel Sambuc   if (D1_before != 3) e(5);
479*433d6423SLionel Sambuc   if (D2_before != 2) e(6);
480*433d6423SLionel Sambuc   if (D1_after != 2) e(7);
481*433d6423SLionel Sambuc   if (D2_after != 3) e(8);
482*433d6423SLionel Sambuc   if (x_link != 2) e(9);
483*433d6423SLionel Sambuc   if (y_link != 2) e(10);
484*433d6423SLionel Sambuc   if (access("D2/Y", 7) != 0) e(11);
485*433d6423SLionel Sambuc   if (rename("D2/Y", "D1/Z") != 0) e(12);
486*433d6423SLionel Sambuc   if (get_link("D1") != 3) e(13);
487*433d6423SLionel Sambuc   if (get_link("D2") != 2) e(14);
488*433d6423SLionel Sambuc   if (rmdir("D1/Z") != 0) e(15);
489*433d6423SLionel Sambuc   if (get_link("D1") != 2) e(16);
490*433d6423SLionel Sambuc   if (rmdir("D1") != 0) e(17);
491*433d6423SLionel Sambuc   if (rmdir("D2") != 0) e(18);
492*433d6423SLionel Sambuc }
493*433d6423SLionel Sambuc 
test21k()494*433d6423SLionel Sambuc void test21k()
495*433d6423SLionel Sambuc {
496*433d6423SLionel Sambuc /* Now test the same 4 cases, except when the target exists. */
497*433d6423SLionel Sambuc 
498*433d6423SLionel Sambuc   int fd, D1_before, D1_after, x_link, y_link;
499*433d6423SLionel Sambuc 
500*433d6423SLionel Sambuc   /* Test case 5: renaming a file within the same directory. */
501*433d6423SLionel Sambuc   subtest = 10;
502*433d6423SLionel Sambuc   if (mkdir("D1", 0777) != 0) e(1);
503*433d6423SLionel Sambuc   if ( (fd = creat("D1/x", 0777)) < 0) e(2);
504*433d6423SLionel Sambuc   if (close(fd) != 0) e(3);
505*433d6423SLionel Sambuc   if ( (fd = creat("D1/y", 0777)) < 0) e(3);
506*433d6423SLionel Sambuc   if (close(fd) != 0) e(4);
507*433d6423SLionel Sambuc   D1_before = get_link("D1");
508*433d6423SLionel Sambuc   x_link = get_link("D1/x");
509*433d6423SLionel Sambuc   if (rename("D1/x", "D1/y") != 0) e(5);
510*433d6423SLionel Sambuc   y_link = get_link("D1/y");
511*433d6423SLionel Sambuc   D1_after = get_link("D1");
512*433d6423SLionel Sambuc   if (D1_before != 2) e(6);
513*433d6423SLionel Sambuc   if (D1_after != 2) e(7);
514*433d6423SLionel Sambuc   if (x_link != 1) e(8);
515*433d6423SLionel Sambuc   if (y_link != 1) e(9);
516*433d6423SLionel Sambuc   if (access("D1/y", 7) != 0) e(10);
517*433d6423SLionel Sambuc   if (unlink("D1/y") != 0) e(11);
518*433d6423SLionel Sambuc   if (rmdir("D1") != 0) e(12);
519*433d6423SLionel Sambuc }
520*433d6423SLionel Sambuc 
test21l()521*433d6423SLionel Sambuc void test21l()
522*433d6423SLionel Sambuc {
523*433d6423SLionel Sambuc   int fd, D1_before, D1_after, D2_before, D2_after, x_link, y_link;
524*433d6423SLionel Sambuc 
525*433d6423SLionel Sambuc   /* Test case 6: move a file to a new directory. */
526*433d6423SLionel Sambuc   subtest = 11;
527*433d6423SLionel Sambuc   if (mkdir("D1", 0777) != 0) e(1);
528*433d6423SLionel Sambuc   if (mkdir("D2", 0777) != 0) e(2);
529*433d6423SLionel Sambuc   if ( (fd = creat("D1/x", 0777)) < 0) e(3);
530*433d6423SLionel Sambuc   if (close(fd) != 0) e(4);
531*433d6423SLionel Sambuc   if ( (fd = creat("D2/y", 0777)) < 0) e(5);
532*433d6423SLionel Sambuc   if (close(fd) != 0) e(6);
533*433d6423SLionel Sambuc   D1_before = get_link("D1");
534*433d6423SLionel Sambuc   D2_before = get_link("D2");
535*433d6423SLionel Sambuc   x_link = get_link("D1/x");
536*433d6423SLionel Sambuc   if (rename("D1/x", "D2/y") != 0) e(7);
537*433d6423SLionel Sambuc   y_link = get_link("D2/y");
538*433d6423SLionel Sambuc   D1_after = get_link("D1");
539*433d6423SLionel Sambuc   D2_after = get_link("D2");
540*433d6423SLionel Sambuc   if (D1_before != 2) e(8);
541*433d6423SLionel Sambuc   if (D2_before != 2) e(9);
542*433d6423SLionel Sambuc   if (D1_after != 2) e(10);
543*433d6423SLionel Sambuc   if (D2_after != 2) e(11);
544*433d6423SLionel Sambuc   if (x_link != 1) e(12);
545*433d6423SLionel Sambuc   if (y_link != 1) e(13);
546*433d6423SLionel Sambuc   if (access("D2/y", 7) != 0) e(14);
547*433d6423SLionel Sambuc   if (unlink("D2/y") != 0) e(15);
548*433d6423SLionel Sambuc   if (rmdir("D1") != 0) e(16);
549*433d6423SLionel Sambuc   if (rmdir("D2") != 0) e(17);
550*433d6423SLionel Sambuc }
551*433d6423SLionel Sambuc 
test21m()552*433d6423SLionel Sambuc void test21m()
553*433d6423SLionel Sambuc {
554*433d6423SLionel Sambuc   int D1_before, D1_after, x_link, y_link;
555*433d6423SLionel Sambuc 
556*433d6423SLionel Sambuc   /* Test case 7: renaming a directory within the same directory. */
557*433d6423SLionel Sambuc   subtest = 12;
558*433d6423SLionel Sambuc   if (mkdir("D1", 0777) != 0) e(1);
559*433d6423SLionel Sambuc   if (mkdir("D1/X", 0777) != 0) e(2);
560*433d6423SLionel Sambuc   if (mkdir("D1/Y", 0777) != 0) e(3);
561*433d6423SLionel Sambuc   D1_before = get_link("D1");
562*433d6423SLionel Sambuc   x_link = get_link("D1/X");
563*433d6423SLionel Sambuc   if (rename("D1/X", "D1/Y") != 0) e(4);
564*433d6423SLionel Sambuc   y_link = get_link("D1/Y");
565*433d6423SLionel Sambuc   D1_after = get_link("D1");
566*433d6423SLionel Sambuc   if (D1_before != 4) e(5);
567*433d6423SLionel Sambuc   if (D1_after != 3) e(6);
568*433d6423SLionel Sambuc   if (x_link != 2) e(7);
569*433d6423SLionel Sambuc   if (y_link != 2) e(8);
570*433d6423SLionel Sambuc   if (access("D1/Y", 7) != 0) e(9);
571*433d6423SLionel Sambuc   if (rmdir("D1/Y") != 0) e(10);
572*433d6423SLionel Sambuc   if (get_link("D1") != 2) e(11);
573*433d6423SLionel Sambuc   if (rmdir("D1") != 0) e(12);
574*433d6423SLionel Sambuc }
575*433d6423SLionel Sambuc 
test21n()576*433d6423SLionel Sambuc void test21n()
577*433d6423SLionel Sambuc {
578*433d6423SLionel Sambuc   int D1_before, D1_after, D2_before, D2_after, x_link, y_link;
579*433d6423SLionel Sambuc 
580*433d6423SLionel Sambuc   /* Test case 8: move a directory to a new directory. */
581*433d6423SLionel Sambuc   subtest = 13;
582*433d6423SLionel Sambuc   if (mkdir("D1", 0777) != 0) e(1);
583*433d6423SLionel Sambuc   if (mkdir("D2", 0777) != 0) e(2);
584*433d6423SLionel Sambuc   if (mkdir("D1/X", 0777) != 0) e(3);
585*433d6423SLionel Sambuc   if (mkdir("D2/Y", 0777) != 0) e(4);
586*433d6423SLionel Sambuc   D1_before = get_link("D1");
587*433d6423SLionel Sambuc   D2_before = get_link("D2");
588*433d6423SLionel Sambuc   x_link = get_link("D1/X");
589*433d6423SLionel Sambuc   if (rename("D1/X", "D2/Y") != 0) e(5);
590*433d6423SLionel Sambuc   y_link = get_link("D2/Y");
591*433d6423SLionel Sambuc   D1_after = get_link("D1");
592*433d6423SLionel Sambuc   D2_after = get_link("D2");
593*433d6423SLionel Sambuc   if (D1_before != 3) e(6);
594*433d6423SLionel Sambuc   if (D2_before != 3) e(7);
595*433d6423SLionel Sambuc   if (D1_after != 2) e(8);
596*433d6423SLionel Sambuc   if (D2_after != 3) e(9);
597*433d6423SLionel Sambuc   if (x_link != 2) e(10);
598*433d6423SLionel Sambuc   if (y_link != 2) e(11);
599*433d6423SLionel Sambuc   if (access("D2/Y", 7) != 0) e(12);
600*433d6423SLionel Sambuc   if (rename("D2/Y", "D1/Z") != 0) e(13);
601*433d6423SLionel Sambuc   if (get_link("D1") != 3) e(14);
602*433d6423SLionel Sambuc   if (get_link("D2") != 2) e(15);
603*433d6423SLionel Sambuc   if (rmdir("D1/Z") != 0) e(16);
604*433d6423SLionel Sambuc   if (get_link("D1") != 2) e(17);
605*433d6423SLionel Sambuc   if (rmdir("D1") != 0) e(18);
606*433d6423SLionel Sambuc   if (rmdir("D2") != 0) e(19);
607*433d6423SLionel Sambuc }
608*433d6423SLionel Sambuc 
test21o()609*433d6423SLionel Sambuc void test21o()
610*433d6423SLionel Sambuc {
611*433d6423SLionel Sambuc   /* Test trying to remove . and .. */
612*433d6423SLionel Sambuc   subtest = 14;
613*433d6423SLionel Sambuc   if (mkdir("D1", 0777) != 0) e(1);
614*433d6423SLionel Sambuc   if (chdir("D1") != 0) e(2);
615*433d6423SLionel Sambuc   if (rmdir(".") == 0) e(3);
616*433d6423SLionel Sambuc   if (rmdir("..") == 0) e(4);
617*433d6423SLionel Sambuc   if (mkdir("D2", 0777) != 0) e(5);
618*433d6423SLionel Sambuc   if (mkdir("D3", 0777) != 0) e(6);
619*433d6423SLionel Sambuc   if (mkdir("D4", 0777) != 0) e(7);
620*433d6423SLionel Sambuc   if (rmdir("D2/../D3/../D4") != 0) e(8);	/* legal way to remove D4 */
621*433d6423SLionel Sambuc   if (rmdir("D2/../D3/../D2/..") == 0) e(9);	/* removing self is illegal */
622*433d6423SLionel Sambuc   if (rmdir("D2/../D3/../D2/../..") == 0) e(10);/* removing parent is illegal*/
623*433d6423SLionel Sambuc   if (rmdir("../D1/../D1/D3") != 0) e(11);	/* legal way to remove D3 */
624*433d6423SLionel Sambuc   if (rmdir("./D2/../D2") != 0) e(12);		/* legal way to remove D2 */
625*433d6423SLionel Sambuc   if (chdir("..") != 0) e(13);
626*433d6423SLionel Sambuc   if (rmdir("D1") != 0) e(14);
627*433d6423SLionel Sambuc }
628*433d6423SLionel Sambuc 
get_link(name)629*433d6423SLionel Sambuc int get_link(name)
630*433d6423SLionel Sambuc char *name;
631*433d6423SLionel Sambuc {
632*433d6423SLionel Sambuc   struct stat statbuf;
633*433d6423SLionel Sambuc 
634*433d6423SLionel Sambuc   if (stat(name, &statbuf) != 0) {
635*433d6423SLionel Sambuc 	printf("Unable to stat %s\n", name);
636*433d6423SLionel Sambuc 	errct++;
637*433d6423SLionel Sambuc 	return(-1);
638*433d6423SLionel Sambuc   }
639*433d6423SLionel Sambuc   return(statbuf.st_nlink);
640*433d6423SLionel Sambuc }
641*433d6423SLionel Sambuc 
642