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