ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/src/fileio.c
Revision: 1028
Committed: Sun Nov 8 13:03:38 2009 UTC (14 years, 5 months ago) by michael
Content type: text/x-csrc
File size: 4548 byte(s)
Log Message:
- move ircd-hybrid-7.2 to trunk

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
45 if (number_fd == hard_fdlimit)
46 {
47 errno = ENFILE;
48 return -1;
49 }
50
51 if ((fd = open(filename, mode, fmode)) < 0)
52 return -1;
53
54 fd_open(F, fd, 0, filename);
55 return 0;
56 }
57
58 void
59 file_close(fde_t *F)
60 {
61 fd_close(F);
62 }
63
64 FBFILE *
65 fbopen(const char *filename, const char *mode)
66 {
67 FBFILE *fb = MyMalloc(sizeof(FBFILE));
68 int openmode = 0;
69 int pmode = 0;
70
71 while (*mode)
72 switch (*mode++)
73 {
74 case 'r':
75 openmode = O_RDONLY;
76 break;
77 case 'w':
78 openmode = O_WRONLY | O_CREAT | O_TRUNC;
79 pmode = 0644;
80 break;
81 case 'a':
82 openmode = O_WRONLY | O_CREAT | O_APPEND;
83 pmode = 0644;
84 break;
85 case '+':
86 openmode &= ~(O_RDONLY | O_WRONLY);
87 openmode |= O_RDWR;
88 }
89
90 if (file_open(&fb->F, filename, openmode, pmode) < 0)
91 {
92 MyFree(fb);
93 return NULL;
94 }
95
96 fb->ptr = fb->endp = fb->buf;
97 fb->flags = 0;
98 fb->pbptr = NULL;
99 return fb;
100 }
101
102 int
103 fbrewind(FBFILE *fb)
104 {
105 fb->ptr = fb->endp = fb->buf;
106 fb->flags = 0;
107 fb->pbptr = NULL;
108
109 lseek(fb->F.fd, 0, SEEK_SET);
110 return 0;
111 }
112
113 void
114 fbclose(FBFILE *fb)
115 {
116 if (fb == NULL)
117 return;
118 file_close(&fb->F);
119 MyFree(fb);
120 }
121
122 static int
123 fbfill(FBFILE *fb)
124 {
125 int n;
126
127 if (fb->flags)
128 return -1;
129
130 n = read(fb->F.fd, fb->buf, BUFSIZ);
131
132 if (n > 0)
133 {
134 fb->ptr = fb->buf;
135 fb->endp = fb->buf + n;
136 }
137 else if (n < 0)
138 fb->flags |= FB_FAIL;
139 else
140 fb->flags |= FB_EOF;
141
142 return n;
143 }
144
145 int
146 fbgetc(FBFILE *fb)
147 {
148 if (fb->pbptr != NULL)
149 if ((fb->pbptr == (fb->pbuf + BUFSIZ)) || !*fb->pbptr)
150 fb->pbptr = NULL;
151
152 if (fb->ptr < fb->endp || fbfill(fb) > 0)
153 return *fb->ptr++;
154
155 return EOF;
156 }
157
158 void
159 fbungetc(char c, FBFILE *fb)
160 {
161 if (fb->pbptr == NULL)
162 fb->pbptr = fb->pbuf + BUFSIZ;
163
164 if (fb->pbptr != fb->pbuf)
165 *--fb->pbptr = c;
166 }
167
168 char *
169 fbgets(char *buf, size_t len, FBFILE *fb)
170 {
171 char *p = buf;
172 assert(0 < len);
173
174 if (fb->pbptr != NULL)
175 {
176 strlcpy(buf, fb->pbptr, len);
177 fb->pbptr = NULL;
178 return buf;
179 }
180
181 if (fb->ptr == fb->endp && fbfill(fb) < 1)
182 return NULL;
183
184 --len;
185
186 while (len--)
187 {
188 *p = *fb->ptr++;
189
190 if ('\n' == *p)
191 {
192 ++p;
193 break;
194 }
195
196 /* deal with CR's */
197 else if ('\r' == *p)
198 {
199 if (fb->ptr < fb->endp || fbfill(fb) > 0)
200 {
201 if ('\n' == *fb->ptr)
202 ++fb->ptr;
203 }
204
205 *p++ = '\n';
206 break;
207 }
208
209 ++p;
210
211 if (fb->ptr == fb->endp && fbfill(fb) < 1)
212 break;
213 }
214
215 *p = '\0';
216 return buf;
217 }
218
219 int
220 fbputs(const char *str, FBFILE *fb, size_t nbytes)
221 {
222 int n = -1;
223
224 if (0 == fb->flags)
225 {
226 assert(strlen(str) == nbytes);
227 n = write(fb->F.fd, str, nbytes);
228
229 if (n == -1)
230 fb->flags |= FB_FAIL;
231 }
232
233 return n;
234 }
235
236 int
237 save_spare_fd(const char *spare_purpose)
238 {
239 int spare_fd = open(PATH_DEVNULL, O_RDONLY, 0);
240
241 if (spare_fd < 0)
242 {
243 ilog(L_NOTICE, "Failed to reserve low fd for %s - open failed", spare_purpose);
244 return -1;
245 }
246 else if (spare_fd > 255)
247 {
248 ilog(L_NOTICE, "Failed to reserve low fd for %s - too high", spare_purpose);
249 close(spare_fd);
250 return -1;
251 }
252
253 return spare_fd;
254 }

Properties

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