ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/src/fileio.c
Revision: 34
Committed: Sun Oct 2 21:05:51 2005 UTC (18 years, 5 months ago) by lusky
Content type: text/x-csrc
File size: 5638 byte(s)
Log Message:
create 7.2 branch, we can move/rename it as needed.


File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * fileio.c: Provides a file input-output interface to ircd.
4 *
5 * Copyright (C) 2002 by the past and present ircd coders, and others.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 *
22 * $Id$
23 */
24
25 #include "stdinc.h"
26 #include "fileio.h"
27 #include "irc_string.h"
28 #include "memory.h"
29 #include "s_log.h"
30
31 /* The following are to get the fd manipulation routines. eww. */
32 #include "fdlist.h"
33
34
35 /*
36 * Wrappers around open() / close() for fileio, since a whole bunch of
37 * code that should be using the fbopen() / fbclose() code isn't.
38 * Grr. -- adrian
39 */
40 int
41 file_open(fde_t *F, const char *filename, int mode, int fmode)
42 {
43 int fd;
44 #ifdef _WIN32
45 DWORD dwDesiredAccess = 0;
46
47 switch (mode & ~(O_CREAT | O_TRUNC | O_APPEND))
48 {
49 case O_RDONLY:
50 dwDesiredAccess = GENERIC_READ;
51 break;
52 case O_WRONLY:
53 dwDesiredAccess = GENERIC_WRITE;
54 break;
55 case O_RDWR:
56 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
57 }
58
59 fd = (int) CreateFile(
60 filename,
61 dwDesiredAccess,
62 FILE_SHARE_READ | ((dwDesiredAccess & GENERIC_WRITE) ? 0:FILE_SHARE_WRITE),
63 NULL,
64 ((mode & O_CREAT) == 0) ? OPEN_EXISTING :
65 ((mode & O_TRUNC) ? CREATE_ALWAYS : OPEN_ALWAYS),
66 FILE_ATTRIBUTE_NORMAL,
67 NULL
68 );
69
70 if (fd == (int)INVALID_HANDLE_VALUE)
71 {
72 errno = GetLastError();
73 return -1;
74 }
75
76 if ((mode & O_APPEND))
77 SetFilePointer((HANDLE)fd, 0, NULL, FILE_END);
78 #else
79 if (number_fd == hard_fdlimit)
80 {
81 errno = ENFILE;
82 return -1;
83 }
84
85 if ((fd = open(filename, mode, fmode)) < 0)
86 return -1;
87 #endif
88
89 fd_open(F, fd, 0, filename);
90 return 0;
91 }
92
93 void
94 file_close(fde_t *F)
95 {
96 fd_close(F);
97 }
98
99 FBFILE *
100 fbopen(const char *filename, const char *mode)
101 {
102 FBFILE *fb = MyMalloc(sizeof(FBFILE));
103 int openmode = 0;
104 int pmode = 0;
105
106 while (*mode)
107 switch (*mode++)
108 {
109 case 'r':
110 openmode = O_RDONLY;
111 break;
112 case 'w':
113 openmode = O_WRONLY | O_CREAT | O_TRUNC;
114 pmode = 0644;
115 break;
116 case 'a':
117 openmode = O_WRONLY | O_CREAT | O_APPEND;
118 pmode = 0644;
119 break;
120 case '+':
121 openmode &= ~(O_RDONLY | O_WRONLY);
122 openmode |= O_RDWR;
123 }
124
125 if (file_open(&fb->F, filename, openmode, pmode) < 0)
126 {
127 MyFree(fb);
128 return NULL;
129 }
130
131 fb->ptr = fb->endp = fb->buf;
132 fb->flags = 0;
133 fb->pbptr = NULL;
134 return fb;
135 }
136
137 int
138 fbrewind(FBFILE *fb)
139 {
140 fb->ptr = fb->endp = fb->buf;
141 fb->flags = 0;
142 fb->pbptr = NULL;
143
144 #ifdef _WIN32
145 SetFilePointer((HANDLE)fb->F.fd, 0, NULL, FILE_BEGIN);
146 #else
147 lseek(fb->F.fd, 0, SEEK_SET);
148 #endif
149 return 0;
150 }
151
152 void
153 fbclose(FBFILE *fb)
154 {
155 if (fb == NULL)
156 return;
157 file_close(&fb->F);
158 MyFree(fb);
159 }
160
161 static int
162 fbfill(FBFILE *fb)
163 {
164 int n;
165
166 if (fb->flags)
167 return -1;
168
169 #ifdef _WIN32
170 if (!ReadFile((HANDLE)fb->F.fd, fb->buf, BUFSIZ, (LPDWORD)&n, NULL))
171 n = -1;
172 #else
173 n = read(fb->F.fd, fb->buf, BUFSIZ);
174 #endif
175
176 if (n > 0)
177 {
178 fb->ptr = fb->buf;
179 fb->endp = fb->buf + n;
180 }
181 else if (n < 0)
182 fb->flags |= FB_FAIL;
183 else
184 fb->flags |= FB_EOF;
185
186 return n;
187 }
188
189 int
190 fbgetc(FBFILE *fb)
191 {
192 if (fb->pbptr != NULL)
193 if ((fb->pbptr == (fb->pbuf + BUFSIZ)) || !*fb->pbptr)
194 fb->pbptr = NULL;
195
196 if (fb->ptr < fb->endp || fbfill(fb) > 0)
197 return *fb->ptr++;
198
199 return EOF;
200 }
201
202 void
203 fbungetc(char c, FBFILE *fb)
204 {
205 if (fb->pbptr == NULL)
206 fb->pbptr = fb->pbuf + BUFSIZ;
207
208 if (fb->pbptr != fb->pbuf)
209 *--fb->pbptr = c;
210 }
211
212 char *
213 fbgets(char *buf, size_t len, FBFILE *fb)
214 {
215 char *p = buf;
216 assert(0 < len);
217
218 if (fb->pbptr != NULL)
219 {
220 strlcpy(buf, fb->pbptr, len);
221 fb->pbptr = NULL;
222 return buf;
223 }
224
225 if (fb->ptr == fb->endp && fbfill(fb) < 1)
226 return NULL;
227
228 --len;
229
230 while (len--)
231 {
232 *p = *fb->ptr++;
233
234 if ('\n' == *p)
235 {
236 ++p;
237 break;
238 }
239
240 /* deal with CR's */
241 else if ('\r' == *p)
242 {
243 if (fb->ptr < fb->endp || fbfill(fb) > 0)
244 {
245 if ('\n' == *fb->ptr)
246 ++fb->ptr;
247 }
248
249 *p++ = '\n';
250 break;
251 }
252
253 ++p;
254
255 if (fb->ptr == fb->endp && fbfill(fb) < 1)
256 break;
257 }
258
259 *p = '\0';
260 return buf;
261 }
262
263 int
264 fbputs(const char *str, FBFILE *fb, size_t nbytes)
265 {
266 int n = -1;
267
268 if (0 == fb->flags)
269 {
270 assert(strlen(str) == nbytes);
271 #ifdef _WIN32
272 if (!WriteFile((HANDLE)fb->F.fd, str, nbytes, (LPDWORD)&n, NULL))
273 n = -1;
274 #else
275 n = write(fb->F.fd, str, nbytes);
276 #endif
277 if (n == -1)
278 fb->flags |= FB_FAIL;
279 }
280
281 return n;
282 }
283
284 int
285 save_spare_fd(const char *spare_purpose)
286 {
287 int spare_fd = open(PATH_DEVNULL, O_RDONLY, 0);
288
289 if (spare_fd < 0)
290 {
291 ilog(L_NOTICE, "Failed to reserve low fd for %s - open failed", spare_purpose);
292 return -1;
293 }
294 else if (spare_fd > 255)
295 {
296 ilog(L_NOTICE, "Failed to reserve low fd for %s - too high", spare_purpose);
297 close(spare_fd);
298 return -1;
299 }
300
301 return spare_fd;
302 }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision