1 /*
2 * files.c -- allows you to read/write files. Wow.
3 *
4 * (C) 1995 Jeremy Nelson (ESL)
5 * See the COPYRIGHT file for more information
6 */
7
8 #include "irc.h"
9 static char cvsrevision[] = "$Id: files.c 3 2008-02-25 09:49:14Z keaston $";
10 CVS_REVISION(files_c)
11 #include "ircaux.h"
12 #define MAIN_SOURCE
13 #include "modval.h"
14
15 /* Here's the plan.
16 * You want to open a file.. you can READ it or you can WRITE it.
17 * unix files can be read/written, but its not the way you expect.
18 * so we will only alllow one or the other. If you try to write to
19 * read only file, it punts, and if you try to read a writable file,
20 * you get a null.
21 *
22 * New functions: open(FILENAME <type>)
23 * <type> is 0 for read, 1 for write, 0 is default.
24 * Returns fd of opened file, -1 on error
25 * read (fd)
26 * Returns line for given fd, as long as fd is
27 * opened via the open() call, -1 on error
28 * write (fd text)
29 * Writes the text to the file pointed to by fd.
30 * Returns the number of bytes written, -1 on error
31 * close (fd)
32 * closes file for given fd
33 * Returns 0 on OK, -1 on error
34 * eof (fd)
35 * Returns 1 if fd is at EOF, 0 if not. -1 on error
36 */
37
38 struct FILE___ {
39 FILE *file;
40 struct FILE___ *next;
41 };
42 typedef struct FILE___ File;
43
44 static File *FtopEntry = NULL;
45
new_file(void)46 File *new_file (void)
47 {
48 File *tmp = FtopEntry;
49 File *tmpfile = (File *)new_malloc(sizeof(File));
50
51 if (FtopEntry == NULL)
52 FtopEntry = tmpfile;
53 else
54 {
55 while (tmp->next)
56 tmp = tmp->next;
57 tmp->next = tmpfile;
58 }
59 return tmpfile;
60 }
61
remove_file(File * file)62 void remove_file (File *file)
63 {
64 File *tmp = FtopEntry;
65
66 if (file == FtopEntry)
67 FtopEntry = file->next;
68 else
69 {
70 while (tmp->next && tmp->next != file)
71 tmp = tmp->next;
72 if (tmp->next)
73 tmp->next = tmp->next->next;
74 }
75 fclose(file->file);
76 new_free((char **)&file);
77 }
78
79
open_file_for_read(char * filename)80 int open_file_for_read (char *filename)
81 {
82 char *dummy_filename = NULL;
83 FILE *file;
84
85 malloc_strcpy(&dummy_filename, filename);
86 file = uzfopen(&dummy_filename, ".", 0);
87 new_free(&dummy_filename);
88 if (file)
89 {
90 File *nfs = new_file();
91 nfs->file = file;
92 nfs->next = NULL;
93 return fileno(file);
94 }
95 else
96 return -1;
97 }
98
open_file_for_write(char * filename)99 int open_file_for_write (char *filename)
100 {
101 /* patch by Scott H Kilau so expand_twiddle works */
102 char *expand = NULL;
103 FILE *file;
104
105 if (!(expand = expand_twiddle(filename)))
106 malloc_strcpy(&expand, filename);
107 file = fopen(expand, "a");
108 new_free(&expand);
109 if (file)
110 {
111 File *nfs = new_file();
112 nfs->file = file;
113 nfs->next = NULL;
114 return fileno(file);
115 }
116 else
117 return -1;
118 }
119
open_file_for_bwrite(char * filename)120 int open_file_for_bwrite (char *filename)
121 {
122 /* patch by Scott H Kilau so expand_twiddle works */
123 char *expand = NULL;
124 FILE *file;
125
126 if (!(expand = expand_twiddle(filename)))
127 malloc_strcpy(&expand, filename);
128 file = fopen(expand, "wb");
129 new_free(&expand);
130 if (file)
131 {
132 File *nfs = new_file();
133 nfs->file = file;
134 nfs->next = NULL;
135 return fileno(file);
136 }
137 else
138 return -1;
139 }
140
lookup_file(int fd)141 File *lookup_file (int fd)
142 {
143 File *ptr = FtopEntry;
144
145 while (ptr)
146 {
147 if (fileno(ptr->file) == fd)
148 return ptr;
149 else
150 ptr = ptr -> next;
151 }
152 return NULL;
153 }
154
file_write(int fd,char * stuff)155 int file_write (int fd, char *stuff)
156 {
157 File *ptr = lookup_file(fd);
158 int ret;
159 if (!ptr)
160 return -1;
161 ret = fprintf(ptr->file, "%s\n", stuff);
162 fflush(ptr->file);
163 return ret;
164 }
165
file_writeb(int fd,char * stuff)166 int file_writeb (int fd, char *stuff)
167 {
168 File *ptr = lookup_file(fd);
169 int ret;
170 if (!ptr)
171 return -1;
172 ret = fwrite(stuff, 1, strlen(stuff), ptr->file);
173 fflush(ptr->file);
174 return ret;
175 }
176
file_read(int fd)177 char *file_read (int fd)
178 {
179 File *ptr = lookup_file(fd);
180 if (!ptr)
181 return m_strdup(empty_string);
182 else
183 {
184 char blah[10240];
185 if ((fgets(blah, 10239, ptr->file)))
186 chop(blah, 1);
187 else
188 blah[0] = 0;
189 return m_strdup(blah);
190 }
191 }
192
file_readb(int fd,int numb)193 char *file_readb (int fd, int numb)
194 {
195 File *ptr = lookup_file(fd);
196 if (!ptr)
197 return m_strdup(empty_string);
198 else
199 {
200 char *blah = (char *)new_malloc(numb+1);
201 if ((fread(blah, 1, numb, ptr->file)))
202 blah[numb] = 0;
203 else
204 blah[0] = 0;
205 return blah;
206 }
207 }
208
209
file_eof(int fd)210 int file_eof (int fd)
211 {
212 File *ptr = lookup_file (fd);
213 if (!ptr)
214 return -1;
215 else
216 return feof(ptr->file);
217 }
218
file_close(int fd)219 int file_close (int fd)
220 {
221 File *ptr = lookup_file (fd);
222 if (!ptr)
223 return -1;
224 else
225 remove_file (ptr);
226 return 0;
227 }
228
229 /*
230 ** by: Walter Bright via Usenet C newsgroup
231 **
232 ** modified by: Bob Stout based on a recommendation by Ray Gardner
233 **
234 ** There is no point in going to asm to get high speed file copies. Since it
235 ** is inherently disk-bound, there is no sense (unless tiny code size is
236 ** the goal). Here's a C version that you'll find is as fast as any asm code
237 ** for files larger than a few bytes (the trick is to use large disk buffers):
238 */
239
file_copy(int from,int to)240 int file_copy(int from,int to)
241 {
242 int bufsiz;
243 if (from < 0)
244 return 1;
245 if (to < 0)
246 return 1;
247
248 if (!fork())
249 {
250 /* Use the largest buffer we can get */
251 for (bufsiz = 0x4000; bufsiz >= 128; bufsiz >>= 1)
252 {
253 register char *buffer;
254
255 buffer = (char *) malloc(bufsiz);
256 if (buffer)
257 {
258 while (1)
259 {
260 register int n;
261
262 n = read(from,buffer,bufsiz);
263 if (n == -1) /* if error */
264 break;
265 if (n == 0) /* if end of file */
266 {
267 free(buffer);
268 _exit(0);
269 }
270 if (n != write(to,buffer,(unsigned) n))
271 break;
272 }
273 free(buffer);
274 break;
275 }
276 }
277 _exit(1);
278 }
279 return 0;
280 }
281
file_valid(int fd)282 int file_valid (int fd)
283 {
284 if (lookup_file(fd))
285 return 1;
286 return 0;
287 }
288
289