7d2d14757281af64b6f1e7ae737fa72ed1cd7fe6
[silc.git] / lib / silcutil / silcfileutil.c
1 /*
2
3   silcfileutil.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2002 Pekka Riikonen
8
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.
12
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.
17
18 */
19 /* $Id$ */
20
21 #include "silcincludes.h"
22
23 /* Opens a file indicated by the filename `filename' with flags indicated
24    by the `flags'. */
25
26 int silc_file_open(const char *filename, int flags)
27 {
28   int fd = open(filename, flags, 0600);
29   return fd;
30 }
31
32 /* Opens a file indicated by the filename `filename' with flags indicated
33    by the `flags', and with the specified `mode'. */
34
35 int silc_file_open_mode(const char *filename, int flags, int mode)
36 {
37   int fd = open(filename, flags, mode);
38   return fd;
39 }
40
41 /* Reads data from file descriptor `fd' to `buf'. */
42
43 int silc_file_read(int fd, unsigned char *buf, SilcUInt32 buf_len)
44 {
45   return read(fd, (void *)buf, buf_len);
46 }
47
48 /* Writes `buffer' of length of `len' to file descriptor `fd'. */
49
50 int silc_file_write(int fd, const char *buffer, SilcUInt32 len)
51 {
52   return write(fd, (const void *)buffer, len);
53 }
54
55 /* Closes file descriptor */
56
57 int silc_file_close(int fd)
58 {
59   return close(fd);
60 }
61
62 /* Writes a buffer to the file. */
63
64 int silc_file_writefile(const char *filename, const char *buffer,
65                         SilcUInt32 len)
66 {
67   int fd;
68
69   if ((fd = creat(filename, 0644)) == -1) {
70     SILC_LOG_ERROR(("Cannot open file %s for writing: %s", filename,
71                     strerror(errno)));
72     return -1;
73   }
74
75   if (silc_file_write(fd, buffer, len) == -1) {
76     SILC_LOG_ERROR(("Cannot write to file %s: %s", filename, strerror(errno)));
77     silc_file_close(fd);
78     return -1;
79   }
80
81   silc_file_close(fd);
82
83   return 0;
84 }
85
86 /* Writes a buffer to the file.  If the file is created specific mode is
87    set to the file. */
88
89 int silc_file_writefile_mode(const char *filename, const char *buffer,
90                              SilcUInt32 len, int mode)
91 {
92   int fd;
93
94   if ((fd = creat(filename, mode)) == -1) {
95     SILC_LOG_ERROR(("Cannot open file %s for writing: %s", filename,
96                     strerror(errno)));
97     return -1;
98   }
99
100   if ((silc_file_write(fd, buffer, len)) == -1) {
101     SILC_LOG_ERROR(("Cannot write to file %s: %s", filename, strerror(errno)));
102     silc_file_close(fd);
103     return -1;
104   }
105
106   silc_file_close(fd);
107
108   return 0;
109 }
110
111 /* Reads a file to a buffer. The allocated buffer is returned. Length of
112    the file read is returned to the return_len argument. */
113
114 char *silc_file_readfile(const char *filename, SilcUInt32 *return_len)
115 {
116   int fd;
117   char *buffer;
118   int filelen;
119
120   fd = silc_file_open(filename, O_RDONLY);
121   if (fd < 0) {
122     if (errno == ENOENT)
123       return NULL;
124     SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno)));
125     return NULL;
126   }
127
128   filelen = lseek(fd, (off_t)0L, SEEK_END);
129   if (filelen < 0) {
130     silc_file_close(fd);
131     return NULL;
132   }
133   if (lseek(fd, (off_t)0L, SEEK_SET) < 0) {
134     silc_file_close(fd);
135     return NULL;
136   }
137
138   if (filelen < 0) {
139     SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno)));
140     silc_file_close(fd);
141     return NULL;
142   }
143
144   buffer = silc_calloc(filelen + 1, sizeof(char));
145
146   if ((silc_file_read(fd, buffer, filelen)) == -1) {
147     memset(buffer, 0, sizeof(buffer));
148     silc_file_close(fd);
149     SILC_LOG_ERROR(("Cannot read from file %s: %s", filename,
150                     strerror(errno)));
151     return NULL;
152   }
153
154   silc_file_close(fd);
155   buffer[filelen] = EOF;
156
157   if (return_len)
158     *return_len = filelen;
159
160   return buffer;
161 }
162
163 /* Returns the size of `filename'. Returns 0 on error. */
164
165 SilcUInt64 silc_file_size(const char *filename)
166 {
167   int ret;
168   struct stat stats;
169
170 #ifndef SILC_WIN32
171   ret = lstat(filename, &stats);
172 #else
173   ret = stat(filename, &stats);
174 #endif
175   if (ret < 0)
176     return 0;
177
178   return (SilcUInt64)stats.st_size;
179 }