00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "stdinc.h"
00026 #include "fileio.h"
00027 #include "irc_string.h"
00028 #include "memory.h"
00029 #include "s_log.h"
00030
00031
00032 #include "fdlist.h"
00033
00034
00035
00036
00037
00038
00039
00040 int
00041 file_open(fde_t *F, const char *filename, int mode, int fmode)
00042 {
00043 int fd;
00044 #ifdef _WIN32
00045 DWORD dwDesiredAccess = 0;
00046
00047 switch (mode & ~(O_CREAT | O_TRUNC | O_APPEND))
00048 {
00049 case O_RDONLY:
00050 dwDesiredAccess = GENERIC_READ;
00051 break;
00052 case O_WRONLY:
00053 dwDesiredAccess = GENERIC_WRITE;
00054 break;
00055 case O_RDWR:
00056 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
00057 }
00058
00059 fd = (int) CreateFile(
00060 filename,
00061 dwDesiredAccess,
00062 FILE_SHARE_READ | ((dwDesiredAccess & GENERIC_WRITE) ? 0:FILE_SHARE_WRITE),
00063 NULL,
00064 ((mode & O_CREAT) == 0) ? OPEN_EXISTING :
00065 ((mode & O_TRUNC) ? CREATE_ALWAYS : OPEN_ALWAYS),
00066 FILE_ATTRIBUTE_NORMAL,
00067 NULL
00068 );
00069
00070 if (fd == (int)INVALID_HANDLE_VALUE)
00071 {
00072 errno = GetLastError();
00073 return -1;
00074 }
00075
00076 if ((mode & O_APPEND))
00077 SetFilePointer((HANDLE)fd, 0, NULL, FILE_END);
00078 #else
00079 if (number_fd == hard_fdlimit)
00080 {
00081 errno = ENFILE;
00082 return -1;
00083 }
00084
00085 if ((fd = open(filename, mode, fmode)) < 0)
00086 return -1;
00087 #endif
00088
00089 fd_open(F, fd, 0, filename);
00090 return 0;
00091 }
00092
00093 void
00094 file_close(fde_t *F)
00095 {
00096 fd_close(F);
00097 }
00098
00099 FBFILE *
00100 fbopen(const char *filename, const char *mode)
00101 {
00102 FBFILE *fb = MyMalloc(sizeof(FBFILE));
00103 int openmode = 0;
00104 int pmode = 0;
00105
00106 while (*mode)
00107 switch (*mode++)
00108 {
00109 case 'r':
00110 openmode = O_RDONLY;
00111 break;
00112 case 'w':
00113 openmode = O_WRONLY | O_CREAT | O_TRUNC;
00114 pmode = 0644;
00115 break;
00116 case 'a':
00117 openmode = O_WRONLY | O_CREAT | O_APPEND;
00118 pmode = 0644;
00119 break;
00120 case '+':
00121 openmode &= ~(O_RDONLY | O_WRONLY);
00122 openmode |= O_RDWR;
00123 }
00124
00125 if (file_open(&fb->F, filename, openmode, pmode) < 0)
00126 {
00127 MyFree(fb);
00128 return NULL;
00129 }
00130
00131 fb->ptr = fb->endp = fb->buf;
00132 fb->flags = 0;
00133 fb->pbptr = NULL;
00134 return fb;
00135 }
00136
00137 int
00138 fbrewind(FBFILE *fb)
00139 {
00140 fb->ptr = fb->endp = fb->buf;
00141 fb->flags = 0;
00142 fb->pbptr = NULL;
00143
00144 #ifdef _WIN32
00145 SetFilePointer((HANDLE)fb->F.fd, 0, NULL, FILE_BEGIN);
00146 #else
00147 lseek(fb->F.fd, 0, SEEK_SET);
00148 #endif
00149 return 0;
00150 }
00151
00152 void
00153 fbclose(FBFILE *fb)
00154 {
00155 if (fb == NULL)
00156 return;
00157 file_close(&fb->F);
00158 MyFree(fb);
00159 }
00160
00161 static int
00162 fbfill(FBFILE *fb)
00163 {
00164 int n;
00165
00166 if (fb->flags)
00167 return -1;
00168
00169 #ifdef _WIN32
00170 if (!ReadFile((HANDLE)fb->F.fd, fb->buf, BUFSIZ, (LPDWORD)&n, NULL))
00171 n = -1;
00172 #else
00173 n = read(fb->F.fd, fb->buf, BUFSIZ);
00174 #endif
00175
00176 if (n > 0)
00177 {
00178 fb->ptr = fb->buf;
00179 fb->endp = fb->buf + n;
00180 }
00181 else if (n < 0)
00182 fb->flags |= FB_FAIL;
00183 else
00184 fb->flags |= FB_EOF;
00185
00186 return n;
00187 }
00188
00189 int
00190 fbgetc(FBFILE *fb)
00191 {
00192 if (fb->pbptr != NULL)
00193 if ((fb->pbptr == (fb->pbuf + BUFSIZ)) || !*fb->pbptr)
00194 fb->pbptr = NULL;
00195
00196 if (fb->ptr < fb->endp || fbfill(fb) > 0)
00197 return *fb->ptr++;
00198
00199 return EOF;
00200 }
00201
00202 void
00203 fbungetc(char c, FBFILE *fb)
00204 {
00205 if (fb->pbptr == NULL)
00206 fb->pbptr = fb->pbuf + BUFSIZ;
00207
00208 if (fb->pbptr != fb->pbuf)
00209 *--fb->pbptr = c;
00210 }
00211
00212 char *
00213 fbgets(char *buf, size_t len, FBFILE *fb)
00214 {
00215 char *p = buf;
00216 assert(0 < len);
00217
00218 if (fb->pbptr != NULL)
00219 {
00220 strlcpy(buf, fb->pbptr, len);
00221 fb->pbptr = NULL;
00222 return buf;
00223 }
00224
00225 if (fb->ptr == fb->endp && fbfill(fb) < 1)
00226 return NULL;
00227
00228 --len;
00229
00230 while (len--)
00231 {
00232 *p = *fb->ptr++;
00233
00234 if ('\n' == *p)
00235 {
00236 ++p;
00237 break;
00238 }
00239
00240
00241 else if ('\r' == *p)
00242 {
00243 if (fb->ptr < fb->endp || fbfill(fb) > 0)
00244 {
00245 if ('\n' == *fb->ptr)
00246 ++fb->ptr;
00247 }
00248
00249 *p++ = '\n';
00250 break;
00251 }
00252
00253 ++p;
00254
00255 if (fb->ptr == fb->endp && fbfill(fb) < 1)
00256 break;
00257 }
00258
00259 *p = '\0';
00260 return buf;
00261 }
00262
00263 int
00264 fbputs(const char *str, FBFILE *fb, size_t nbytes)
00265 {
00266 int n = -1;
00267
00268 if (0 == fb->flags)
00269 {
00270 assert(strlen(str) == nbytes);
00271 #ifdef _WIN32
00272 if (!WriteFile((HANDLE)fb->F.fd, str, nbytes, (LPDWORD)&n, NULL))
00273 n = -1;
00274 #else
00275 n = write(fb->F.fd, str, nbytes);
00276 #endif
00277 if (n == -1)
00278 fb->flags |= FB_FAIL;
00279 }
00280
00281 return n;
00282 }
00283
00284 int
00285 save_spare_fd(const char *spare_purpose)
00286 {
00287 int spare_fd = open(PATH_DEVNULL, O_RDONLY, 0);
00288
00289 if (spare_fd < 0)
00290 {
00291 ilog(L_NOTICE, "Failed to reserve low fd for %s - open failed", spare_purpose);
00292 return -1;
00293 }
00294 else if (spare_fd > 255)
00295 {
00296 ilog(L_NOTICE, "Failed to reserve low fd for %s - too high", spare_purpose);
00297 close(spare_fd);
00298 return -1;
00299 }
00300
00301 return spare_fd;
00302 }