Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / tests / kill-softer.c
1 /*
2 * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <fcntl.h>
44 #include <unistd.h>
45 #include <dirent.h>
46
47 #include <err.h>
48
49 static FILE *verbose;
50
51 struct entry {
52 char *name;
53 int status;
54 };
55
56 static void
57 kill_one(struct entry *ents, int ind, int curents);
58
59 static void
60 do_dir(const char *dirname);
61
62 static void
63 kill_dir(const char *dirname);
64
65 static void
66 kill_one(struct entry *ents, int ind, int curents)
67 {
68 int ret;
69 int i;
70
71 ret = unlink(ents[ind].name);
72 if (ret < 0) {
73 if (errno == EISDIR || errno == EPERM)
74 do_dir(ents[ind].name);
75 else
76 err(1, "unlink %s", ents[ind].name);
77 }
78 ents[ind].status = 0;
79 for (i = 0; i <= ind; ++i) {
80 struct stat sb;
81
82 ret = lstat(ents[i].name, &sb);
83 if (ret == 0 || errno != ENOENT)
84 err(1, "%s still exists?", ents[i].name);
85 }
86
87 for (i = ind + 1; i < curents; ++i) {
88 struct stat sb;
89
90 ret = lstat(ents[i].name, &sb);
91 if (ret < 0)
92 err(1, "stat %s", ents[i].name);
93 }
94 }
95
96 static void
97 do_dir(const char *dirname)
98 {
99 int ret;
100
101 ret = chdir(dirname);
102 if (ret < 0)
103 err(1, "chdir %s", dirname);
104 kill_dir(dirname);
105 ret = chdir("..");
106 if (ret < 0)
107 err(1, "chdir ..");
108 ret = rmdir(dirname);
109 if (ret < 0)
110 err(1, "rmdir %s", dirname);
111 }
112
113 static void
114 kill_dir(const char *dirname)
115 {
116 struct entry *ents;
117 int maxents;
118 int curents = 0;
119 DIR *dir;
120 struct dirent *dp;
121 int i;
122
123 fprintf(verbose, "reading %s\n", dirname);
124
125 dir = opendir(".");
126 if (dir == NULL)
127 err(1, "opendir %s", dirname);
128 maxents = 10;
129 ents = malloc(sizeof(*ents) * maxents);
130 if (ents == NULL)
131 err(1, "malloc");
132 while ((dp = readdir(dir)) != NULL) {
133 if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
134 continue;
135
136 if (curents >= maxents) {
137 maxents *= 2;
138 ents = realloc(ents, sizeof(*ents) * maxents);
139 if (ents == NULL)
140 err(1, "realloc");
141 }
142 ents[curents].name = strdup(dp->d_name);
143 ents[curents].status = 1;
144 ++curents;
145 fprintf(verbose, " adding %s\n", dp->d_name);
146 }
147 closedir(dir);
148 dir = opendir(".");
149 if (dir == NULL)
150 err(1, "opendir %s", dirname);
151 i = 0;
152 while ((dp = readdir(dir)) != NULL) {
153 if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
154 continue;
155
156 if (strcmp(ents[i].name, dp->d_name) != 0) {
157 errx(1, "%s != %s", ents[i].name, dp->d_name);
158 }
159 fprintf(verbose, " deleting %s\n", ents[i].name);
160 kill_one(ents, i, curents);
161 ++i;
162 }
163 if (i != curents)
164 errx(1, "missing %d entries in %s", curents - i, dirname);
165 closedir(dir);
166 free(ents);
167 fprintf(verbose, "end of %s\n", dirname);
168 }
169
170 int
171 main(int argc, char **argv)
172 {
173
174 verbose = fdopen(4, "w");
175 if (verbose == NULL) {
176 verbose = fopen("/dev/null", "w");
177 if (verbose == NULL)
178 err(1, "fopen /dev/null");
179 }
180
181 if (argc != 2)
182 errx(1, "usage: %s directory", argv[0]);
183 do_dir(argv[1]);
184 return 0;
185 }