5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2008 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 #include "silcruntime.h"
22 /* Opens a file indicated by the filename `filename' with flags indicated
25 int silc_file_open(const char *filename, int flags)
27 return silc_file_open_mode(filename, flags, 0600);
30 /* Opens a file indicated by the filename `filename' with flags indicated
31 by the `flags', and with the specified `mode'. */
33 int silc_file_open_mode(const char *filename, int flags, int mode)
35 int fd = open(filename, flags, mode);
37 silc_set_errno_posix(errno);
41 /* Reads data from file descriptor `fd' to `buf'. */
43 int silc_file_read(int fd, unsigned char *buf, SilcUInt32 buf_len)
45 int ret = read(fd, (void *)buf, buf_len);
47 silc_set_errno_posix(errno);
51 /* Writes `buffer' of length of `len' to file descriptor `fd'. */
53 int silc_file_write(int fd, const char *buffer, SilcUInt32 len)
55 int ret = write(fd, (const void *)buffer, len);
57 silc_set_errno_posix(errno);
61 /* Closes file descriptor */
63 int silc_file_close(int fd)
67 silc_set_errno_posix(errno);
71 /* Writes a buffer to the file. */
73 int silc_file_writefile(const char *filename, const char *buffer,
77 int flags = O_CREAT | O_WRONLY | O_TRUNC;
83 if ((fd = open(filename, flags, 0644)) == -1) {
84 SILC_LOG_ERROR(("Cannot open file %s for writing: %s", filename,
85 silc_errno_string(silc_errno)));
89 if (silc_file_write(fd, buffer, len) == -1) {
90 SILC_LOG_ERROR(("Cannot write to file %s: %s", filename,
91 silc_errno_string(silc_errno)));
98 #endif /* SILC_UNIX */
100 return silc_file_close(fd);
103 /* Writes a buffer to the file. If the file is created specific mode is
106 int silc_file_writefile_mode(const char *filename, const char *buffer,
107 SilcUInt32 len, int mode)
110 int flags = O_CREAT | O_WRONLY | O_TRUNC;
112 #if defined(O_BINARY)
114 #endif /* O_BINARY */
116 if ((fd = open(filename, flags, mode)) == -1) {
117 SILC_LOG_ERROR(("Cannot open file %s for writing: %s", filename,
118 silc_errno_string(silc_errno)));
122 if ((silc_file_write(fd, buffer, len)) == -1) {
123 SILC_LOG_ERROR(("Cannot write to file %s: %s", filename,
124 silc_errno_string(silc_errno)));
131 #endif /* SILC_UNIX */
133 return silc_file_close(fd);
136 /* Reads a file to a buffer. The allocated buffer is returned. Length of
137 the file read is returned to the return_len argument. */
139 char *silc_file_readfile(const char *filename, SilcUInt32 *return_len,
143 unsigned char *buffer;
146 fd = silc_file_open(filename, O_RDONLY);
148 if (silc_errno == SILC_ERR_NO_SUCH_FILE)
150 SILC_LOG_ERROR(("Cannot open file %s: %s", filename,
151 silc_errno_string(silc_errno)));
155 filelen = lseek(fd, (off_t)0L, SEEK_END);
157 silc_set_errno_posix(errno);
161 if (lseek(fd, (off_t)0L, SEEK_SET) < 0) {
162 silc_set_errno_posix(errno);
167 buffer = silc_calloc(filelen + 1, sizeof(*buffer));
169 silc_set_errno_posix(errno);
174 if ((silc_file_read(fd, buffer, filelen)) == -1) {
175 memset(buffer, 0, sizeof(buffer));
177 SILC_LOG_ERROR(("Cannot read from file %s: %s", filename,
178 silc_errno_string(silc_errno)));
183 buffer[filelen] = EOF;
186 *return_len = filelen;
188 return (char *)buffer;
191 /* Returns the size of `filename'. */
193 SilcUInt64 silc_file_size(const char *filename)
195 SilcFileStatStruct status;
197 if (!silc_file_stat(filename, FALSE, &status))
203 /* Return file size */
205 SilcUInt64 silc_file_fsize(int fd)
207 SilcFileStatStruct status;
209 if (!silc_file_fstat(fd, &status))
215 /* Fill file status context */
217 static void silc_file_fill_stat(struct stat *status,
218 SilcFileStat return_stat)
220 memset(return_stat, 0, sizeof(*return_stat));
222 silc_time_value(status->st_atime * 1000, &return_stat->last_access);
223 silc_time_value(status->st_mtime * 1000, &return_stat->last_mod);
224 silc_time_value(status->st_ctime * 1000, &return_stat->last_change);
226 return_stat->rdev = status->st_rdev;
227 return_stat->dev = status->st_dev;
228 return_stat->nlink = status->st_nlink;
229 return_stat->gid = status->st_gid;
230 return_stat->uid = status->st_uid;
231 return_stat->size = status->st_size;
233 #if defined(S_IFSOCK)
234 if (status->st_mode & S_IFSOCK)
235 return_stat->mode |= SILC_FILE_IFSOCK;
236 #endif /* S_IFSOCK */
238 if (status->st_mode & S_IFLNK)
239 return_stat->mode |= SILC_FILE_IFLNK;
242 if (status->st_mode & S_IFREG)
243 return_stat->mode |= SILC_FILE_IFREG;
246 if (status->st_mode & S_IFBLK)
247 return_stat->mode |= SILC_FILE_IFBLK;
250 if (status->st_mode & S_IFDIR)
251 return_stat->mode |= SILC_FILE_IFDIR;
254 if (status->st_mode & S_IFCHR)
255 return_stat->mode |= SILC_FILE_IFCHR;
258 if (status->st_mode & S_IFIFO)
259 return_stat->mode |= SILC_FILE_IFIFO;
262 if (status->st_mode & S_IRUSR)
263 return_stat->mode |= SILC_FILE_IRUSR;
266 if (status->st_mode & S_IWUSR)
267 return_stat->mode |= SILC_FILE_IWUSR;
270 if (status->st_mode & S_IXUSR)
271 return_stat->mode |= SILC_FILE_IXUSR;
274 if (status->st_mode & S_IRGRP)
275 return_stat->mode |= SILC_FILE_IRGRP;
278 if (status->st_mode & S_IWGRP)
279 return_stat->mode |= SILC_FILE_IWGRP;
282 if (status->st_mode & S_IXGRP)
283 return_stat->mode |= SILC_FILE_IXGRP;
286 if (status->st_mode & S_IROTH)
287 return_stat->mode |= SILC_FILE_IROTH;
290 if (status->st_mode & S_IWOTH)
291 return_stat->mode |= SILC_FILE_IWOTH;
294 if (status->st_mode & S_IXOTH)
295 return_stat->mode |= SILC_FILE_IXOTH;
299 /* Return file status information */
301 SilcBool silc_file_stat(const char *filename, SilcBool follow_symlinks,
302 SilcFileStat return_stat)
306 if (silc_unlikely(!filename || !return_stat)) {
307 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
311 SILC_LOG_DEBUG(("Get status for file '%s'", filename));
313 if (!follow_symlinks) {
314 if (silc_unlikely(stat(filename, &status) != 0)) {
315 silc_set_errno_posix(errno);
320 if (silc_unlikely(lstat(filename, &status) != 0)) {
321 silc_set_errno_posix(errno);
325 if (silc_unlikely(stat(filename, &status) != 0)) {
326 silc_set_errno_posix(errno);
329 #endif /* HAVE_LSTAT */
332 silc_file_fill_stat(&status, return_stat);
337 /* Return file status information. */
339 SilcBool silc_file_fstat(int fd, SilcFileStat return_stat)
343 if (silc_unlikely(!return_stat)) {
344 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
348 if (silc_unlikely(fstat(fd, &status) != 0)) {
349 silc_set_errno_posix(errno);
353 silc_file_fill_stat(&status, return_stat);