Credit Andrew fix Alpha Bug of BT558 + small cleanup
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / renderfarmfsclient.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 // Disable 64 bit indirections so we can override both functions.
23 #undef _LARGEFILE64_SOURCE
24 #undef _LARGEFILE_SOURCE
25 #undef _FILE_OFFSET_BITS
26
27 #include "mutex.h"
28 #include "renderfarm.h"
29 #include "renderfarmclient.h"
30 #include "renderfarmfsclient.h"
31 #include "renderfarmfsserver.h"
32 #include "units.h"
33
34 #include <dlfcn.h>
35 #include <fcntl.h>
36 #include <stdarg.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <sys/stat.h>
40 #include <unistd.h>
41
42
43 #define DEBUG 0
44
45 // These are hacks to get all the file I/O libraries to transparently
46 // go over the network without rewriting them.
47
48
49 extern "C"
50 {
51
52
53
54
55
56
57
58 RenderFarmFSClient *renderfarm_fs_global = 0;
59
60
61 // open doesn't seem overridable
62 // int open (__const char *path, int flags, ...)
63 // {
64 //      static int (*func)(__const char *__file, int __oflag) = 0;
65 //      int result = -1;
66 // printf("open %s\n", path);
67 //
68 //      if (!func)
69 //      func = (int(*)(const char *path, int flags))dlsym(RTLD_NEXT, "open");
70 //
71 //      result = (*func)(path, flags);
72 //      return result;
73 // }
74
75
76 FILE* fopen(const char *path, const char *mode)
77 {
78         static FILE* (*func)(const char *path, const char *mode) = 0;
79 // This pointer is meaningless except on the server.
80         FILE *result = 0;
81
82         if (!func)
83         func = (FILE*(*)(const char *path, const char *mode))dlsym(RTLD_NEXT, "fopen");
84
85 // VFS path
86         if(!strncmp(path, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
87         {
88                 renderfarm_fs_global->lock();
89                 result = renderfarm_fs_global->fopen(path, mode);
90                 renderfarm_fs_global->unlock();
91         }
92         else
93                 result = (*func)(path, mode);
94
95     return result;
96 }
97
98 FILE* fopen64(const char *path, const char *mode)
99 {
100         static FILE* (*func)(const char *path, const char *mode) = 0;
101 // This pointer is meaningless except on the server.
102         FILE *result = 0;
103
104         if (!func)
105         func = (FILE*(*)(const char *path, const char *mode))dlsym(RTLD_NEXT, "fopen64");
106
107 // VFS path
108         if(!strncmp(path, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
109         {
110                 renderfarm_fs_global->lock();
111                 result = renderfarm_fs_global->fopen(path, mode);
112                 renderfarm_fs_global->unlock();
113         }
114         else
115                 result = (*func)(path, mode);
116
117     return result;
118 }
119
120
121
122 int fclose(FILE *file)
123 {
124         static int (*func)(FILE *) = 0;
125         int result = 0, done = 0;
126         if(!func)
127         func = (int(*)(FILE *))dlsym(RTLD_NEXT, "fclose");
128 //printf("fclose\n");
129
130         if(renderfarm_fs_global)
131         {
132                 renderfarm_fs_global->lock();
133                 if(renderfarm_fs_global->is_open(file))
134                 {
135                         result = renderfarm_fs_global->fclose(file);
136                         done = 1;
137                 }
138                 renderfarm_fs_global->unlock();
139         }
140
141         if(!done) result = (*func)(file);
142         return result;
143 }
144
145 int fileno (FILE *stream)
146 {
147         static int (*func)(FILE *) = 0;
148         int result = -1;
149         if(!func)
150         func = (int(*)(FILE *))dlsym(RTLD_NEXT, "fileno");
151         if(renderfarm_fs_global)
152         {
153                 renderfarm_fs_global->lock();
154                 if(renderfarm_fs_global->is_open(stream))
155                 {
156                         result = renderfarm_fs_global->fileno(stream);
157                 }
158                 renderfarm_fs_global->unlock();
159         }
160         else
161                 result = (*func)(stream);
162         return result;
163 }
164
165 // int fflush(FILE *file)
166 // {
167 //      static int (*func)(FILE *) = 0;
168 //      int result = 0, done = 0;
169 //      if(!func)
170 //      func = (int(*)(FILE *))dlsym(RTLD_NEXT, "fflush");
171 // //printf("fflush\n");
172 //
173 //      renderfarm_fs_global->lock();
174 //      if(renderfarm_fs_global->is_open(file))
175 //      {
176 //              result = renderfarm_fs_global->fflush(file);
177 //              done = 1;
178 //      }
179 //      renderfarm_fs_global->unlock();
180 //
181 //      if(!done) result = (*func)(file);
182 //      return result;
183 // }
184
185 int remove (__const char *__filename)
186 {
187         static int (*func)(__const char *) = 0;
188         int result = 0;
189         if(!func)
190         func = (int(*)(__const char *))dlsym(RTLD_NEXT, "remove");
191 //printf("remove\n");
192
193 // VFS path
194         if(!strncmp(__filename, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
195         {
196                 renderfarm_fs_global->lock();
197                 result = renderfarm_fs_global->remove(__filename);
198                 renderfarm_fs_global->unlock();
199         }
200         else
201                 result = (*func)(__filename);
202
203         return result;
204 }
205
206 int rename (__const char *__old, __const char *__new)
207 {
208         static int (*func)(__const char *, __const char *) = 0;
209         int result = 0;
210         if(!func)
211         func = (int(*)(__const char *, __const char *))dlsym(RTLD_NEXT, "rename");
212 //printf("rename\n");
213
214 // VFS path
215         if(!strncmp(__old, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
216         {
217                 renderfarm_fs_global->lock();
218                 result = renderfarm_fs_global->rename(__old, __new);
219                 renderfarm_fs_global->unlock();
220         }
221         else
222                 result = (*func)(__old, __new);
223
224         return result;
225 }
226
227 int fgetc (FILE *__stream)
228 {
229         static int (*func)(FILE *) = 0;
230         int result = 0, done = 0;
231         if(!func)
232         func = (int(*)(FILE *))dlsym(RTLD_NEXT, "fgetc");
233 //printf("fgetc\n");
234
235         if(renderfarm_fs_global)
236         {
237                 renderfarm_fs_global->lock();
238                 if(renderfarm_fs_global->is_open(__stream))
239                 {
240                         result = renderfarm_fs_global->fgetc(__stream);
241                         done = 1;
242                 }
243                 renderfarm_fs_global->unlock();
244         }
245
246         if(!done) result = (*func)(__stream);
247         return result;
248 }
249
250 int getc (FILE *__stream)
251 {
252         return fgetc(__stream);
253 }
254
255 int fputc (int __c, FILE *__stream)
256 {
257         static int (*func)(int, FILE *) = 0;
258         int result = 0, done = 0;
259         if(!func)
260         func = (int(*)(int, FILE *))dlsym(RTLD_NEXT, "fputc");
261 //printf("fputc\n");
262
263         if(renderfarm_fs_global)
264         {
265                 renderfarm_fs_global->lock();
266                 if(renderfarm_fs_global->is_open(__stream))
267                 {
268                         result = renderfarm_fs_global->fputc(__c, __stream);
269                         done = 1;
270                 }
271                 renderfarm_fs_global->unlock();
272         }
273
274         if(!done) result = (*func)(__c, __stream);
275         return result;
276 }
277
278 int putc (int __c, FILE *__stream)
279 {
280         return fputc(__c, __stream);
281 }
282
283 size_t fread (void *__restrict __ptr, size_t __size,
284                      size_t __n, FILE *__restrict __stream)
285 {
286         static int (*func)(void *, size_t, size_t, FILE *) = 0;
287         size_t result = 0;
288         int done = 0;
289         if(!func)
290         func = (int(*)(void *, size_t, size_t, FILE *))dlsym(RTLD_NEXT, "fread");
291 //printf("fread\n");
292
293         if(renderfarm_fs_global)
294         {
295                 renderfarm_fs_global->lock();
296                 if(renderfarm_fs_global->is_open(__stream))
297                 {
298                         result = renderfarm_fs_global->fread(__ptr, __size, __n, __stream);
299                         done = 1;
300                 }
301                 renderfarm_fs_global->unlock();
302         }
303
304         if(!done) result = (*func)(__ptr, __size, __n, __stream);
305
306         return result;
307 }
308
309 size_t fwrite (__const void *__restrict __ptr, size_t __size,
310                       size_t __n, FILE *__restrict __s)
311 {
312         static int (*func)(__const void *, size_t, size_t, FILE *) = 0;
313         size_t result = 0;
314         int done = 0;
315         if(!func)
316         func = (int(*)(__const void *, size_t, size_t, FILE *))dlsym(RTLD_NEXT, "fwrite");
317
318         if(renderfarm_fs_global)
319         {
320                 renderfarm_fs_global->lock();
321                 if(renderfarm_fs_global->is_open(__s))
322                 {
323                         result = renderfarm_fs_global->fwrite(__ptr, __size, __n, __s);
324                         done = 1;
325                 }
326                 renderfarm_fs_global->unlock();
327         }
328
329         if(!done) result = (*func)(__ptr, __size, __n, __s);
330
331         return result;
332 }
333
334 int fseek (FILE *__stream, long int __off, int __whence)
335 {
336         static int (*func)(FILE *, long int, int) = 0;
337         int result = 0;
338         int done = 0;
339         if(!func)
340         func = (int(*)(FILE *, long int, int))dlsym(RTLD_NEXT, "fseek");
341 //printf("fseek\n");
342
343         if(renderfarm_fs_global)
344         {
345                 renderfarm_fs_global->lock();
346                 if(renderfarm_fs_global->is_open(__stream))
347                 {
348                         result = renderfarm_fs_global->fseek(__stream, __off, __whence);
349                         done = 1;
350                 }
351                 renderfarm_fs_global->unlock();
352         }
353
354         if(!done) result = (*func)(__stream, __off, __whence);
355
356         return result;
357 }
358
359 int fseeko64 (FILE *__stream, __off64_t __off, int __whence)
360 {
361         static int (*func)(FILE *, __off64_t, int) = 0;
362         int result = 0;
363         int done = 0;
364         if(!func)
365         func = (int(*)(FILE *, __off64_t, int))dlsym(RTLD_NEXT, "fseeko64");
366 //printf("fseeko64\n");
367
368         if(renderfarm_fs_global)
369         {
370                 renderfarm_fs_global->lock();
371                 if(renderfarm_fs_global->is_open(__stream))
372                 {
373                         result = renderfarm_fs_global->fseek(__stream, __off, __whence);
374                         done = 1;
375                 }
376                 renderfarm_fs_global->unlock();
377         }
378
379         if(!done) result = (*func)(__stream, __off, __whence);
380
381         return result;
382 }
383
384 long int ftell (FILE *__stream)
385 {
386         static long int (*func)(FILE *) = 0;
387         int result = 0;
388         int done = 0;
389         if(!func)
390         func = (long int(*)(FILE *))dlsym(RTLD_NEXT, "ftell");
391 //printf("ftell\n");
392
393         if(renderfarm_fs_global)
394         {
395                 renderfarm_fs_global->lock();
396                 if(renderfarm_fs_global->is_open(__stream))
397                 {
398                         result = renderfarm_fs_global->ftell(__stream);
399                         done = 1;
400                 }
401                 renderfarm_fs_global->unlock();
402         }
403
404         if(!done) result = (*func)(__stream);
405
406         return result;
407 }
408
409 __off64_t ftello64 (FILE *__stream)
410 {
411         static __off64_t (*func)(FILE *) = 0;
412         __off64_t result = 0;
413         int done = 0;
414         if(!func)
415         func = (__off64_t(*)(FILE *))dlsym(RTLD_NEXT, "ftello64");
416
417         if(renderfarm_fs_global)
418         {
419                 renderfarm_fs_global->lock();
420                 if(renderfarm_fs_global->is_open(__stream))
421                 {
422                         result = renderfarm_fs_global->ftell(__stream);
423                         done = 1;
424                 }
425                 renderfarm_fs_global->unlock();
426         }
427
428         if(!done) result = (*func)(__stream);
429
430         return result;
431         return (*func)(__stream);
432 }
433
434
435 // Glibc inlines the stat functions and redirects them to __xstat functions
436 int __xstat (int __ver, __const char *__filename,
437                     struct stat *__stat_buf)
438 {
439         static int (*func)(int __ver, __const char *__filename,
440                     struct stat *__stat_buf) = 0;
441
442 // This pointer is meaningless except on the server.
443         int result = 0;
444
445         if (!func)
446         func = (int(*)(int __ver, __const char *__filename,
447                     struct stat *__stat_buf))dlsym(RTLD_NEXT, "__xstat");
448
449 // VFS path
450         if(!strncmp(__filename, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
451         {
452                 renderfarm_fs_global->lock();
453                 result = renderfarm_fs_global->stat(__filename, __stat_buf);
454                 renderfarm_fs_global->unlock();
455         }
456         else
457         {
458                 result = (*func)(__ver, __filename, __stat_buf);
459         }
460
461     return result;
462 }
463
464 int __xstat64 (int __ver, __const char *__filename,
465                       struct stat64 *__stat_buf)
466 {
467         static int (*func)(int __ver, __const char *__restrict __file,
468                  struct stat64 *__restrict __buf) = 0;
469 // This pointer is meaningless except on the server.
470         int result = 0;
471
472         if (!func)
473         func = (int(*)(int __ver, __const char *__restrict __file,
474                                         struct stat64 *__restrict __buf))dlsym(RTLD_NEXT, "__xstat64");
475
476 // VFS path
477         if(!strncmp(__filename, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
478         {
479                 renderfarm_fs_global->lock();
480                 result = renderfarm_fs_global->stat64(__filename, __stat_buf);
481                 renderfarm_fs_global->unlock();
482         }
483         else
484                 result = (*func)(__ver, __filename, __stat_buf);
485
486     return result;
487 }
488
489 char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
490 {
491         static char* (*func)(char *__restrict __s, int __n, FILE *__restrict __stream) = 0;
492         char *result = 0;
493         int done = 0;
494         if(!func)
495         func = (char*(*)(char *__restrict __s, int __n, FILE *__restrict __stream))dlsym(RTLD_NEXT, "fgets");
496
497         if(renderfarm_fs_global)
498         {
499                 renderfarm_fs_global->lock();
500                 if(renderfarm_fs_global->is_open(__stream))
501                 {
502                         result = renderfarm_fs_global->fgets(__s, __n, __stream);
503                         done = 1;
504                 }
505                 renderfarm_fs_global->unlock();
506         }
507
508         if(!done) result = (*func)(__s, __n, __stream);
509
510         return result;
511 }
512
513 int fscanf (FILE *__restrict __stream,
514                    __const char *__restrict __format, ...)
515 {
516         int result = 0;
517         int done = 0;
518         va_list ap;
519         va_start(ap, __format);
520
521         if(renderfarm_fs_global)
522         {
523                 renderfarm_fs_global->lock();
524                 if(renderfarm_fs_global->is_open(__stream))
525                 {
526 // Since this is currently only used in one place in dcraw, leave it blank.
527 // The future implementation may just read until the next \n and scan the string.
528                         result = renderfarm_fs_global->fscanf(__stream, __format, ap);
529                         done = 1;
530                 }
531                 renderfarm_fs_global->unlock();
532         }
533
534         if(!done) result = vfscanf(__stream, __format, ap);
535         return result;
536 }
537
538
539
540
541
542
543
544
545
546
547 }
548
549
550
551
552
553
554
555
556
557
558
559
560 RenderFarmFSClient::RenderFarmFSClient(RenderFarmClientThread *client)
561 {
562         mutex_lock = new Mutex("RenderFarmFSClient::mutex_lock");
563         this->client = client;
564 }
565
566 RenderFarmFSClient::~RenderFarmFSClient()
567 {
568         delete mutex_lock;
569 // Must not access filesystem until we get here
570         renderfarm_fs_global = 0;
571 }
572
573 void RenderFarmFSClient::initialize()
574 {
575         renderfarm_fs_global = this;
576 }
577
578 void RenderFarmFSClient::lock()
579 {
580         mutex_lock->lock("RenderFarmFSClient::lock");
581 }
582
583 void RenderFarmFSClient::unlock()
584 {
585         mutex_lock->unlock();
586 }
587
588 int RenderFarmFSClient::is_open(FILE *ptr)
589 {
590         for(int i = 0; i < files.total; i++)
591                 if(files.values[i] == ptr) return 1;
592         return 0;
593 }
594
595 void RenderFarmFSClient::set_open(FILE *ptr, int64_t pointer)
596 {
597         files.append(ptr);
598         if(sizeof(FILE*) == 4)
599                 pointers.append(pointer);
600 }
601
602 void RenderFarmFSClient::unset_open(FILE *ptr, int64_t pointer)
603 {
604         files.remove(ptr);
605         if(sizeof(FILE*) == 4)
606                 pointers.remove(pointer);
607 }
608
609 int64_t RenderFarmFSClient::get_64(FILE *ptr)
610 {
611         if(sizeof(FILE*) == 4)
612         {
613                 for(int i = 0; i < files.total; i++)
614                 {
615                         if(files.values[i] == ptr)
616                                 return pointers.values[i];
617                 }
618         }
619         else
620                 return Units::ptr_to_int64(ptr);
621
622         printf("RenderFarmFSClient::get_64 file %p not found\n", ptr);
623         return 0;
624 }
625
626
627 FILE* RenderFarmFSClient::fopen(const char *path, const char *mode)
628 {
629 if(DEBUG)
630 printf("RenderFarmFSClient::fopen 1\n");
631         int len = strlen(path) - strlen(RENDERFARM_FS_PREFIX) + strlen(mode) + 2;
632         char *buffer = new char[len];
633         FILE *file = 0;
634         int64_t file_int64;
635         strcpy(buffer, path + strlen(RENDERFARM_FS_PREFIX));
636         strcpy(buffer + strlen(buffer) + 1, mode);
637
638
639         client->lock("RenderFarmFSClient::fopen");
640         if(!client->send_request_header(RENDERFARM_FOPEN,
641                 len))
642         {
643                 if(client->write_socket(buffer, len, RENDERFARM_TIMEOUT) == len)
644                 {
645                         unsigned char data[8];
646                         if(client->read_socket((char*)data, 8, RENDERFARM_TIMEOUT) == 8)
647                         {
648                                 file_int64 = READ_INT64(data);
649                                 file = (FILE*)Units::int64_to_ptr(file_int64);
650                         }
651                 }
652         }
653         client->unlock();
654         if(file) set_open(file, file_int64);
655         delete [] buffer;
656
657 if(DEBUG)
658 printf("RenderFarmFSClient::fopen path=%s mode=%s file=%p\n", path, mode, file);
659
660         return file;
661 }
662
663 int RenderFarmFSClient::fclose(FILE *file)
664 {
665         int result = 0;
666         unsigned char datagram[8];
667         int i = 0;
668         int64_t file_int64 = get_64(file);
669         STORE_INT64(file_int64);
670
671         client->lock("RenderFarmFSClient::fclose");
672         if(!client->send_request_header(RENDERFARM_FCLOSE, 8))
673         {
674                 if(client->write_socket((char*)datagram, 8, RENDERFARM_TIMEOUT) == 8)
675                         result = 0;
676                 else
677                         result = -1;
678         }
679         else
680                 result = -1;
681         client->unlock();
682         unset_open(file, file_int64);
683 if(DEBUG)
684 printf("RenderFarmFSClient::fclose file=%p\n", file);
685         return result;
686 }
687
688 int RenderFarmFSClient::fileno(FILE *file)
689 {
690 if(DEBUG)
691 printf("RenderFarmFSClient::fileno file=%p\n", file);
692         int result = 0;
693         unsigned char datagram[8];
694         int i = 0;
695         int64_t file_int64 = get_64(file);
696         STORE_INT64(file_int64);
697
698         client->lock("RenderFarmFSClient::fileno");
699         if(!client->send_request_header(RENDERFARM_FILENO, 8))
700         {
701                 if(client->write_socket((char*)datagram, 8, RENDERFARM_TIMEOUT) == 8)
702                 {
703                         unsigned char data[4];
704                         if(client->read_socket((char*)data, 4, RENDERFARM_TIMEOUT) == 4)
705                         {
706                                 result = READ_INT32(data);
707                         }
708                 }
709                 else
710                         result = -1;
711         }
712         else
713                 result = -1;
714         client->unlock();
715 if(DEBUG)
716 printf("RenderFarmFSClient::fileno file=%p result=%d\n", file, result);
717         return result;
718 }
719
720 int RenderFarmFSClient::remove (__const char *__filename)
721 {
722         int result = 0;
723         int len = strlen(__filename) + 1;
724         char *datagram = new char[len];
725         strcpy(datagram, __filename);
726
727         client->lock("RenderFarmFSClient::remove");
728         if(!client->send_request_header(RENDERFARM_REMOVE, len))
729         {
730                 if(client->write_socket(datagram, len, RENDERFARM_TIMEOUT) != len)
731                         result = -1;
732                 else
733                         result = 0;
734         }
735         else
736                 result = -1;
737         client->unlock();
738
739         delete [] datagram;
740 if(DEBUG)
741 printf("RenderFarmFSClient::remove path=%s\n", __filename);
742         return result;
743 }
744
745 int RenderFarmFSClient::rename (__const char *__old, __const char *__new)
746 {
747         int result = 0;
748         int len = strlen(__old) + 1 + strlen(__new) + 1;
749         char *datagram = new char[len];
750         strcpy(datagram, __old);
751         strcpy(datagram + strlen(__old) + 1, __new);
752
753         client->lock("RenderFarmFSClient::rename");
754         if(!client->send_request_header(RENDERFARM_RENAME, len))
755         {
756                 if(client->write_socket(datagram, len, RENDERFARM_TIMEOUT) != len)
757                         result = -1;
758                 else
759                         result = 0;
760         }
761         else
762                 result = -1;
763         client->unlock();
764
765         delete [] datagram;
766 if(DEBUG)
767 printf("RenderFarmFSClient::remove old=%s new=%s\n", __old, __new);
768         return result;
769 }
770
771 int RenderFarmFSClient::fgetc (FILE *__stream)
772 {
773 if(DEBUG)
774 printf("RenderFarmFSClient::fgetc 1\n");
775         int result = 0;
776         unsigned char datagram[8];
777         int i = 0;
778         int64_t file_int64 = get_64(__stream);
779         STORE_INT64(file_int64);
780
781         client->lock("RenderFarmFSClient::fgetc");
782         if(!client->send_request_header(RENDERFARM_FGETC, 8))
783         {
784                 if(client->write_socket((char*)datagram, 8, RENDERFARM_TIMEOUT) != 8)
785                         result = -1;
786                 else
787                 {
788                         if(client->read_socket((char*)datagram, 1, RENDERFARM_TIMEOUT) != 1)
789                                 result = -1;
790                         else
791                         {
792                                 result = datagram[0];
793                         }
794                 }
795         }
796         else
797                 result = -1;
798         client->unlock();
799 if(DEBUG)
800 printf("RenderFarmFSClient::fgetc file=%p result=%02x\n", __stream, result);
801
802         return result;
803 }
804
805 int RenderFarmFSClient::fputc (int __c, FILE *__stream)
806 {
807 if(DEBUG)
808 printf("RenderFarmFSClient::fputc 1\n");
809         int result = 0;
810         unsigned char datagram[9];
811         int i = 0;
812         int64_t file_int64 = get_64(__stream);
813         STORE_INT64(file_int64);
814         datagram[i++] = __c;
815
816         client->lock("RenderFarmFSClient::fputc");
817         if(!client->send_request_header(RENDERFARM_FPUTC, 9))
818         {
819                 if(client->write_socket((char*)datagram, 9, RENDERFARM_TIMEOUT) != 9)
820                         result = -1;
821                 else
822                         result = __c;
823         }
824         else
825                 result = -1;
826         client->unlock();
827 if(DEBUG)
828 printf("RenderFarmFSClient::fputc file=%p result=%02x\n", __stream, result);
829
830         return result;
831 }
832
833 int RenderFarmFSClient::fscanf(FILE *__restrict stream, const char *__restrict format, va_list ap)
834 {
835         char string[BCTEXTLEN];
836         fgets (string, BCTEXTLEN, stream);
837         return 0;
838 }
839
840 char* RenderFarmFSClient::fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
841 {
842         char *result = 0;
843         int bytes = 0;
844         unsigned char datagram[12];
845         int i = 0;
846         int64_t file_int64 = get_64(__stream);
847         STORE_INT64(file_int64);
848         STORE_INT32(__n);
849
850         client->lock("RenderFarmFSClient::fgets");
851         if(!client->send_request_header(RENDERFARM_FGETS, 12))
852         {
853                 if(client->write_socket((char*)datagram, 12, RENDERFARM_TIMEOUT) == 12)
854                 {
855 // fgets bytes to follow
856                         if(client->read_socket((char*)datagram, 4, RENDERFARM_TIMEOUT) == 4)
857                         {
858 // fgets data
859                                 bytes = READ_INT32(datagram);
860                                 if(bytes)
861                                 {
862                                         if(client->read_socket((char*)__s, bytes, RENDERFARM_TIMEOUT) == bytes)
863                                         {
864                                                 result = __s;
865                                         }
866                                 }
867                         }
868                 }
869         }
870         else
871                 result = 0;
872         client->unlock();
873 if(DEBUG)
874 printf("RenderFarmFSClient::fgets file=%p string=%p size=%d bytes=%p\n",
875 __stream, __s, bytes, bytes);
876
877         return result;
878 }
879
880
881 size_t RenderFarmFSClient::fread (void *__restrict __ptr, size_t __size,
882                      size_t __n, FILE *__restrict __stream)
883 {
884         size_t result = 0;
885         unsigned char datagram[16];
886         int i = 0;
887         int64_t file_int64 = get_64(__stream);
888         STORE_INT64(file_int64);
889         STORE_INT32(__size);
890         STORE_INT32(__n);
891
892         client->lock("RenderFarmFSClient::fread");
893         if(!client->send_request_header(RENDERFARM_FREAD, 16))
894         {
895                 if(client->write_socket((char*)datagram, 16, RENDERFARM_TIMEOUT) != 16)
896                         result = 0;
897                 else
898                 {
899 // fread result
900                         if(client->read_socket((char*)datagram, 4, RENDERFARM_TIMEOUT) != 4)
901                                 result = 0;
902                         else
903                         {
904 // fread data
905                                 result = READ_INT32(datagram);
906                                 if(client->read_socket((char*)__ptr, __size * result, RENDERFARM_TIMEOUT) !=
907                                         __size * result)
908                                         result = 0;
909                         }
910                 }
911         }
912         else
913                 result = 0;
914         client->unlock();
915 if(DEBUG)
916 printf("RenderFarmFSClient::fread file=%p size=%d num=%d result=%d\n",
917 __stream, __size, __n, result);
918
919         return result;
920 }
921
922 size_t RenderFarmFSClient::fwrite (__const void *__restrict __ptr, size_t __size,
923                       size_t __n, FILE *__restrict __s)
924 {
925 if(DEBUG)
926 printf("RenderFarmFSClient::fwrite 1\n");
927         size_t result = 0;
928         unsigned char datagram[16];
929         int i = 0;
930         int64_t file_int64 = get_64(__s);
931         STORE_INT64(file_int64);
932         STORE_INT32(__size);
933         STORE_INT32(__n);
934
935         client->lock("RenderFarmFSClient::fwrite");
936         if(!client->send_request_header(RENDERFARM_FWRITE, 16))
937         {
938                 if(client->write_socket((char*)datagram, 16, RENDERFARM_TIMEOUT) != 16)
939                         result = 0;
940                 else
941                 {
942 // fwrite data
943                         if(client->write_socket((char*)__ptr, __size * __n, RENDERFARM_TIMEOUT) !=
944                                 __size * __n)
945                         result = 0;
946                         else
947                         {
948 // fwrite result
949                                 if(client->read_socket((char*)datagram, 4, RENDERFARM_TIMEOUT) != 4)
950                                         result = 0;
951                                 else
952                                 {
953                                         result = READ_INT32(datagram);
954                                 }
955                         }
956                 }
957         }
958         else
959                 result = 0;
960         client->unlock();
961 if(DEBUG)
962 printf("RenderFarmFSClient::fwrite file=%p size=%d num=%d result=%d\n",
963 __s, __size, __n, result);
964
965         return result;
966 }
967
968 int RenderFarmFSClient::fseek (FILE *__stream, int64_t __off, int __whence)
969 {
970 if(DEBUG)
971 printf("RenderFarmFSClient::fseek 1\n");
972         int result = 0;
973         unsigned char datagram[20];
974         int i = 0;
975         int64_t file_int64 = get_64(__stream);
976         STORE_INT64(file_int64);
977         STORE_INT64(__off);
978         STORE_INT32(__whence);
979
980 // printf("RenderFarmFSClient::fseek %p %llx datagram=%02x%02x%02x%02x%02x%02x%02x%02x\n",
981 // __stream, file_int64, datagram[0], datagram[1], datagram[2], datagram[3], datagram[4], datagram[5], datagram[6], datagram[7]);
982         client->lock("RenderFarmFSClient::fseek");
983         if(!client->send_request_header(RENDERFARM_FSEEK, 20))
984         {
985                 if(client->write_socket((char*)datagram, 20, RENDERFARM_TIMEOUT) != 20)
986                         result = -1;
987                 else
988                 {
989                         if(client->read_socket((char*)datagram, 4, RENDERFARM_TIMEOUT) != 4)
990                                 result = -1;
991                         else
992                                 result = READ_INT32(datagram);
993                 }
994         }
995         else
996                 result = -1;
997         client->unlock();
998 if(DEBUG)
999 printf("RenderFarmFSClient::fseek stream=%p offset=%jd whence=%d result=%d\n",
1000 __stream, __off, __whence, result);
1001         return result;
1002 }
1003
1004 int64_t RenderFarmFSClient::ftell (FILE *__stream)
1005 {
1006         int64_t result = 0;
1007         unsigned char datagram[8];
1008         int i = 0;
1009         int64_t file_int64 = get_64(__stream);
1010         STORE_INT64(file_int64);
1011
1012         client->lock("RenderFarmFSClient::ftell");
1013         if(!client->send_request_header(RENDERFARM_FTELL, 8))
1014         {
1015                 if(client->write_socket((char*)datagram, 8, RENDERFARM_TIMEOUT) != 8)
1016                         result = -1;
1017                 else
1018                 {
1019                         if(client->read_socket((char*)datagram, 8, RENDERFARM_TIMEOUT) != 8)
1020                                 result = -1;
1021                         else
1022                                 result = READ_INT64(datagram);
1023                 }
1024         }
1025         else
1026                 result = -1;
1027         client->unlock();
1028 if(DEBUG)
1029 printf("RenderFarmFSClient::fseek stream=%p result=%jd\n",
1030 __stream, result);
1031         return result;
1032 }
1033
1034 int RenderFarmFSClient::stat (__const char *__restrict __file,
1035                  struct stat *__restrict __buf)
1036 {
1037         int len = strlen(__file) + 1;
1038         int result = 0;
1039
1040         client->lock("RenderFarmFSClient::stat");
1041         if(!client->send_request_header(RENDERFARM_STAT, len))
1042         {
1043                 if(client->write_socket((char*)__file + strlen(RENDERFARM_FS_PREFIX), len, RENDERFARM_TIMEOUT) == len)
1044                 {
1045                         if(client->read_socket((char*)__buf, sizeof(struct stat), RENDERFARM_TIMEOUT) == sizeof(struct stat))
1046                         {
1047                                 ;
1048                         }
1049                         else
1050                                 result = 1;
1051                 }
1052                 else
1053                         result = 1;
1054         }
1055         else
1056                 result = 1;
1057         client->unlock();
1058 if(DEBUG)
1059 printf("RenderFarmFSClient::stat path=%s\n", __file);
1060
1061         return result;
1062 }
1063
1064
1065
1066 int RenderFarmFSClient::stat64 (__const char *__restrict __file,
1067                    struct stat64 *__restrict __buf)
1068 {
1069         int len = strlen(__file) + 1;
1070         int result = 0;
1071         bzero(__buf, sizeof(struct stat64));
1072
1073         client->lock("RenderFarmFSClient::stat64");
1074         if(!client->send_request_header(RENDERFARM_STAT64, len))
1075         {
1076                 if(client->write_socket((char*)__file + strlen(RENDERFARM_FS_PREFIX), len, RENDERFARM_TIMEOUT) == len)
1077                 {
1078                         vfs_stat_t arg;
1079                         if(client->read_socket((char*)&arg, sizeof(arg), RENDERFARM_TIMEOUT) == sizeof(arg))
1080                         {
1081                                 __buf->st_dev = arg.dev;
1082 //                              __buf->__st_ino = arg.ino32;
1083                                 __buf->st_ino = arg.ino;
1084                                 __buf->st_mode = arg.mode;
1085                                 __buf->st_nlink = arg.nlink;
1086                                 __buf->st_uid = arg.uid;
1087                                 __buf->st_gid = arg.gid;
1088                                 __buf->st_rdev = arg.rdev;
1089                                 __buf->st_size = arg.size;
1090                                 __buf->st_blksize = arg.blksize;
1091                                 __buf->st_blocks = arg.blocks;
1092                                 __buf->st_atim.tv_sec = arg.atim;
1093                                 __buf->st_mtim.tv_sec = arg.mtim;
1094                                 __buf->st_ctim.tv_sec = arg.ctim;
1095                         }
1096                         else
1097                                 result = 1;
1098                 }
1099                 else
1100                         result = 1;
1101         }
1102         else
1103                 result = 1;
1104         client->unlock();
1105 if(DEBUG)
1106 printf("RenderFarmFSClient::stat64 path=%s\n", __file);
1107
1108         return result;
1109 }
1110
1111
1112