This source file includes following definitions.
- croak
- xmalloc
- main_1
- main_2
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <config.h>
21
22 #include <stdio.h>
23 #include <fcntl.h>
24 #include <errno.h>
25 #include <byteswap.h>
26 #include <stdlib.h>
27 #include <dirent.h>
28 #include <string.h>
29 #include <unistd.h>
30
31 #include <sys/stat.h>
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 struct directory_tree
58 {
59
60 size_t offset;
61
62
63 char *name;
64
65
66 struct directory_tree *children, *next;
67 };
68
69
70
71
72 static _Noreturn void
73 croak (const char *what)
74 {
75 perror (what);
76 exit (EXIT_FAILURE);
77 }
78
79
80
81 static void *
82 xmalloc (size_t size)
83 {
84 void *ptr;
85
86 ptr = malloc (size);
87
88 if (!ptr)
89 croak ("malloc");
90
91 return ptr;
92 }
93
94
95
96
97
98
99
100 static void
101 main_1 (DIR *dir, struct directory_tree *parent)
102 {
103 struct dirent *dirent;
104 int dir_fd, fd;
105 struct stat statb;
106 struct directory_tree *this, **last;
107 size_t length;
108 DIR *otherdir;
109
110 dir_fd = dirfd (dir);
111 last = &parent->children;
112
113 while ((dirent = readdir (dir)))
114 {
115
116
117 if (fstatat (dir_fd, dirent->d_name, &statb,
118 AT_SYMLINK_NOFOLLOW) == -1)
119 croak ("fstatat");
120
121
122
123 if (!strcmp (dirent->d_name, ".")
124 || !strcmp (dirent->d_name, ".."))
125 continue;
126
127 length = strlen (dirent->d_name);
128
129 if (statb.st_mode & S_IFDIR)
130 {
131
132
133
134 this = xmalloc (sizeof *this);
135 this->children = NULL;
136 this->next = NULL;
137 *last = this;
138 last = &this->next;
139 this->name = xmalloc (length + 2);
140 strcpy (this->name, dirent->d_name);
141
142
143
144
145 this->offset = parent->offset + length + 6;
146
147
148 this->name[length] = '/';
149 this->name[length + 1] = '\0';
150
151
152
153 fd = openat (dir_fd, dirent->d_name, O_DIRECTORY,
154 O_RDONLY);
155 if (fd < 0)
156 croak ("openat");
157 otherdir = fdopendir (fd);
158 if (!otherdir)
159 croak ("fdopendir");
160
161 main_1 (otherdir, this);
162
163
164 closedir (otherdir);
165
166
167 parent->offset = this->offset;
168 }
169 else if (statb.st_mode & S_IFREG)
170 {
171
172 this = xmalloc (sizeof *this);
173 this->children = NULL;
174 this->next = NULL;
175 *last = this;
176 last = &this->next;
177 this->name = xmalloc (length + 1);
178 strcpy (this->name, dirent->d_name);
179
180
181
182 this->offset = parent->offset + length + 5;
183 parent->offset = this->offset;
184 }
185 }
186 }
187
188
189
190
191
192 static void
193 main_2 (int fd, struct directory_tree *tree, size_t *offset)
194 {
195 ssize_t size;
196 struct directory_tree *child;
197 unsigned int output;
198
199
200 size = strlen (tree->name) + 1;
201 if (write (fd, tree->name, size) < size)
202 croak ("write");
203
204
205 #ifdef WORDS_BIGENDIAN
206 output = bswap_32 (tree->offset);
207 #else
208 output = tree->offset;
209 #endif
210 if (write (fd, &output, 4) < 1)
211 croak ("write");
212 size += 4;
213
214
215 *offset += size;
216
217
218 for (child = tree->children; child; child = child->next)
219 main_2 (fd, child, offset);
220
221
222 if (tree->offset != *offset)
223 {
224 fprintf (stderr,
225 "asset-directory-tool: invalid offset: expected %tu, "
226 "got %tu.\n"
227 "Please report this bug to bug-gnu-emacs@gnu.org, along\n"
228 "with an archive containing the contents of the java/inst"
229 "all_temp directory.\n",
230 tree->offset, *offset);
231 abort ();
232 }
233 }
234
235 int
236 main (int argc, char **argv)
237 {
238 int fd;
239 DIR *indir;
240 struct directory_tree tree;
241 size_t offset;
242
243 if (argc != 3)
244 {
245 fprintf (stderr, "usage: %s directory output-file\n",
246 argv[0]);
247 return EXIT_FAILURE;
248 }
249
250 fd = open (argv[2], O_CREAT | O_TRUNC | O_RDWR,
251 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
252
253 if (fd < 0)
254 {
255 perror ("open");
256 return EXIT_FAILURE;
257 }
258
259 indir = opendir (argv[1]);
260
261 if (!indir)
262 {
263 perror ("opendir");
264 return EXIT_FAILURE;
265 }
266
267
268
269 if (write (fd, "EMACS", 5) < 5)
270 {
271 perror ("write");
272 return EXIT_FAILURE;
273 }
274
275
276
277 tree.offset = 5;
278 tree.children = NULL;
279
280 main_1 (indir, &tree);
281 closedir (indir);
282
283
284 offset = 5;
285 for (; tree.children; tree.children = tree.children->next)
286 main_2 (fd, tree.children, &offset);
287
288 return 0;
289 }