librazor/atomic-none.c
author J. Ali Harlow <ali@juiblex.co.uk>
Sat Aug 23 11:13:48 2014 +0100 (2014-08-23)
changeset 440 48204dea0b9f
parent 416 d0aa9e0a6d04
child 441 cf499fd51df7
permissions -rw-r--r--
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.
     1 /*
     2  * Copyright (C) 2011-2012  J. Ali Harlow <ali@juiblex.co.uk>
     3  *
     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.
     8  *
     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.
    13  *
    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.
    17  */
    18 
    19 #include "config.h"
    20 
    21 #if !ENABLE_ATOMIC
    22 
    23 #include <stdlib.h>
    24 #ifdef MSWIN_API
    25 #include <windows.h>
    26 #endif
    27 #include <stdio.h>
    28 #include <limits.h>
    29 #include <errno.h>
    30 #include <unistd.h>
    31 #include <fcntl.h>
    32 #include <sys/stat.h>
    33 #include <string.h>
    34 #include <assert.h>
    35 
    36 #include "razor.h"
    37 #include "razor-internal.h"
    38 
    39 #ifndef O_BINARY
    40 #define O_BINARY	0
    41 #endif
    42 
    43 RAZOR_EXPORT struct razor_atomic *
    44 razor_atomic_open(const char *description)
    45 {
    46 	struct razor_atomic *atomic;
    47 
    48 	atomic = zalloc(sizeof *atomic);
    49 
    50 	return atomic;
    51 }
    52 
    53 RAZOR_EXPORT int
    54 razor_atomic_commit(struct razor_atomic *atomic)
    55 {
    56 	return razor_atomic_in_error_state(atomic);
    57 }
    58 
    59 RAZOR_EXPORT void
    60 razor_atomic_destroy(struct razor_atomic *atomic)
    61 {
    62 	if (atomic->error)
    63 		razor_error_free(atomic->error);
    64 
    65 	free(atomic);
    66 }
    67 
    68 RAZOR_EXPORT int
    69 razor_atomic_make_dirs(struct razor_atomic *atomic, const char *root,
    70 		       const char *path)
    71 {
    72 	char buffer[PATH_MAX], *p;
    73 	const char *slash, *next;
    74 	struct stat buf;
    75 
    76 	if (razor_atomic_in_error_state(atomic))
    77 		return -1;
    78 
    79 	strcpy(buffer, root);
    80 	p = buffer + strlen(buffer);
    81 	slash = path;
    82 	for (slash = path; *slash != '\0'; slash = next) {
    83 #ifdef MSWIN_API
    84 		next = strpbrk(slash + 1, "/\\");
    85 #else
    86 		next = strchr(slash + 1, '/');
    87 #endif
    88 		if (next == NULL)
    89 			break;
    90 
    91 		memcpy(p, slash, next - slash);
    92 		p += next - slash;
    93 		*p = '\0';
    94 
    95 		if (razor_valid_root_name(buffer))
    96 			continue;
    97 
    98 		if (stat(buffer, &buf) == 0) {
    99 			if (!S_ISDIR(buf.st_mode)) {
   100 				atomic->error = razor_error_new_str(buffer,
   101 								    "Not a directory");
   102 				return -1;
   103 			}
   104 		} else if (mkdir(buffer, 0777) < 0) {
   105 			atomic->error = razor_error_new_str(buffer,
   106 							    strerror(errno));
   107 			return -1;
   108 		}
   109 	}
   110 
   111 	return 0;
   112 }
   113 
   114 RAZOR_EXPORT int
   115 razor_atomic_remove(struct razor_atomic *atomic, const char *path)
   116 {
   117 #ifdef MSWIN_API
   118 	wchar_t *buf;
   119 	DWORD err;
   120 #endif
   121 
   122 	if (razor_atomic_in_error_state(atomic))
   123 		return -1;
   124 
   125 #ifdef MSWIN_API
   126 	buf = razor_utf8_to_utf16(path, -1);
   127 
   128 	if (!DeleteFileW(buf)) {
   129 		err = GetLastError();
   130 		if (err != ERROR_FILE_NOT_FOUND &&
   131 		    err != ERROR_PATH_NOT_FOUND &&
   132 		    !(SetFileAttributesW(buf, FILE_ATTRIBUTE_NORMAL) &&
   133 		      DeleteFileW(buf)) &&
   134 		    !RemoveDirectoryW(buf) &&
   135 		    GetLastError() != ERROR_DIR_NOT_EMPTY)
   136 			atomic->error = razor_error_new_mswin(buf, err);
   137 	}
   138 
   139 	free(buf);
   140 #else
   141 	if (remove(path))
   142 		atomic->error = razor_error_new_str(path, strerror(errno));
   143 #endif
   144 
   145 	return razor_atomic_in_error_state(atomic);
   146 }
   147 
   148 RAZOR_EXPORT int
   149 razor_atomic_rename_file(struct razor_atomic *atomic, const char *oldpath,
   150 			 const char *newpath)
   151 {
   152 #ifdef MSWIN_API
   153 	wchar_t *oldbuf, *newbuf;
   154 	const DWORD flags = MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING;
   155 #endif
   156 
   157 	if (razor_atomic_in_error_state(atomic))
   158 		return -1;
   159 
   160 #ifdef MSWIN_API
   161 	newbuf = razor_utf8_to_utf16(newpath, -1);
   162 	oldbuf = razor_utf8_to_utf16(oldpath, -1);
   163 
   164 	/*
   165 	 * Passing MOVEFILE_REPLACE_EXISTING to MoveFileEx() will
   166 	 * cover every case we care about _except_ replacing an empty
   167 	 * directory with a file. Calling RemoveDirectory() will deal
   168 	 * with this case while having no effect in all other cases.
   169 	 */
   170 	(void)RemoveDirectoryW(newbuf);
   171 
   172 	if (!MoveFileExW(oldbuf, newbuf, flags))
   173 		atomic->error = razor_error_new_mswin(newbuf, GetLastError());
   174 
   175 	free(newbuf);
   176 	free(oldbuf);
   177 #else
   178 	if (rename(oldpath, newpath))
   179 		atomic->error = razor_error_new_str(newpath, strerror(errno));
   180 #endif
   181 
   182 	return razor_atomic_in_error_state(atomic);
   183 }
   184 
   185 RAZOR_EXPORT int
   186 razor_atomic_create_dir(struct razor_atomic *atomic, const char *dirname,
   187 			mode_t mode)
   188 {
   189 	if (razor_atomic_in_error_state(atomic))
   190 		return -1;
   191 
   192 	if (!mkdir(dirname, mode & (S_IRWXU | S_IRWXG | S_IRWXO)))
   193 		return 0;
   194 
   195 	if (errno != EEXIST) {
   196 		atomic->error = razor_error_new_str(dirname, strerror(errno));
   197 		return -1;
   198 	}
   199 
   200 	if (chmod(dirname, mode & (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) {
   201 		atomic->error = razor_error_new_str(dirname, strerror(errno));
   202 		return -1;
   203 	}
   204 
   205 	return 0;
   206 }
   207 
   208 RAZOR_EXPORT int
   209 razor_atomic_create_symlink(struct razor_atomic *atomic, const char *target,
   210 			    const char *path)
   211 {
   212 	if (razor_atomic_in_error_state(atomic))
   213 		return -1;
   214 
   215 #if HAVE_SYMLINK
   216 	if (symlink(target, path) < 0) {
   217 		atomic->error = razor_error_new_str(path, strerror(errno));
   218 		return -1;
   219 	}
   220 
   221 	return 0;
   222 #else
   223 	atomic->error = razor_error_new_str(NULL,
   224 					    "Symbolic links not supported "
   225 					    "on this platform");
   226 
   227 	return -1;
   228 #endif
   229 }
   230 
   231 RAZOR_EXPORT int
   232 razor_atomic_create_file(struct razor_atomic *atomic, const char *filename,
   233 			 mode_t mode)
   234 {
   235 	int fd;
   236 
   237 	if (razor_atomic_in_error_state(atomic))
   238 		return -1;
   239 
   240 	fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
   241 		  mode & (S_IRWXU | S_IRWXG | S_IRWXO));
   242 
   243 	if (fd == -1)
   244 		atomic->error = razor_error_new_str(filename, strerror(errno));
   245 
   246 	return fd;
   247 }
   248 
   249 #endif	/* !ENABLE_ATOMIC */