Merged from silc_1_0_branch.
[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   int flags = O_CREAT | O_WRONLY | O_TRUNC;
69
70 #if defined(O_BINARY)
71   flags |= O_BINARY;
72 #endif /* O_BINARY */
73
74   if ((fd = open(filename, flags, 0644)) == -1) {
75     SILC_LOG_ERROR(("Cannot open file %s for writing: %s", filename,
76                     strerror(errno)));
77     return -1;
78   }
79
80   if (silc_file_write(fd, buffer, len) == -1) {
81     SILC_LOG_ERROR(("Cannot write to file %s: %s", filename, strerror(errno)));
82     silc_file_close(fd);
83     return -1;
84   }
85
86   silc_file_close(fd);
87
88   return 0;
89 }
90
91 /* Writes a buffer to the file.  If the file is created specific mode is
92    set to the file. */
93
94 int silc_file_writefile_mode(const char *filename, const char *buffer,
95                              SilcUInt32 len, int mode)
96 {
97   int fd;
98   int flags = O_CREAT | O_WRONLY | O_TRUNC;
99
100 #if defined(O_BINARY)
101   flags |= O_BINARY;
102 #endif /* O_BINARY */
103
104   if ((fd = open(filename, flags, 0644)) == -1) {
105     SILC_LOG_ERROR(("Cannot open file %s for writing: %s", filename,
106                     strerror(errno)));
107     return -1;
108   }
109
110   if ((silc_file_write(fd, buffer, len)) == -1) {
111     SILC_LOG_ERROR(("Cannot write to file %s: %s", filename, strerror(errno)));
112     silc_file_close(fd);
113     return -1;
114   }
115
116   silc_file_close(fd);
117
118   return 0;
119 }
120
121 /* Reads a file to a buffer. The allocated buffer is returned. Length of
122    the file read is returned to the return_len argument. */
123
124 char *silc_file_readfile(const char *filename, SilcUInt32 *return_len)
125 {
126   int fd;
127   char *buffer;
128   int filelen;
129
130   fd = silc_file_open(filename, O_RDONLY);
131   if (fd < 0) {
132     if (errno == ENOENT)
133       return NULL;
134     SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno)));
135     return NULL;
136   }
137
138   filelen = lseek(fd, (off_t)0L, SEEK_END);
139   if (filelen < 0) {
140     silc_file_close(fd);
141     return NULL;
142   }
143   if (lseek(fd, (off_t)0L, SEEK_SET) < 0) {
144     silc_file_close(fd);
145     return NULL;
146   }
147
148   if (filelen < 0) {
149     SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno)));
150     silc_file_close(fd);
151     return NULL;
152   }
153
154   buffer = silc_calloc(filelen + 1, sizeof(char));
155
156   if ((silc_file_read(fd, buffer, filelen)) == -1) {
157     memset(buffer, 0, sizeof(buffer));
158     silc_file_close(fd);
159     SILC_LOG_ERROR(("Cannot read from file %s: %s", filename,
160                     strerror(errno)));
161     return NULL;
162   }
163
164   silc_file_close(fd);
165   buffer[filelen] = EOF;
166
167   if (return_len)
168     *return_len = filelen;
169
170   return buffer;
171 }
172
173 /* Returns the size of `filename'. Returns 0 on error. */
174
175 SilcUInt64 silc_file_size(const char *filename)
176 {
177   int ret;
178   struct stat stats;
179
180 #ifndef SILC_WIN32
181   ret = lstat(filename, &stats);
182 #else
183   ret = stat(filename, &stats);
184 #endif
185   if (ret < 0)
186     return 0;
187
188   return (SilcUInt64)stats.st_size;
189 }