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