]>
jfr.im git - irc/quakenet/snircd.git/blob - ircd/fileio.c
2 * IRC - Internet Relay Chat, ircd/fileio.c
3 * Copyright (C) 1998 Thomas Helvey <tomh@inxpress.net>
4 * Copyright (C) 1990 Jarkko Oikarinen and
5 * University of Oulu, Co Center
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 1, or (at your option)
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * @brief ANSI FILE* clone API implementation.
23 * @version $Id: fileio.c,v 1.8 2005/03/20 16:06:17 entrope Exp $
28 #include "ircd_alloc.h" /* MyMalloc, MyFree */
29 #include "ircd_log.h" /* assert */
31 /* #include <assert.h> -- Now using assert in ircd_log.h */ /* assert */
32 #include <fcntl.h> /* O_RDONLY, O_WRONLY, ... */
33 #include <stdio.h> /* BUFSIZ, EOF */
34 #include <sys/stat.h> /* struct stat */
35 #include <unistd.h> /* read, write, open, close */
38 #define FB_EOF 0x01 /**< File has reached EOF. */
39 #define FB_FAIL 0x02 /**< File operation failed. */
41 /** Tracks status and buffer for a file on disk. */
43 int fd
; /**< file descriptor */
44 char *endp
; /**< one past the end */
45 char *ptr
; /**< current read pos */
46 int flags
; /**< file state */
47 char buf
[BUFSIZ
]; /**< buffer */
50 /** Open a new FBFILE.
51 * @param[in] filename Name of file to open.
52 * @param[in] mode fopen()-style mode string.
53 * @return Pointer to newly allocated FBFILE.
55 FBFILE
* fbopen(const char *filename
, const char *mode
)
70 openmode
= O_WRONLY
| O_CREAT
| O_TRUNC
;
71 pmode
= S_IRUSR
| S_IWUSR
;
74 openmode
= O_WRONLY
| O_CREAT
| O_APPEND
;
75 pmode
= S_IRUSR
| S_IWUSR
;
78 openmode
&= ~(O_RDONLY
| O_WRONLY
);
87 * stop NFS hangs...most systems should be able to open a file in
88 * 3 seconds. -avalon (courtesy of wumpus)
91 if ((fd
= open(filename
, openmode
, pmode
)) == -1) {
97 if (NULL
== (fb
= fdbopen(fd
, NULL
)))
102 /** Open a FBFILE from a file descriptor.
103 * @param[in] fd File descriptor to use.
104 * @param[in] mode fopen()-style mode string (ignored).
106 FBFILE
* fdbopen(int fd
, const char *mode
)
109 * ignore mode, if file descriptor hasn't been opened with the
110 * correct mode, the first use will fail
112 FBFILE
*fb
= (FBFILE
*) MyMalloc(sizeof(FBFILE
));
114 fb
->ptr
= fb
->endp
= fb
->buf
;
122 * @param[in] fb File buffer to close.
124 void fbclose(FBFILE
* fb
)
131 /** Attempt to fill a file's buffer.
132 * @param[in] fb File to operate on.
133 * @return Number of bytes read into buffer, or a negative number on error.
135 static int fbfill(FBFILE
* fb
)
141 n
= read(fb
->fd
, fb
->buf
, BUFSIZ
);
145 fb
->endp
= fb
->buf
+ n
;
148 fb
->flags
|= FB_FAIL
;
154 /** Get a single character from a file.
155 * @param[in] fb File to fetch from.
156 * @return Character value read, or EOF on error or end-of-file.
158 int fbgetc(FBFILE
* fb
)
161 if (fb
->ptr
< fb
->endp
|| fbfill(fb
) > 0)
166 /** Get a line of input from a file.
167 * @param[out] buf Output buffer to read to.
168 * @param[in] len Maximum number of bytes to write to buffer
169 * (including terminating NUL).
170 * @param[in] fb File to read from.
172 char *fbgets(char *buf
, size_t len
, FBFILE
* fb
)
179 if (fb
->ptr
== fb
->endp
&& fbfill(fb
) < 1)
192 else if ('\r' == *p
) {
193 if (fb
->ptr
< fb
->endp
|| fbfill(fb
) > 0) {
194 if ('\n' == *fb
->ptr
)
201 if (fb
->ptr
== fb
->endp
&& fbfill(fb
) < 1)
208 /** Write a string to a file.
209 * @param[in] str String to write to file.
210 * @param[in] fb File to write to.
211 * @return Number of bytes written, or -1 on error.
213 int fbputs(const char *str
, FBFILE
* fb
)
219 if (0 == fb
->flags
) {
220 n
= write(fb
->fd
, str
, strlen(str
));
222 fb
->flags
|= FB_FAIL
;
228 * @param[out] sb Receives file status.
229 * @param[in] fb File to get status for.
230 * @return Zero on success, -1 on error.
232 int fbstat(struct stat
*sb
, FBFILE
* fb
)
236 return fstat(fb
->fd
, sb
);