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