1 | /* |
---|
2 | * Abuse - dark 2D side-scrolling platform game |
---|
3 | * Copyright (c) 1995 Crack dot Com |
---|
4 | * |
---|
5 | * This software was released into the Public Domain. As with most public |
---|
6 | * domain software, no warranty is made or implied by Crack dot Com or |
---|
7 | * Jonathan Clark. |
---|
8 | */ |
---|
9 | |
---|
10 | #include "config.h" |
---|
11 | |
---|
12 | #include <sys/types.h> |
---|
13 | #include <fcntl.h> |
---|
14 | #include <unistd.h> |
---|
15 | |
---|
16 | #include "specs.hpp" |
---|
17 | #include "nfserver.hpp" |
---|
18 | #include "dprint.hpp" |
---|
19 | #include "crc.hpp" |
---|
20 | #include "cache.hpp" |
---|
21 | |
---|
22 | class nfs_file : public bFILE |
---|
23 | { |
---|
24 | jFILE *local; |
---|
25 | int nfs_fd; |
---|
26 | int offset; |
---|
27 | public : |
---|
28 | nfs_file(char *filename, char *mode); |
---|
29 | virtual int open_failure(); |
---|
30 | virtual int unbuffered_read(void *buf, size_t count); // returns number of bytes read |
---|
31 | int new_read(void *buf, size_t count); // returns number of bytes read |
---|
32 | virtual int unbuffered_write(void *buf, size_t count); // returns number of bytes written |
---|
33 | virtual int unbuffered_seek(int32_t offset, int whence); // whence=SEEK_SET, SEEK_CUR, SEEK_END, ret=0=success |
---|
34 | virtual int unbuffered_tell(); |
---|
35 | virtual int file_size(); |
---|
36 | virtual ~nfs_file(); |
---|
37 | } ; |
---|
38 | |
---|
39 | bFILE *open_nfs_file(char *filename,char *mode) |
---|
40 | { |
---|
41 | return new nfs_file(filename,mode); |
---|
42 | } |
---|
43 | |
---|
44 | |
---|
45 | static out_socket *nfs_server=NULL; |
---|
46 | void connect_to_nfs_server(char *name, int port) |
---|
47 | { |
---|
48 | nfs_server=create_out_socket(name,port); |
---|
49 | if (!nfs_server) |
---|
50 | { |
---|
51 | fprintf(stderr,"%s\n",last_sock_err); |
---|
52 | exit(0); |
---|
53 | } else |
---|
54 | { |
---|
55 | set_file_opener(open_nfs_file); // from now on all files wll go through NFS creator |
---|
56 | } |
---|
57 | } |
---|
58 | |
---|
59 | static void nfs_disconnect() |
---|
60 | { |
---|
61 | if (nfs_server) |
---|
62 | { |
---|
63 | delete nfs_server; |
---|
64 | nfs_server=NULL; |
---|
65 | set_file_opener(NULL); // use local means for opening files |
---|
66 | } |
---|
67 | } |
---|
68 | |
---|
69 | |
---|
70 | nfs_file::nfs_file(char *filename, char *mode) |
---|
71 | { |
---|
72 | int local_only=0; |
---|
73 | for (char *s=mode;*s;s++) // check to see if writeable file, if so don't go through nfs |
---|
74 | if (*s=='w' || *s=='W' || *s=='a' || *s=='A') |
---|
75 | local_only=1; |
---|
76 | if (local_only) |
---|
77 | { |
---|
78 | local=new jFILE(filename,mode); |
---|
79 | nfs_fd=-1; |
---|
80 | } |
---|
81 | else |
---|
82 | { |
---|
83 | local=NULL; |
---|
84 | nfs_fd=-1; |
---|
85 | if (nfs_server) |
---|
86 | { |
---|
87 | packet pk; |
---|
88 | int do_open=0; |
---|
89 | jFILE *local_test=new jFILE(filename,mode); |
---|
90 | if (local_test->open_failure()) |
---|
91 | { |
---|
92 | delete local_test; |
---|
93 | local_test=NULL; |
---|
94 | pk.write_uint8(NFS_OPEN); |
---|
95 | } |
---|
96 | else |
---|
97 | { |
---|
98 | pk.write_uint8(NFS_CRC_OPEN); |
---|
99 | int fail; |
---|
100 | uint32_t crc=crc_man.get_crc(crc_man.get_filenumber(filename),fail); // skip crc calc if we can |
---|
101 | if (fail) crc=crc_file(local_test); |
---|
102 | pk.write_uint32(crc); |
---|
103 | } |
---|
104 | |
---|
105 | pk.write_uint8(strlen(filename)+1); |
---|
106 | pk.write((uint8_t *)filename,strlen(filename)+1); |
---|
107 | pk.write_uint8(strlen(mode)+1); |
---|
108 | pk.write((uint8_t *)mode,strlen(mode)+1); |
---|
109 | dprintf("try open %s,%s\n",filename,mode); |
---|
110 | offset=0; |
---|
111 | if (!nfs_server->send(pk)) |
---|
112 | nfs_disconnect(); |
---|
113 | else |
---|
114 | { |
---|
115 | if (!nfs_server->get(pk)) nfs_disconnect(); |
---|
116 | else |
---|
117 | { |
---|
118 | int32_t fd; |
---|
119 | if (pk.read((uint8_t *)&fd,4)!=4) |
---|
120 | nfs_disconnect(); |
---|
121 | else |
---|
122 | { |
---|
123 | fd=lltl(fd); |
---|
124 | nfs_fd=fd; |
---|
125 | if (local_test && fd==-2) // confirmed that CRCs match, use local file |
---|
126 | { local=local_test; local_test=NULL; } |
---|
127 | |
---|
128 | } |
---|
129 | } |
---|
130 | } |
---|
131 | if (local_test) |
---|
132 | delete local_test; |
---|
133 | } |
---|
134 | } |
---|
135 | } |
---|
136 | |
---|
137 | |
---|
138 | int nfs_file::open_failure() { return !local && nfs_fd==-1; } |
---|
139 | |
---|
140 | int nfs_file::unbuffered_read(void *buf, size_t count) // returns number of bytes read |
---|
141 | { |
---|
142 | if (local) |
---|
143 | return local->read(buf,count); |
---|
144 | else |
---|
145 | { |
---|
146 | int ret=new_read(buf,count); |
---|
147 | void *comp=jmalloc(count,"compare"); |
---|
148 | /* ::read(check_fd,comp,count); |
---|
149 | if (memcmp(comp,buf,count)) |
---|
150 | { |
---|
151 | printf("bad read!\n"); |
---|
152 | } |
---|
153 | jfree(comp);*/ |
---|
154 | return ret; |
---|
155 | } |
---|
156 | } |
---|
157 | |
---|
158 | int nfs_file::new_read(void *buf, size_t count) // returns number of bytes read |
---|
159 | { |
---|
160 | if (local) |
---|
161 | return local->read(buf,count); |
---|
162 | else |
---|
163 | { |
---|
164 | packet pk; |
---|
165 | pk.write_uint8(NFS_READ); |
---|
166 | pk.write_uint32(nfs_fd); |
---|
167 | pk.write_uint32(count); |
---|
168 | dprintf("try read %d,%d\n",nfs_fd,count); |
---|
169 | if (!nfs_server->send(pk)) |
---|
170 | { |
---|
171 | nfs_disconnect(); |
---|
172 | return 0; |
---|
173 | } |
---|
174 | else |
---|
175 | { |
---|
176 | |
---|
177 | int fail=0; |
---|
178 | int rtotal=0; |
---|
179 | uint16_t size=1; |
---|
180 | while (count>0 && !fail && size) |
---|
181 | { |
---|
182 | if (!nfs_server->get(pk)) fail=1; |
---|
183 | else |
---|
184 | { |
---|
185 | if (pk.read((uint8_t *)&size,2)!=2) fail=1; |
---|
186 | else |
---|
187 | { |
---|
188 | size=lstl(size); |
---|
189 | printf("read %d bytes\n",size); |
---|
190 | if (size) |
---|
191 | { |
---|
192 | int need_size=size>count ? count : size; |
---|
193 | |
---|
194 | if (pk.read((uint8_t *)buf,need_size)!=need_size) fail=1; |
---|
195 | else |
---|
196 | { |
---|
197 | count-=need_size; |
---|
198 | rtotal+=need_size; |
---|
199 | buf=(void *)(((char *)buf)+need_size); |
---|
200 | offset+=need_size; |
---|
201 | if (need_size<size) // see if there are any leftovers to buffer |
---|
202 | fprintf(stderr,"Server sent to much\n"); |
---|
203 | } |
---|
204 | if (need_size<2048) count=0; |
---|
205 | } |
---|
206 | } |
---|
207 | } |
---|
208 | } |
---|
209 | if (fail) |
---|
210 | { |
---|
211 | dprintf("nfs read failed\n"); |
---|
212 | nfs_disconnect(); |
---|
213 | } |
---|
214 | return rtotal; |
---|
215 | } |
---|
216 | } |
---|
217 | } |
---|
218 | |
---|
219 | |
---|
220 | int nfs_file::unbuffered_write(void *buf, size_t count) // returns number of bytes written |
---|
221 | { |
---|
222 | if (local) |
---|
223 | return local->write(buf,count); |
---|
224 | else |
---|
225 | { |
---|
226 | fprintf(stderr,"write to nfs file not allowed for now!\n"); |
---|
227 | exit(0); |
---|
228 | } |
---|
229 | return 0; |
---|
230 | } |
---|
231 | |
---|
232 | |
---|
233 | int nfs_file::unbuffered_seek(int32_t off, int whence) // whence=SEEK_SET, SEEK_CUR, SEEK_END, ret=0=success |
---|
234 | { |
---|
235 | if (local) |
---|
236 | return local->seek(off,whence); |
---|
237 | else |
---|
238 | { |
---|
239 | packet pk; |
---|
240 | pk.write_uint8(NFS_SEEK); |
---|
241 | pk.write_uint32(nfs_fd); |
---|
242 | |
---|
243 | pk.write_uint32(off); |
---|
244 | pk.write_uint32(whence); |
---|
245 | dprintf("seek %d %d %d\n",nfs_fd,off,whence); |
---|
246 | if (!nfs_server->send(pk)) |
---|
247 | { |
---|
248 | dprintf("disconnected on seek\n"); |
---|
249 | nfs_disconnect(); |
---|
250 | return 0; |
---|
251 | } |
---|
252 | } |
---|
253 | return 0; |
---|
254 | } |
---|
255 | |
---|
256 | int nfs_file::unbuffered_tell() |
---|
257 | { |
---|
258 | if (local) |
---|
259 | return local->tell(); |
---|
260 | else if (nfs_server) |
---|
261 | { |
---|
262 | packet pk; |
---|
263 | pk.write_uint8(NFS_TELL); |
---|
264 | pk.write_uint32(nfs_fd); |
---|
265 | if (!nfs_server->send(pk)) |
---|
266 | { |
---|
267 | nfs_disconnect(); |
---|
268 | return 0; |
---|
269 | } else |
---|
270 | { |
---|
271 | if (!nfs_server->get(pk)) |
---|
272 | { |
---|
273 | nfs_disconnect(); |
---|
274 | return 0; |
---|
275 | } else |
---|
276 | { |
---|
277 | int32_t off; |
---|
278 | if (pk.read((uint8_t *)&off,4)!=4) |
---|
279 | { |
---|
280 | dprintf("Disconnected on tell()\n"); |
---|
281 | nfs_disconnect(); |
---|
282 | } else return lltl(off); |
---|
283 | |
---|
284 | } |
---|
285 | } |
---|
286 | } |
---|
287 | return 0; |
---|
288 | } |
---|
289 | |
---|
290 | |
---|
291 | int nfs_file::file_size() |
---|
292 | { |
---|
293 | if (local) |
---|
294 | return local->file_size(); |
---|
295 | else if (nfs_server) |
---|
296 | { |
---|
297 | packet pk; |
---|
298 | pk.write_uint8(NFS_FILESIZE); |
---|
299 | pk.write_uint32(nfs_fd); |
---|
300 | if (!nfs_server->send(pk)) |
---|
301 | { |
---|
302 | nfs_disconnect(); |
---|
303 | return 0; |
---|
304 | } else |
---|
305 | { |
---|
306 | if (!nfs_server->get(pk)) |
---|
307 | { |
---|
308 | nfs_disconnect(); |
---|
309 | return 0; |
---|
310 | } else |
---|
311 | { |
---|
312 | int32_t size; |
---|
313 | if (pk.read((uint8_t *)&size,4)!=4) |
---|
314 | { |
---|
315 | dprintf("disconnected on filesize\n"); |
---|
316 | nfs_disconnect(); |
---|
317 | } |
---|
318 | else return lltl(size); |
---|
319 | } |
---|
320 | } |
---|
321 | } |
---|
322 | return 0; |
---|
323 | } |
---|
324 | |
---|
325 | nfs_file::~nfs_file() |
---|
326 | { |
---|
327 | flush_writes(); |
---|
328 | if (local) delete local; |
---|
329 | else if (nfs_server && !open_failure()) |
---|
330 | { |
---|
331 | packet pk; |
---|
332 | pk.write_uint8(NFS_CLOSE); |
---|
333 | pk.write_uint32(nfs_fd); |
---|
334 | dprintf("close %d\n",nfs_fd); |
---|
335 | if (!nfs_server->send(pk)) |
---|
336 | { |
---|
337 | dprintf("disconnected on close\n"); |
---|
338 | nfs_disconnect(); |
---|
339 | } |
---|
340 | } |
---|
341 | } |
---|
342 | |
---|
343 | |
---|
344 | |
---|
345 | |
---|