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