Remove INTLLIBS from librazor_la_LIBADD.
This partially reverts 611c84a3f4b4538a65d186050608c17adbf17770.
It's not clear what motivated the initial inclusion of INTLLIBS
here since the net effect is only seen in librazor.la and not
in razor.pc and librazor.la is not normally packaged. Certainly
neither the static nor the dynamic versions of librazor currently
use libintl. At best this would cause the linker to search a
static libintl for undefined symbols without finding any; at worse
it causes a static build of plover using librazor.la to fail if
no static version of libintl is installed.
2 * Copyright (C) 2012 J. Ali Harlow <ali@juiblex.co.uk>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #if ENABLE_ATOMIC && !HAVE_WINDOWS_KTM
29 #include <sys/types.h>
32 #include "razor-internal.h"
34 char *atomic_action_attic_tmpnam(struct razor_atomic *atomic)
37 sprintf(filename,"%03X",atomic->next_file_tag++);
38 return razor_concat(atomic->toplevel, "/", filename, NULL);
41 static struct atomic_action *
42 atomic_action_list_pop_head(struct atomic_action **list)
44 struct atomic_action *head;
55 struct atomic_action *
56 atomic_action_list_prepend(struct atomic_action *list,
57 struct atomic_action *action)
59 assert(action->next == NULL);
66 static struct atomic_action *
67 atomic_action_list_concat(struct atomic_action *list1,
68 struct atomic_action *list2)
70 struct atomic_action *action;
75 for(action=list1;action->next;action=action->next)
83 void atomic_action_free(struct atomic_action *action)
85 struct atomic_action *a;
88 a = atomic_action_list_pop_head(&action);
93 case ACTION_MAKE_DIRS:
94 free(a->args.u.make_dirs.root);
97 free(a->args.u.move.dest);
100 case ACTION_CREATE_SYMLINK:
101 free(a->args.u.create_symlink.target);
105 case ACTION_CREATE_DIR:
113 struct atomic_action *atomic_action_new(enum atomic_action_type type)
115 struct atomic_action *action;
117 action = zalloc(sizeof *action);
123 struct atomic_action *atomic_action_list_reverse(struct atomic_action *list)
125 struct atomic_action *prev = NULL, *next;
138 * All action_ functions take 1 action and return a list of primitive
139 * actions they took (such that the first action in the list is the
140 * last action they took). Primitive actions are always reversable.
142 * On failure, an error should be set on the atomic object (if it is
143 * not already set), the action freed and NULL returned.
145 * Whether they succeed or fail, they take ownership of the passed
146 * action and should thus either free it or return it back to their
147 * caller as appropriate.
149 * A NULL return means that nothing was done which may, or may not,
153 static struct atomic_action *
154 atomic_action_make_dirs(struct razor_atomic *atomic,
155 struct atomic_action *action)
157 char buffer[PATH_MAX], *p;
158 const char *slash, *next;
159 struct atomic_action *primitives = NULL;
160 struct atomic_action *prim;
162 if (razor_atomic_in_error_state(atomic)) {
163 atomic_action_free(action);
167 strcpy(buffer, action->args.u.make_dirs.root);
168 p = buffer + strlen(buffer);
169 slash = action->args.path;
170 for (; *slash != '\0'; slash = next) {
172 next = strpbrk(slash + 1, "/\\");
174 next = strchr(slash + 1, '/');
179 memcpy(p, slash, next - slash);
183 if (razor_valid_root_name(buffer))
186 prim = atomic_action_new(ACTION_CREATE_DIR);
187 prim->args.path = strdup(buffer);
188 prim->args.u.create_dir.mode = S_IRWXU | S_IRWXG | S_IRWXO;
189 primitives = atomic_action_list_prepend(primitives, prim);
191 primitives = atomic_action_list_reverse(primitives);
193 return atomic_action_do(atomic, primitives);
196 static struct atomic_action *
197 atomic_action_remove(struct razor_atomic *atomic, struct atomic_action *action)
205 struct atomic_action *prim;
207 if (razor_atomic_in_error_state(atomic)) {
208 atomic_action_free(action);
213 * Non-empty directories should NOT be removed
216 path = razor_utf8_to_utf16(action->args.path, -1);
218 dir = _wopendir(path);
219 if (dir && _wreaddir(dir)) {
220 atomic_action_free(action);
225 dir = opendir(action->args.path);
226 if (dir && readdir(dir)) {
227 atomic_action_free(action);
234 prim = atomic_action_new(ACTION_MOVE);
235 prim->args.path = strdup(action->args.path);
236 prim->args.u.move.dest = atomic_action_attic_tmpnam(atomic);
238 atomic_action_free(action);
242 return prim ? atomic_action_do(atomic, prim) : NULL;
245 static struct atomic_action *
246 atomic_action_create_dir(struct razor_atomic *atomic,
247 struct atomic_action *action)
251 if (razor_atomic_in_error_state(atomic)) {
252 atomic_action_free(action);
256 mode = action->args.u.create_dir.mode & (S_IRWXU | S_IRWXG | S_IRWXO);
258 if (!mkdir(action->args.path, mode))
261 if (errno != EEXIST || chmod(action->args.path, mode) < 0) {
263 atomic->error = razor_error_new_str(action->args.path,
265 atomic_action_free(action);
272 static struct atomic_action *atomic_action_rmdir(struct razor_atomic *atomic,
273 struct atomic_action *action)
275 if (razor_atomic_in_error_state(atomic)) {
276 atomic_action_free(action);
280 if (rmdir(action->args.path) < 0) {
282 atomic->error = razor_error_new_str(action->args.path,
284 atomic_action_free(action);
291 static struct atomic_action *
292 atomic_action_create_symlink(struct razor_atomic *atomic,
293 struct atomic_action *action)
297 if (razor_atomic_in_error_state(atomic)) {
298 atomic_action_free(action);
302 r = symlink(action->args.u.create_symlink.target, action->args.path);
305 atomic->error = razor_error_new_str(action->args.path,
307 atomic_action_free(action);
314 static struct atomic_action *
315 atomic_action_remove_symlink(struct razor_atomic *atomic,
316 struct atomic_action *action)
318 if (razor_atomic_in_error_state(atomic)) {
319 atomic_action_free(action);
323 if (unlink(action->args.path) < 0) {
325 atomic->error = razor_error_new_str(action->args.path,
327 atomic_action_free(action);
336 move_file(struct razor_atomic *atomic, const char *path, const char *dest)
339 wchar_t *oldbuf, *newbuf;
340 const DWORD flags = MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING;
342 newbuf = razor_utf8_to_utf16(dest, -1);
343 oldbuf = razor_utf8_to_utf16(path, -1);
346 * Passing MOVEFILE_REPLACE_EXISTING to MoveFileEx() will
347 * cover every case we care about _except_ replacing an empty
348 * directory with a file. Calling RemoveDirectory() will deal
349 * with this case while having no effect in all other cases.
351 (void)RemoveDirectoryW(newbuf);
353 if (!MoveFileExW(oldbuf, newbuf, flags)) {
355 atomic->error = razor_error_new_mswin(newbuf,
363 if (rename(path, dest)) {
365 atomic->error = razor_error_new_str(dest,
374 static struct atomic_action *
375 atomic_action_move(struct razor_atomic *atomic, struct atomic_action *action)
377 if (razor_atomic_in_error_state(atomic)) {
378 atomic_action_free(action);
382 if (move_file(atomic, action->args.path, action->args.u.move.dest)) {
383 atomic_action_free(action);
390 static struct atomic_action *
391 atomic_action_unmove(struct razor_atomic *atomic, struct atomic_action *action)
393 if (razor_atomic_in_error_state(atomic)) {
394 atomic_action_free(action);
398 if (move_file(atomic, action->args.u.move.dest, action->args.path)) {
399 atomic_action_free(action);
406 static struct atomic_action *atomic_action_apply(struct razor_atomic *atomic,
407 struct atomic_action *action)
409 switch(action->type) {
410 case ACTION_MAKE_DIRS:
411 action = atomic_action_make_dirs(atomic, action);
414 action = atomic_action_remove(atomic, action);
416 case ACTION_CREATE_DIR:
417 action = atomic_action_create_dir(atomic, action);
420 action = atomic_action_move(atomic, action);
423 case ACTION_CREATE_SYMLINK:
424 action = atomic_action_create_symlink(atomic, action);
431 static struct atomic_action *atomic_action_reverse(struct razor_atomic *atomic,
432 struct atomic_action *action)
434 switch(action->type) {
435 case ACTION_MAKE_DIRS:
437 /* Complex actions: should never happen */
439 case ACTION_CREATE_DIR:
440 action = atomic_action_rmdir(atomic, action);
443 action = atomic_action_unmove(atomic, action);
446 case ACTION_CREATE_SYMLINK:
447 action = atomic_action_remove_symlink(atomic, action);
455 * Note that undo has no error checking.
458 void atomic_action_undo(struct razor_atomic *atomic,
459 struct atomic_action *actions)
461 struct atomic_action *a;
466 a = atomic_action_list_pop_head(&actions);
467 a = atomic_action_reverse(atomic, a);
468 atomic_action_free(a);
474 struct atomic_action *atomic_action_do(struct razor_atomic *atomic,
475 struct atomic_action *actions)
477 struct atomic_action *done = NULL, *a;
479 if (razor_atomic_in_error_state(atomic)) {
480 atomic_action_free(actions);
485 a = atomic_action_list_pop_head(&actions);
486 a = atomic_action_apply(atomic, a);
488 done = atomic_action_list_concat(a, done);
489 if (razor_atomic_in_error_state(atomic)) {
490 atomic_action_undo(atomic, done);
492 atomic_action_free(actions);
499 #endif /* ENABLE_ATOMIC && !HAVE_WINDOWS_KTM */