1 /*
2  * Copyright (C) 2016 Jakub Kruszona-Zawadzki, Core Technology Sp. z o.o.
3  *
4  * This file is part of MooseFS.
5  *
6  * MooseFS 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, version 2 (only).
9  *
10  * MooseFS is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with MooseFS; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA
18  * or visit http://www.gnu.org/licenses/gpl-2.0.html
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #define MMAP_ALLOC 1
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <sys/poll.h>
32 #include <syslog.h>
33 #include <time.h>
34 #include <limits.h>
35 #include <errno.h>
36 #include <pthread.h>
37 #ifdef MMAP_ALLOC
38 #include <sys/types.h>
39 #include <sys/mman.h>
40 #endif
41 #include <pwd.h>
42 #include <grp.h>
43 
44 #include "MFSCommunication.h"
45 #include "stats.h"
46 #include "sockets.h"
47 #include "strerr.h"
48 #include "md5.h"
49 #include "datapack.h"
50 // #include "dircache.h"
51 
52 #define CONNECT_TIMEOUT 2000
53 
54 typedef struct _threc {
55 	pthread_t thid;
56 	pthread_mutex_t mutex;
57 	pthread_cond_t cond;
58 	uint8_t *obuff;
59 	uint32_t obuffsize;
60 	uint32_t odataleng;
61 	uint8_t *ibuff;
62 	uint32_t ibuffsize;
63 	uint32_t idataleng;
64 
65 	uint8_t sent;		// packet was sent
66 	uint8_t status;		// receive status
67 	uint8_t rcvd;		// packet was received
68 	uint8_t waiting;	// thread is waiting for answer
69 
70 	uint32_t rcvd_cmd;
71 
72 	uint32_t packetid;	// thread number
73 	struct _threc *next;
74 } threc;
75 
76 /*
77 typedef struct _threc {
78 	pthread_t thid;
79 	pthread_mutex_t mutex;
80 	pthread_cond_t cond;
81 	uint8_t *buff;
82 	uint32_t buffsize;
83 	uint8_t sent;
84 	uint8_t status;
85 	uint8_t release;	// cond variable
86 	uint8_t waiting;
87 	uint32_t size;
88 	uint32_t cmd;
89 	uint32_t packetid;
90 	struct _threc *next;
91 } threc;
92 */
93 
94 
95 typedef struct _acquired_file {
96 	uint32_t inode;
97 	unsigned cnt:31; // open/close count
98 	unsigned dentry:1; // inode exists in dentry cache (can't be removed/reused)
99 	struct _acquired_file *next;
100 } acquired_file;
101 
102 #define DEFAULT_OUTPUT_BUFFSIZE 0x1000
103 #define DEFAULT_INPUT_BUFFSIZE 0x10000
104 
105 #define RECEIVE_TIMEOUT 10
106 
107 static threc *threchead=NULL;
108 
109 static acquired_file *afhead=NULL;
110 
111 static int fd;
112 static int disconnect;
113 static int donotsendsustainedinodes;
114 static time_t lastwrite;
115 static int sessionlost;
116 
117 static uint32_t maxretries;
118 
119 static pthread_t rpthid,npthid;
120 static pthread_mutex_t fdlock,reclock,aflock;
121 
122 static uint32_t sessionid;
123 static uint32_t masterversion;
124 
125 static char masterstrip[17];
126 static uint32_t masterip=0;
127 static uint16_t masterport=0;
128 static char srcstrip[17];
129 static uint32_t srcip=0;
130 
131 static uint8_t fterm;
132 
fs_getmasterlocation(uint8_t loc[14])133 void fs_getmasterlocation(uint8_t loc[14]) {
134 	pthread_mutex_lock(&fdlock);
135 	put32bit(&loc,masterip);
136 	put16bit(&loc,masterport);
137 	put32bit(&loc,sessionid);
138 	put32bit(&loc,masterversion);
139 	pthread_mutex_unlock(&fdlock);
140 }
141 
master_version(void)142 uint32_t master_version(void) {
143 	uint32_t mver;
144 	pthread_mutex_lock(&fdlock);
145 	mver = masterversion;
146 	pthread_mutex_unlock(&fdlock);
147 	return mver;
148 }
149 
fs_getsrcip()150 uint32_t fs_getsrcip() {
151 	uint32_t sip;
152 	pthread_mutex_lock(&fdlock);
153 	sip = srcip;
154 	pthread_mutex_unlock(&fdlock);
155 	return sip;
156 }
157 
158 enum {
159 	MASTER_CONNECTS = 0,
160 	MASTER_BYTESSENT,
161 	MASTER_BYTESRCVD,
162 	MASTER_PACKETSSENT,
163 	MASTER_PACKETSRCVD,
164 	STATNODES
165 };
166 
167 static void *statsptr[STATNODES];
168 
169 struct connect_args_t {
170 	char *bindhostname;
171 	char *masterhostname;
172 	char *masterportname;
173 	uint8_t meta;
174 	uint8_t clearpassword;
175 	char *info;
176 	char *subfolder;
177 	uint8_t *passworddigest;
178 };
179 
180 static struct connect_args_t connect_args;
181 
master_statsptr_init(void)182 void master_statsptr_init(void) {
183 	void *s;
184 	s = stats_get_subnode(NULL,"master",0,0);
185 	statsptr[MASTER_PACKETSRCVD] = stats_get_subnode(s,"packets_received",0,1);
186 	statsptr[MASTER_PACKETSSENT] = stats_get_subnode(s,"packets_sent",0,1);
187 	statsptr[MASTER_BYTESRCVD] = stats_get_subnode(s,"bytes_received",0,1);
188 	statsptr[MASTER_BYTESSENT] = stats_get_subnode(s,"bytes_sent",0,1);
189 	statsptr[MASTER_CONNECTS] = stats_get_subnode(s,"reconnects",0,1);
190 }
191 
master_stats_inc(uint8_t id)192 void master_stats_inc(uint8_t id) {
193 	if (id<STATNODES) {
194 		stats_counter_inc(statsptr[id]);
195 	}
196 }
197 
master_stats_add(uint8_t id,uint64_t s)198 void master_stats_add(uint8_t id,uint64_t s) {
199 	if (id<STATNODES) {
200 		stats_counter_add(statsptr[id],s);
201 	}
202 }
203 
204 const char* errtab[]={ERROR_STRINGS};
205 
mfs_strerror(uint8_t status)206 static inline const char* mfs_strerror(uint8_t status) {
207 	if (status>ERROR_MAX) {
208 		status=ERROR_MAX;
209 	}
210 	return errtab[status];
211 }
212 
fs_add_entry(uint32_t inode)213 void fs_add_entry(uint32_t inode) {
214 	acquired_file *afptr,**afpptr;
215 	pthread_mutex_lock(&aflock);
216 	afpptr = &afhead;
217 	while ((afptr=*afpptr)) {
218 		if (afptr->inode == inode) {
219 			afptr->dentry = 1;
220 			pthread_mutex_unlock(&aflock);
221 			return;
222 		}
223 		if (afptr->inode > inode) {
224 			break;
225 		}
226 		afpptr = &(afptr->next);
227 	}
228 	afptr = (acquired_file*)malloc(sizeof(acquired_file));
229 	afptr->inode = inode;
230 	afptr->cnt = 0;
231 	afptr->dentry = 1;
232 	afptr->next = *afpptr;
233 	*afpptr = afptr;
234 	pthread_mutex_unlock(&aflock);
235 }
236 
fs_forget_entry(uint32_t inode)237 void fs_forget_entry(uint32_t inode) {
238 	acquired_file *afptr,**afpptr;
239 	pthread_mutex_lock(&aflock);
240 	afpptr = &afhead;
241 	while ((afptr=*afpptr)) {
242 		if (afptr->inode == inode) {
243 			afptr->dentry = 0;
244 			if (afptr->cnt==0) {
245 				*afpptr = afptr->next;
246 				free(afptr);
247 			}
248 			pthread_mutex_unlock(&aflock);
249 			return;
250 		}
251 		afpptr = &(afptr->next);
252 	}
253 	pthread_mutex_unlock(&aflock);
254 }
255 
fs_inc_acnt(uint32_t inode)256 void fs_inc_acnt(uint32_t inode) {
257 	acquired_file *afptr,**afpptr;
258 	pthread_mutex_lock(&aflock);
259 	afpptr = &afhead;
260 	while ((afptr=*afpptr)) {
261 		if (afptr->inode==inode) {
262 			afptr->cnt++;
263 			pthread_mutex_unlock(&aflock);
264 			return;
265 		}
266 		if (afptr->inode>inode) {
267 			break;
268 		}
269 		afpptr = &(afptr->next);
270 	}
271 	afptr = (acquired_file*)malloc(sizeof(acquired_file));
272 	afptr->inode = inode;
273 	afptr->cnt = 1;
274 	afptr->dentry = 0;
275 	afptr->next = *afpptr;
276 	*afpptr = afptr;
277 	pthread_mutex_unlock(&aflock);
278 }
279 
fs_dec_acnt(uint32_t inode)280 void fs_dec_acnt(uint32_t inode) {
281 	acquired_file *afptr,**afpptr;
282 	pthread_mutex_lock(&aflock);
283 	afpptr = &afhead;
284 	while ((afptr=*afpptr)) {
285 		if (afptr->inode == inode) {
286 			if (afptr->cnt>0) {
287 				afptr->cnt--;
288 			}
289 			if (afptr->cnt==0 && afptr->dentry==0) {
290 				*afpptr = afptr->next;
291 				free(afptr);
292 			}
293 			pthread_mutex_unlock(&aflock);
294 			return;
295 		}
296 		afpptr = &(afptr->next);
297 	}
298 	pthread_mutex_unlock(&aflock);
299 }
300 
fs_get_my_threc()301 threc* fs_get_my_threc() {
302 	pthread_t mythid = pthread_self();
303 	threc *rec;
304 	pthread_mutex_lock(&reclock);
305 	for (rec = threchead ; rec ; rec=rec->next) {
306 		if (pthread_equal(rec->thid,mythid)) {
307 			pthread_mutex_unlock(&reclock);
308 			return rec;
309 		}
310 	}
311 	rec = malloc(sizeof(threc));
312 	rec->thid = mythid;
313 	pthread_mutex_init(&(rec->mutex),NULL);
314 	pthread_cond_init(&(rec->cond),NULL);
315 	rec->obuff = NULL;
316 	rec->ibuff = NULL;
317 	rec->obuffsize = 0;
318 	rec->ibuffsize = 0;
319 	rec->odataleng = 0;
320 	rec->idataleng = 0;
321 	rec->sent = 0;
322 	rec->status = 0;
323 	rec->rcvd = 0;
324 	rec->waiting = 0;
325 	rec->rcvd_cmd = 0;
326 	if (threchead==NULL) {
327 		rec->packetid = 1;
328 	} else {
329 		rec->packetid = threchead->packetid+1;
330 	}
331 	rec->next = threchead;
332 	//syslog(LOG_NOTICE,"mastercomm: create new threc (%"PRIu32")",rec->packetid);
333 	threchead = rec;
334 	pthread_mutex_unlock(&reclock);
335 	return rec;
336 }
337 
fs_get_threc_by_id(uint32_t packetid)338 threc* fs_get_threc_by_id(uint32_t packetid) {
339 	threc *rec;
340 	pthread_mutex_lock(&reclock);
341 	for (rec = threchead ; rec ; rec=rec->next) {
342 		if (rec->packetid==packetid) {
343 			pthread_mutex_unlock(&reclock);
344 			return rec;
345 		}
346 	}
347 	pthread_mutex_unlock(&reclock);
348 	return NULL;
349 }
350 
fs_output_buffer_init(threc * rec,uint32_t size)351 void fs_output_buffer_init(threc *rec,uint32_t size) {
352 	if (size>DEFAULT_OUTPUT_BUFFSIZE) {
353 #ifdef MMAP_ALLOC
354 		if (rec->obuff) {
355 			munmap((void*)(rec->obuff),rec->obuffsize);
356 		}
357 		rec->obuff = (void*)mmap(NULL,size,PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,-1,0);
358 #else
359 		if (rec->obuff) {
360 			free(rec->obuff);
361 		}
362 		rec->obuff = malloc(size);
363 #endif
364 		rec->obuffsize = size;
365 	} else if (rec->obuffsize!=DEFAULT_OUTPUT_BUFFSIZE) {
366 #ifdef MMAP_ALLOC
367 		if (rec->obuff) {
368 			munmap((void*)(rec->obuff),rec->obuffsize);
369 		}
370 		rec->obuff = (void*)mmap(NULL,DEFAULT_OUTPUT_BUFFSIZE,PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,-1,0);
371 #else
372 		if (rec->obuff) {
373 			free(rec->obuff);
374 		}
375 		rec->obuff = malloc(DEFAULT_OUTPUT_BUFFSIZE);
376 #endif
377 		rec->obuffsize = DEFAULT_OUTPUT_BUFFSIZE;
378 	}
379 	if (rec->obuff==NULL) {
380 		rec->obuffsize = 0;
381 	}
382 }
383 
fs_input_buffer_init(threc * rec,uint32_t size)384 void fs_input_buffer_init(threc *rec,uint32_t size) {
385 	if (size>DEFAULT_INPUT_BUFFSIZE) {
386 #ifdef MMAP_ALLOC
387 		if (rec->ibuff) {
388 			munmap((void*)(rec->ibuff),rec->ibuffsize);
389 		}
390 		rec->ibuff = (void*)mmap(NULL,size,PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,-1,0);
391 #else
392 		if (rec->ibuff) {
393 			free(rec->ibuff);
394 		}
395 		rec->ibuff = malloc(size);
396 #endif
397 		rec->ibuffsize = size;
398 	} else if (rec->ibuffsize!=DEFAULT_INPUT_BUFFSIZE) {
399 #ifdef MMAP_ALLOC
400 		if (rec->ibuff) {
401 			munmap((void*)(rec->ibuff),rec->ibuffsize);
402 		}
403 		rec->ibuff = (void*)mmap(NULL,DEFAULT_INPUT_BUFFSIZE,PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,-1,0);
404 #else
405 		if (rec->ibuff) {
406 			free(rec->ibuff);
407 		}
408 		rec->ibuff = malloc(DEFAULT_INPUT_BUFFSIZE);
409 #endif
410 		rec->ibuffsize = DEFAULT_INPUT_BUFFSIZE;
411 	}
412 	if (rec->ibuff==NULL) {
413 		rec->ibuffsize = 0;
414 	}
415 }
416 
fs_createpacket(threc * rec,uint32_t cmd,uint32_t size)417 uint8_t* fs_createpacket(threc *rec,uint32_t cmd,uint32_t size) {
418 	uint8_t *ptr;
419 	uint32_t hdrsize = size+4;
420 	pthread_mutex_lock(&(rec->mutex));	// make helgrind happy
421 	fs_output_buffer_init(rec,size+12);
422 	if (rec->obuff==NULL) {
423 		return NULL;
424 	}
425 	ptr = rec->obuff;
426 	put32bit(&ptr,cmd);
427 	put32bit(&ptr,hdrsize);
428 	put32bit(&ptr,rec->packetid);
429 	rec->odataleng = size+12;
430 	pthread_mutex_unlock(&(rec->mutex));	// make helgrind happy
431 	return ptr;
432 }
433 
fs_sendandreceive(threc * rec,uint32_t expected_cmd,uint32_t * answer_leng)434 const uint8_t* fs_sendandreceive(threc *rec,uint32_t expected_cmd,uint32_t *answer_leng) {
435 	uint32_t cnt;
436 	static uint8_t notsup = ERROR_ENOTSUP;
437 //	uint32_t size = rec->size;
438 
439 	for (cnt=0 ; cnt<maxretries ; cnt++) {
440 		pthread_mutex_lock(&fdlock);
441 		if (sessionlost) {
442 			pthread_mutex_unlock(&fdlock);
443 			return NULL;
444 		}
445 		if (fd==-1) {
446 			pthread_mutex_unlock(&fdlock);
447 			sleep(1+((cnt<30)?(cnt/3):10));
448 			continue;
449 		}
450 		//syslog(LOG_NOTICE,"threc(%"PRIu32") - sending ...",rec->packetid);
451 		pthread_mutex_lock(&(rec->mutex));	// make helgrind happy
452 		if (tcptowrite(fd,rec->obuff,rec->odataleng,1000)!=(int32_t)(rec->odataleng)) {
453 			syslog(LOG_WARNING,"tcp send error: %s",strerr(errno));
454 			disconnect = 1;
455 			pthread_mutex_unlock(&(rec->mutex));
456 			pthread_mutex_unlock(&fdlock);
457 			sleep(1+((cnt<30)?(cnt/3):10));
458 			continue;
459 		}
460 		rec->rcvd = 0;
461 		rec->sent = 1;
462 		pthread_mutex_unlock(&(rec->mutex));	// make helgrind happy
463 		master_stats_add(MASTER_BYTESSENT,rec->odataleng);
464 		master_stats_inc(MASTER_PACKETSSENT);
465 		lastwrite = time(NULL);
466 		pthread_mutex_unlock(&fdlock);
467 		// syslog(LOG_NOTICE,"master: lock: %"PRIu32,rec->packetid);
468 		pthread_mutex_lock(&(rec->mutex));
469 		while (rec->rcvd==0) {
470 			rec->waiting = 1;
471 			pthread_cond_wait(&(rec->cond),&(rec->mutex));
472 			rec->waiting = 0;
473 		}
474 		*answer_leng = rec->idataleng;
475 		// syslog(LOG_NOTICE,"master: unlocked: %"PRIu32,rec->packetid);
476 		// syslog(LOG_NOTICE,"master: command_info: %"PRIu32" ; reccmd: %"PRIu32,command_info,rec->cmd);
477 		if (rec->status!=0) {
478 			pthread_mutex_unlock(&(rec->mutex));
479 			sleep(1+((cnt<30)?(cnt/3):10));
480 			continue;
481 		}
482 		if (rec->rcvd_cmd==ANTOAN_UNKNOWN_COMMAND || rec->rcvd_cmd==ANTOAN_BAD_COMMAND_SIZE) {
483 			pthread_mutex_unlock(&(rec->mutex));
484 			*answer_leng = 1; // simulate error
485 			return &notsup; // return ERROR_ENOTSUP in this case
486 		}
487 		if (rec->rcvd_cmd!=expected_cmd) {
488 			pthread_mutex_unlock(&(rec->mutex));
489 			pthread_mutex_lock(&fdlock);
490 			disconnect = 1;
491 			pthread_mutex_unlock(&fdlock);
492 			sleep(1+((cnt<30)?(cnt/3):10));
493 			continue;
494 		}
495 		pthread_mutex_unlock(&(rec->mutex));
496 		//syslog(LOG_NOTICE,"threc(%"PRIu32") - received",rec->packetid);
497 		return rec->ibuff;
498 	}
499 	return NULL;
500 }
501 
fs_sendandreceive_any(threc * rec,uint32_t * received_cmd,uint32_t * answer_leng)502 const uint8_t* fs_sendandreceive_any(threc *rec,uint32_t *received_cmd,uint32_t *answer_leng) {
503 	uint32_t cnt;
504 //	uint32_t size = rec->size;
505 
506 	for (cnt=0 ; cnt<maxretries ; cnt++) {
507 		pthread_mutex_lock(&fdlock);
508 		if (sessionlost) {
509 			pthread_mutex_unlock(&fdlock);
510 			return NULL;
511 		}
512 		if (fd==-1) {
513 			pthread_mutex_unlock(&fdlock);
514 			sleep(1+((cnt<30)?(cnt/3):10));
515 			continue;
516 		}
517 		//syslog(LOG_NOTICE,"threc(%"PRIu32") - sending ...",rec->packetid);
518 		pthread_mutex_lock(&(rec->mutex));	// make helgrind happy
519 		if (tcptowrite(fd,rec->obuff,rec->odataleng,1000)!=(int32_t)(rec->odataleng)) {
520 			syslog(LOG_WARNING,"tcp send error: %s",strerr(errno));
521 			disconnect = 1;
522 			pthread_mutex_unlock(&(rec->mutex));
523 			pthread_mutex_unlock(&fdlock);
524 			sleep(1+((cnt<30)?(cnt/3):10));
525 			continue;
526 		}
527 		rec->rcvd = 0;
528 		rec->sent = 1;
529 		pthread_mutex_unlock(&(rec->mutex));	// make helgrind happy
530 		master_stats_add(MASTER_BYTESSENT,rec->odataleng);
531 		master_stats_inc(MASTER_PACKETSSENT);
532 		lastwrite = time(NULL);
533 		pthread_mutex_unlock(&fdlock);
534 		// syslog(LOG_NOTICE,"master: lock: %"PRIu32,rec->packetid);
535 		pthread_mutex_lock(&(rec->mutex));
536 		while (rec->rcvd==0) {
537 			rec->waiting = 1;
538 			pthread_cond_wait(&(rec->cond),&(rec->mutex));
539 			rec->waiting = 0;
540 		}
541 		*answer_leng = rec->idataleng;
542 		// syslog(LOG_NOTICE,"master: unlocked: %"PRIu32,rec->packetid);
543 		// syslog(LOG_NOTICE,"master: command_info: %"PRIu32" ; reccmd: %"PRIu32,command_info,rec->cmd);
544 		if (rec->status!=0) {
545 			pthread_mutex_unlock(&(rec->mutex));
546 			sleep(1+((cnt<30)?(cnt/3):10));
547 			continue;
548 		}
549 		*received_cmd = rec->rcvd_cmd;
550 		pthread_mutex_unlock(&(rec->mutex));
551 		//syslog(LOG_NOTICE,"threc(%"PRIu32") - received",rec->packetid);
552 		return rec->ibuff;
553 	}
554 	return NULL;
555 }
556 
557 //static inline const uint8_t* fs_sendandreceive(threc *rec,uint32_t expected_cmd,uint32_t *answer_leng) {
558 //	uint32_t *rcmd;
559 //	const uint8_t *rptr;
560 //	rptr = fs_commwithmaster(rec,&rcmd,answer_leng);
561 //	if (
562 //}
563 
564 /*
565 int fs_direct_connect() {
566 	int rfd;
567 	rfd = tcpsocket();
568 	if (tcpnumconnect(rfd,masterip,masterport)<0) {
569 		tcpclose(rfd);
570 		return -1;
571 	}
572 	master_stats_inc(MASTER_TCONNECTS);
573 	return rfd;
574 }
575 
576 void fs_direct_close(int rfd) {
577 	tcpclose(rfd);
578 }
579 
580 int fs_direct_write(int rfd,const uint8_t *buff,uint32_t size) {
581 	int rsize = tcptowrite(rfd,buff,size,60000);
582 	if (rsize==(int)size) {
583 		master_stats_add(MASTER_BYTESSENT,size);
584 	}
585 	return rsize;
586 }
587 
588 int fs_direct_read(int rfd,uint8_t *buff,uint32_t size) {
589 	int rsize = tcptoread(rfd,buff,size,60000);
590 	if (rsize>0) {
591 		master_stats_add(MASTER_BYTESRCVD,rsize);
592 	}
593 	return rsize;
594 }
595 */
596 
fs_resolve(uint8_t oninit,const char * bindhostname,const char * masterhostname,const char * masterportname)597 int fs_resolve(uint8_t oninit,const char *bindhostname,const char *masterhostname,const char *masterportname) {
598 	if (bindhostname) {
599 		if (tcpresolve(bindhostname,NULL,&srcip,NULL,1)<0) {
600 			if (oninit) {
601 				fprintf(stderr,"can't resolve source hostname (%s)\n",bindhostname);
602 			} else {
603 				syslog(LOG_WARNING,"can't resolve source hostname (%s)",bindhostname);
604 			}
605 			return -1;
606 		}
607 	} else {
608 		srcip=0;
609 	}
610 	snprintf(srcstrip,17,"%"PRIu32".%"PRIu32".%"PRIu32".%"PRIu32,(srcip>>24)&0xFF,(srcip>>16)&0xFF,(srcip>>8)&0xFF,srcip&0xFF);
611 	srcstrip[16]=0;
612 
613 	if (tcpresolve(masterhostname,masterportname,&masterip,&masterport,0)<0) {
614 		if (oninit) {
615 			fprintf(stderr,"can't resolve master hostname and/or portname (%s:%s)\n",masterhostname,masterportname);
616 		} else {
617 			syslog(LOG_WARNING,"can't resolve master hostname and/or portname (%s:%s)",masterhostname,masterportname);
618 		}
619 		return -1;
620 	}
621 	snprintf(masterstrip,17,"%"PRIu32".%"PRIu32".%"PRIu32".%"PRIu32,(masterip>>24)&0xFF,(masterip>>16)&0xFF,(masterip>>8)&0xFF,masterip&0xFF);
622 	masterstrip[16]=0;
623 
624 	return 0;
625 }
626 
627 // int fs_connect(uint8_t oninit,const char *bindhostname,const char *masterhostname,const char *masterportname,uint8_t meta,const char *info,const char *subfolder,const uint8_t passworddigest[16],uint8_t *sesflags,uint32_t *rootuid,uint32_t *rootgid,uint32_t *mapalluid,uint32_t *mapallgid,uint8_t *mingoal,uint8_t *maxgoal,uint32_t *mintrashtime,uint32_t *maxtrashtime) {
fs_connect(uint8_t oninit,struct connect_args_t * cargs)628 int fs_connect(uint8_t oninit,struct connect_args_t *cargs) {
629 	uint32_t i,j;
630 	uint8_t *wptr,*regbuff;
631 	md5ctx ctx;
632 	uint8_t digest[16];
633 	const uint8_t *rptr;
634 	uint32_t newmasterip;
635 	uint8_t havepassword;
636 	uint32_t pleng,ileng;
637 	uint8_t sesflags;
638 	uint32_t rootuid,rootgid,mapalluid,mapallgid;
639 	uint8_t mingoal,maxgoal;
640 	uint32_t mintrashtime,maxtrashtime;
641 	const char *sesflagposstrtab[]={SESFLAG_POS_STRINGS};
642 	const char *sesflagnegstrtab[]={SESFLAG_NEG_STRINGS};
643 	struct passwd pwd,*pw;
644 	struct group grp,*gr;
645 	char pwdgrpbuff[16384];
646 	static uint32_t trycnt=0;
647 
648 	if (fs_resolve(oninit,cargs->bindhostname,cargs->masterhostname,cargs->masterportname)<0) {
649 		return -1;
650 	}
651 
652 	havepassword=(cargs->passworddigest==NULL)?0:1;
653 	ileng=strlen(cargs->info)+1;
654 	if (cargs->meta) {
655 		pleng=0;
656 		regbuff = malloc(8+64+9+ileng+16);
657 	} else {
658 		pleng=strlen(cargs->subfolder)+1;
659 		regbuff = malloc(8+64+13+pleng+ileng+16);
660 	}
661 
662 	do {
663 		fd = tcpsocket();
664 		if (fd<0) {
665 			free(regbuff);
666 			return -1;
667 		}
668 		if (tcpnodelay(fd)<0) {
669 			if (oninit) {
670 				fprintf(stderr,"can't set TCP_NODELAY\n");
671 			} else {
672 				syslog(LOG_WARNING,"can't set TCP_NODELAY");
673 			}
674 		}
675 		if (srcip>0) {
676 			if (tcpnumbind(fd,srcip,0)<0) {
677 				if (oninit) {
678 					fprintf(stderr,"can't bind socket to given ip (\"%s\")\n",srcstrip);
679 				} else {
680 					syslog(LOG_WARNING,"can't bind socket to given ip (\"%s\")",srcstrip);
681 				}
682 				tcpclose(fd);
683 				fd=-1;
684 				free(regbuff);
685 				return -1;
686 			}
687 		}
688 		if (tcpnumtoconnect(fd,masterip,masterport,CONNECT_TIMEOUT)<0) {
689 			tcpclose(fd);
690 			fd=-1;
691 			if (oninit) {
692 				if (trycnt<10) {
693 					trycnt++;
694 					if (fs_resolve(oninit,cargs->bindhostname,cargs->masterhostname,cargs->masterportname)<0) {
695 						free(regbuff);
696 						return -1;
697 					}
698 					i=4;
699 					continue;
700 				} else {
701 					fprintf(stderr,"can't connect to mfsmaster (\"%s\":\"%"PRIu16"\")\n",masterstrip,masterport);
702 					free(regbuff);
703 					return -1;
704 				}
705 			} else {
706 				syslog(LOG_WARNING,"can't connect to mfsmaster (\"%s\":\"%"PRIu16"\")",masterstrip,masterport);
707 				free(regbuff);
708 				return -1;
709 			}
710 		}
711 		if (havepassword) {
712 			wptr = regbuff;
713 			put32bit(&wptr,CLTOMA_FUSE_REGISTER);
714 			put32bit(&wptr,65);
715 			memcpy(wptr,FUSE_REGISTER_BLOB_ACL,64);
716 			wptr+=64;
717 			put8bit(&wptr,REGISTER_GETRANDOM);
718 			if (tcptowrite(fd,regbuff,8+65,1000)!=8+65) {
719 				if (oninit) {
720 					fprintf(stderr,"error sending data to mfsmaster\n");
721 				} else {
722 					syslog(LOG_WARNING,"error sending data to mfsmaster");
723 				}
724 				tcpclose(fd);
725 				fd=-1;
726 				free(regbuff);
727 				return -1;
728 			}
729 			if (tcptoread(fd,regbuff,8,1000)!=8) {
730 				if (oninit) {
731 					fprintf(stderr,"error receiving data from mfsmaster\n");
732 				} else {
733 					syslog(LOG_WARNING,"error receiving data from mfsmaster");
734 				}
735 				tcpclose(fd);
736 				fd=-1;
737 				free(regbuff);
738 				return -1;
739 			}
740 			rptr = regbuff;
741 			i = get32bit(&rptr);
742 			if (i!=MATOCL_FUSE_REGISTER) {
743 				if (oninit) {
744 					fprintf(stderr,"got incorrect answer from mfsmaster\n");
745 				} else {
746 					syslog(LOG_WARNING,"got incorrect answer from mfsmaster");
747 				}
748 				tcpclose(fd);
749 				fd=-1;
750 				free(regbuff);
751 				return -1;
752 			}
753 			i = get32bit(&rptr);
754 			if (i!=32) {
755 				if (oninit) {
756 					fprintf(stderr,"got incorrect answer from mfsmaster\n");
757 				} else {
758 					syslog(LOG_WARNING,"got incorrect answer from mfsmaster");
759 				}
760 				tcpclose(fd);
761 				fd=-1;
762 				free(regbuff);
763 				return -1;
764 			}
765 			if (tcptoread(fd,regbuff,32,1000)!=32) {
766 				if (oninit) {
767 					fprintf(stderr,"error receiving data from mfsmaster\n");
768 				} else {
769 					syslog(LOG_WARNING,"error receiving data from mfsmaster");
770 				}
771 				tcpclose(fd);
772 				fd=-1;
773 				free(regbuff);
774 				return -1;
775 			}
776 			md5_init(&ctx);
777 			md5_update(&ctx,regbuff,16);
778 			md5_update(&ctx,cargs->passworddigest,16);
779 			md5_update(&ctx,regbuff+16,16);
780 			md5_final(digest,&ctx);
781 		}
782 		wptr = regbuff;
783 		put32bit(&wptr,CLTOMA_FUSE_REGISTER);
784 		if (cargs->meta) {
785 			if (havepassword) {
786 				put32bit(&wptr,64+9+ileng+16);
787 			} else {
788 				put32bit(&wptr,64+9+ileng);
789 			}
790 		} else {
791 			if (havepassword) {
792 				put32bit(&wptr,64+13+ileng+pleng+16);
793 			} else {
794 				put32bit(&wptr,64+13+ileng+pleng);
795 			}
796 		}
797 		memcpy(wptr,FUSE_REGISTER_BLOB_ACL,64);
798 		wptr+=64;
799 		put8bit(&wptr,(cargs->meta)?REGISTER_NEWMETASESSION:REGISTER_NEWSESSION);
800 		put16bit(&wptr,VERSMAJ);
801 		put8bit(&wptr,VERSMID);
802 		put8bit(&wptr,VERSMIN);
803 		put32bit(&wptr,ileng);
804 		memcpy(wptr,cargs->info,ileng);
805 		wptr+=ileng;
806 		if (!cargs->meta) {
807 			put32bit(&wptr,pleng);
808 			memcpy(wptr,cargs->subfolder,pleng);
809 		}
810 		if (havepassword) {
811 			memcpy(wptr+pleng,digest,16);
812 		}
813 		if (tcptowrite(fd,regbuff,8+64+(cargs->meta?9:13)+ileng+pleng+(havepassword?16:0),1000)!=(int32_t)(8+64+(cargs->meta?9:13)+ileng+pleng+(havepassword?16:0))) {
814 			if (oninit) {
815 				fprintf(stderr,"error sending data to mfsmaster: %s\n",strerr(errno));
816 			} else {
817 				syslog(LOG_WARNING,"error sending data to mfsmaster: %s",strerr(errno));
818 			}
819 			tcpclose(fd);
820 			fd=-1;
821 			free(regbuff);
822 			return -1;
823 		}
824 		if (tcptoread(fd,regbuff,8,1000)!=8) {
825 			if (oninit) {
826 				fprintf(stderr,"error receiving data from mfsmaster: %s\n",strerr(errno));
827 			} else {
828 				syslog(LOG_WARNING,"error receiving data from mfsmaster: %s",strerr(errno));
829 			}
830 			tcpclose(fd);
831 			fd=-1;
832 			free(regbuff);
833 			return -1;
834 		}
835 		rptr = regbuff;
836 		i = get32bit(&rptr);
837 		if (i!=MATOCL_FUSE_REGISTER) {
838 			if (oninit) {
839 				fprintf(stderr,"got incorrect answer from mfsmaster\n");
840 			} else {
841 				syslog(LOG_WARNING,"got incorrect answer from mfsmaster");
842 			}
843 			tcpclose(fd);
844 			fd=-1;
845 			free(regbuff);
846 			return -1;
847 		}
848 		i = get32bit(&rptr);
849 		if (!(i==1 || i==4 || (cargs->meta && (i==5 || i==9 || i==19)) || (cargs->meta==0 && (i==13 || i==21 || i==25 || i==35)))) {
850 			if (oninit) {
851 				fprintf(stderr,"got incorrect answer from mfsmaster\n");
852 			} else {
853 				syslog(LOG_WARNING,"got incorrect answer from mfsmaster");
854 			}
855 			tcpclose(fd);
856 			fd=-1;
857 			free(regbuff);
858 			return -1;
859 		}
860 		if (tcptoread(fd,regbuff,i,1000)!=(int32_t)i) {
861 			if (oninit) {
862 				fprintf(stderr,"error receiving data from mfsmaster: %s\n",strerr(errno));
863 			} else {
864 				syslog(LOG_WARNING,"error receiving data from mfsmaster: %s",strerr(errno));
865 			}
866 			tcpclose(fd);
867 			fd=-1;
868 			free(regbuff);
869 			return -1;
870 		}
871 		rptr = regbuff;
872 		if (i==1) {
873 			if (oninit) {
874 				fprintf(stderr,"mfsmaster register error: %s\n",mfs_strerror(rptr[0]));
875 			} else {
876 				syslog(LOG_WARNING,"mfsmaster register error: %s",mfs_strerror(rptr[0]));
877 			}
878 			tcpclose(fd);
879 			fd=-1;
880 			free(regbuff);
881 			return -1;
882 		}
883 		if (i==4) {
884 			// redirect
885 			newmasterip = get32bit(&rptr);
886 			if (newmasterip==0 || newmasterip==masterip) {
887 				if (trycnt<10) {
888 					trycnt++;
889 					if (oninit) {
890 						fprintf(stderr,"mfsmaster %s - this is ELECT waitng for being LEADER, waiting a moment and retrying\n",masterstrip);
891 					} else {
892 						syslog(LOG_WARNING,"mfsmaster %s - this is ELECT waitng for being LEADER, waiting a moment and retrying",masterstrip);
893 					}
894 					tcpclose(fd);
895 					fd = -1;
896 					if (oninit) {
897 						sleep(2);
898 					} else {
899 						free(regbuff);
900 						return -1;
901 					}
902 				} else {
903 					trycnt=0;
904 					if (oninit) {
905 						fprintf(stderr,"mfsmaster %s - this is ELECT waitng for being LEADER, waiting a moment and retrying using different IP\n",masterstrip);
906 					} else {
907 						syslog(LOG_WARNING,"mfsmaster %s - this is ELECT waitng for being LEADER, waiting a moment and retrying using different IP",masterstrip);
908 					}
909 					if (oninit) {
910 						if (fs_resolve(oninit,cargs->bindhostname,cargs->masterhostname,cargs->masterportname)<0) {
911 							free(regbuff);
912 							return -1;
913 						}
914 						sleep(2);
915 					} else {
916 						free(regbuff);
917 						return -1;
918 					}
919 				}
920 			} else {
921 				char newmasterstrip[17];
922 				snprintf(newmasterstrip,17,"%"PRIu32".%"PRIu32".%"PRIu32".%"PRIu32,(newmasterip>>24)&0xFF,(newmasterip>>16)&0xFF,(newmasterip>>8)&0xFF,newmasterip&0xFF);
923 				newmasterstrip[16]=0;
924 				if (oninit) {
925 					fprintf(stderr,"mfsmaster %s - found leader: %s\n",masterstrip,newmasterstrip);
926 				} else {
927 					syslog(LOG_WARNING,"mfsmaster %s - found leader: %s",masterstrip,newmasterstrip);
928 				}
929 				masterip = newmasterip;
930 				strcpy(masterstrip,newmasterstrip);
931 				tcpclose(fd);
932 				fd = -1;
933 			}
934 		}
935 	} while (i==4);
936 	if (i==9 || i==19 || i==25 || i==35) {
937 		masterversion = get32bit(&rptr);
938 //		dir_cache_master_switch((masterversion<VERSION2INT(1,6,21))?0:(masterversion<VERSION2INT(1,6,22))?1:2);
939 	} else {
940 		masterversion = 0;
941 //		dir_cache_master_switch(0);
942 	}
943 	sessionid = get32bit(&rptr);
944 	sesflags = get8bit(&rptr);
945 	if (!cargs->meta) {
946 		rootuid = get32bit(&rptr);
947 		rootgid = get32bit(&rptr);
948 		if (i>=21) {
949 			mapalluid = get32bit(&rptr);
950 			mapallgid = get32bit(&rptr);
951 		} else {
952 			mapalluid = 0;
953 			mapallgid = 0;
954 		}
955 	} else {
956 		rootuid = 0;
957 		rootgid = 0;
958 		mapalluid = 0;
959 		mapallgid = 0;
960 	}
961 	if (i==19 || i==35) {
962 		mingoal = get8bit(&rptr);
963 		maxgoal = get8bit(&rptr);
964 		mintrashtime = get32bit(&rptr);
965 		maxtrashtime = get32bit(&rptr);
966 	} else {
967 		mingoal = 0;
968 		maxgoal = 0;
969 		mintrashtime = 0;
970 		maxtrashtime = 0;
971 	}
972 	free(regbuff);
973 	lastwrite=time(NULL);
974 	if (oninit==0) {
975 		syslog(LOG_NOTICE,"registered to master with new session");
976 	}
977 	if (cargs->clearpassword && cargs->passworddigest!=NULL) {
978 		memset(cargs->passworddigest,0,16);
979 		free(cargs->passworddigest);
980 		cargs->passworddigest = NULL;
981 	}
982 	if (oninit==1) {
983 		fprintf(stderr,"mfsmaster accepted connection with parameters: ");
984 		j=0;
985 		for (i=0 ; i<8 ; i++) {
986 			if (sesflags&(1<<i)) {
987 				fprintf(stderr,"%s%s",j?",":"",sesflagposstrtab[i]);
988 				j=1;
989 			} else if (sesflagnegstrtab[i]) {
990 				fprintf(stderr,"%s%s",j?",":"",sesflagnegstrtab[i]);
991 				j=1;
992 			}
993 		}
994 		if (j==0) {
995 			fprintf(stderr,"-");
996 		}
997 		if (!cargs->meta) {
998 			fprintf(stderr," ; root mapped to ");
999 			getpwuid_r(rootuid,&pwd,pwdgrpbuff,16384,&pw);
1000 	//		pw = getpwuid(rootuid);
1001 			if (pw) {
1002 				fprintf(stderr,"%s:",pw->pw_name);
1003 			} else {
1004 				fprintf(stderr,"%"PRIu32":",rootuid);
1005 			}
1006 			getgrgid_r(rootgid,&grp,pwdgrpbuff,16384,&gr);
1007 	//		gr = getgrgid(rootgid);
1008 			if (gr) {
1009 				fprintf(stderr,"%s",gr->gr_name);
1010 			} else {
1011 				fprintf(stderr,"%"PRIu32,rootgid);
1012 			}
1013 			if (sesflags&SESFLAG_MAPALL) {
1014 				fprintf(stderr," ; users mapped to ");
1015 				pw = getpwuid(mapalluid);
1016 				if (pw) {
1017 					fprintf(stderr,"%s:",pw->pw_name);
1018 				} else {
1019 					fprintf(stderr,"%"PRIu32":",mapalluid);
1020 				}
1021 				gr = getgrgid(mapallgid);
1022 				if (gr) {
1023 					fprintf(stderr,"%s",gr->gr_name);
1024 				} else {
1025 					fprintf(stderr,"%"PRIu32,mapallgid);
1026 				}
1027 			}
1028 		}
1029 		if (mingoal>0 && maxgoal>0) {
1030 			if (mingoal>1 || maxgoal<9) {
1031 				fprintf(stderr," ; setgoal limited to (%u:%u)",mingoal,maxgoal);
1032 			}
1033 			if (mintrashtime>0 || maxtrashtime<UINT32_C(0xFFFFFFFF)) {
1034 				fprintf(stderr," ; settrashtime limited to (");
1035 				if (mintrashtime>0) {
1036 					if (mintrashtime>604800) {
1037 						fprintf(stderr,"%uw",mintrashtime/604800);
1038 						mintrashtime %= 604800;
1039 					}
1040 					if (mintrashtime>86400) {
1041 						fprintf(stderr,"%ud",mintrashtime/86400);
1042 						mintrashtime %= 86400;
1043 					}
1044 					if (mintrashtime>3600) {
1045 						fprintf(stderr,"%uh",mintrashtime/3600);
1046 						mintrashtime %= 3600;
1047 					}
1048 					if (mintrashtime>60) {
1049 						fprintf(stderr,"%um",mintrashtime/60);
1050 						mintrashtime %= 60;
1051 					}
1052 					if (mintrashtime>0) {
1053 						fprintf(stderr,"%us",mintrashtime);
1054 					}
1055 				} else {
1056 					fprintf(stderr,"0s");
1057 				}
1058 				fprintf(stderr,":");
1059 				if (maxtrashtime>0) {
1060 					if (maxtrashtime>604800) {
1061 						fprintf(stderr,"%uw",maxtrashtime/604800);
1062 						maxtrashtime %= 604800;
1063 					}
1064 					if (maxtrashtime>86400) {
1065 						fprintf(stderr,"%ud",maxtrashtime/86400);
1066 						maxtrashtime %= 86400;
1067 					}
1068 					if (maxtrashtime>3600) {
1069 						fprintf(stderr,"%uh",maxtrashtime/3600);
1070 						maxtrashtime %= 3600;
1071 					}
1072 					if (maxtrashtime>60) {
1073 						fprintf(stderr,"%um",maxtrashtime/60);
1074 						maxtrashtime %= 60;
1075 					}
1076 					if (maxtrashtime>0) {
1077 						fprintf(stderr,"%us",maxtrashtime);
1078 					}
1079 				} else {
1080 					fprintf(stderr,"0s");
1081 				}
1082 				fprintf(stderr,")");
1083 			}
1084 		}
1085 		fprintf(stderr,"\n");
1086 	}
1087 	return 0;
1088 }
1089 
fs_reconnect()1090 void fs_reconnect() {
1091 	uint32_t newmasterip;
1092 	uint32_t i;
1093 	uint8_t *wptr,regbuff[8+64+9];
1094 	const uint8_t *rptr;
1095 
1096 	if (sessionid==0) {
1097 		syslog(LOG_WARNING,"can't register: session not created");
1098 		return;
1099 	}
1100 
1101 	snprintf(masterstrip,17,"%"PRIu32".%"PRIu32".%"PRIu32".%"PRIu32,(masterip>>24)&0xFF,(masterip>>16)&0xFF,(masterip>>8)&0xFF,masterip&0xFF);
1102 	masterstrip[16]=0;
1103 
1104 	do {
1105 		fd = tcpsocket();
1106 		if (fd<0) {
1107 			return;
1108 		}
1109 		if (tcpnodelay(fd)<0) {
1110 			syslog(LOG_WARNING,"can't set TCP_NODELAY: %s",strerr(errno));
1111 		}
1112 		if (srcip>0) {
1113 			if (tcpnumbind(fd,srcip,0)<0) {
1114 				syslog(LOG_WARNING,"can't bind socket to given ip (\"%s\")",srcstrip);
1115 				tcpclose(fd);
1116 				fd=-1;
1117 				return;
1118 			}
1119 		}
1120 		if (tcpnumtoconnect(fd,masterip,masterport,CONNECT_TIMEOUT)<0) {
1121 			syslog(LOG_WARNING,"can't connect to master (\"%s\":\"%"PRIu16"\")",masterstrip,masterport);
1122 			tcpclose(fd);
1123 			fd=-1;
1124 			return;
1125 		}
1126 		master_stats_inc(MASTER_CONNECTS);
1127 		wptr = regbuff;
1128 		put32bit(&wptr,CLTOMA_FUSE_REGISTER);
1129 		put32bit(&wptr,73);
1130 		memcpy(wptr,FUSE_REGISTER_BLOB_ACL,64);
1131 		wptr+=64;
1132 		put8bit(&wptr,REGISTER_RECONNECT);
1133 		put32bit(&wptr,sessionid);
1134 		put16bit(&wptr,VERSMAJ);
1135 		put8bit(&wptr,VERSMID);
1136 		put8bit(&wptr,VERSMIN);
1137 		if (tcptowrite(fd,regbuff,8+64+9,1000)!=8+64+9) {
1138 			syslog(LOG_WARNING,"master: register error (write: %s)",strerr(errno));
1139 			tcpclose(fd);
1140 			fd=-1;
1141 			return;
1142 		}
1143 		master_stats_add(MASTER_BYTESSENT,16+64);
1144 		master_stats_inc(MASTER_PACKETSSENT);
1145 		if (tcptoread(fd,regbuff,8,1000)!=8) {
1146 			syslog(LOG_WARNING,"master: register error (read header: %s)",strerr(errno));
1147 			tcpclose(fd);
1148 			fd=-1;
1149 			return;
1150 		}
1151 		master_stats_add(MASTER_BYTESRCVD,8);
1152 		rptr = regbuff;
1153 		i = get32bit(&rptr);
1154 		if (i!=MATOCL_FUSE_REGISTER) {
1155 			syslog(LOG_WARNING,"master: register error (bad answer: %"PRIu32")",i);
1156 			tcpclose(fd);
1157 			fd=-1;
1158 			return;
1159 		}
1160 		i = get32bit(&rptr);
1161 		if (i!=1 && i!=4) {
1162 			syslog(LOG_WARNING,"master: register error (bad length: %"PRIu32")",i);
1163 			tcpclose(fd);
1164 			fd=-1;
1165 			return;
1166 		}
1167 		if (tcptoread(fd,regbuff,i,1000)!=(int32_t)i) {
1168 			syslog(LOG_WARNING,"master: register error (read data: %s)",strerr(errno));
1169 			tcpclose(fd);
1170 			fd=-1;
1171 			return;
1172 		}
1173 		master_stats_add(MASTER_BYTESRCVD,i);
1174 		master_stats_inc(MASTER_PACKETSRCVD);
1175 		rptr = regbuff;
1176 		if (i==4) {
1177 			// redirect
1178 			newmasterip = get32bit(&rptr);
1179 			if (newmasterip==0) {
1180 				syslog(LOG_WARNING,"mfsmaster %s - doesn't know his leader, waiting a moment and retrying using different IP",masterstrip);
1181 				tcpclose(fd);
1182 				fd = -1;
1183 				return;
1184 			} else {
1185 				if (newmasterip==masterip) { // this is ELECT
1186 					syslog(LOG_WARNING,"mfsmaster %s - this is ELECT waitng for being LEADER, waiting a moment and retrying",masterstrip);
1187 					tcpclose(fd);
1188 					fd = -1;
1189 					return;
1190 				} else {
1191 					masterip = newmasterip;
1192 					snprintf(masterstrip,17,"%"PRIu32".%"PRIu32".%"PRIu32".%"PRIu32,(masterip>>24)&0xFF,(masterip>>16)&0xFF,(masterip>>8)&0xFF,masterip&0xFF);
1193 					masterstrip[16]=0;
1194 					syslog(LOG_WARNING,"mfsmaster found leader: %s",masterstrip);
1195 					tcpclose(fd);
1196 					fd = -1;
1197 				}
1198 			}
1199 		}
1200 	} while (i==4);
1201 	if (rptr[0]!=0) {
1202 		sessionlost=1;
1203 		syslog(LOG_WARNING,"master: register status: %s",mfs_strerror(rptr[0]));
1204 		tcpclose(fd);
1205 		fd=-1;
1206 		return;
1207 	}
1208 	lastwrite=time(NULL);
1209 	syslog(LOG_NOTICE,"registered to master");
1210 }
1211 
fs_close_session(void)1212 void fs_close_session(void) {
1213 	uint8_t *wptr,regbuff[8+64+5];
1214 
1215 	if (sessionid==0) {
1216 		return;
1217 	}
1218 
1219 	wptr = regbuff;
1220 	put32bit(&wptr,CLTOMA_FUSE_REGISTER);
1221 	put32bit(&wptr,69);
1222 	memcpy(wptr,FUSE_REGISTER_BLOB_ACL,64);
1223 	wptr+=64;
1224 	put8bit(&wptr,REGISTER_CLOSESESSION);
1225 	put32bit(&wptr,sessionid);
1226 	if (tcptowrite(fd,regbuff,8+64+5,1000)!=8+64+5) {
1227 		syslog(LOG_WARNING,"master: close session error (write: %s)",strerr(errno));
1228 	}
1229 	if (masterversion>=VERSION2INT(1,7,29)) {
1230 		if (tcptoread(fd,regbuff,9,500)!=9) {
1231 			syslog(LOG_WARNING,"master: close session error (read: %s)",strerr(errno));
1232 		}
1233 	}
1234 }
1235 
fs_send_open_inodes(void)1236 void fs_send_open_inodes(void) {
1237 	uint8_t *ptr,*inodespacket;
1238 	int32_t inodesleng;
1239 	acquired_file *afptr;
1240 
1241 	pthread_mutex_lock(&aflock);
1242 	//inodesleng=24;
1243 	inodesleng=8;
1244 	for (afptr=afhead ; afptr ; afptr=afptr->next) {
1245 		//syslog(LOG_NOTICE,"sustained inode: %"PRIu32,afptr->inode);
1246 		inodesleng+=4;
1247 	}
1248 	inodespacket = malloc(inodesleng);
1249 	ptr = inodespacket;
1250 	put32bit(&ptr,CLTOMA_FUSE_SUSTAINED_INODES);
1251 	put32bit(&ptr,inodesleng-8);
1252 	//put32bit(&ptr,inodesleng-24);
1253 	//put64bit(&ptr,0);	// readbytes
1254 	//put64bit(&ptr,0);	// writebytes
1255 	// readbytes = 0;
1256 	// writebytes = 0;
1257 	for (afptr=afhead ; afptr ; afptr=afptr->next) {
1258 		put32bit(&ptr,afptr->inode);
1259 	}
1260 	if (tcptowrite(fd,inodespacket,inodesleng,1000)!=inodesleng) {
1261 		disconnect=1;
1262 	} else {
1263 		master_stats_add(MASTER_BYTESSENT,inodesleng);
1264 		master_stats_inc(MASTER_PACKETSSENT);
1265 	}
1266 	free(inodespacket);
1267 	pthread_mutex_unlock(&aflock);
1268 }
1269 
fs_nop_thread(void * arg)1270 void* fs_nop_thread(void *arg) {
1271 	uint8_t *ptr,hdr[12];
1272 	int now;
1273 	int inodeswritecnt=0;
1274 	(void)arg;
1275 	for (;;) {
1276 		now = time(NULL);
1277 		pthread_mutex_lock(&fdlock);
1278 		if (fterm==2 && donotsendsustainedinodes==0) {
1279 			if (fd>=0) {
1280 				fs_send_open_inodes();
1281 				fs_close_session();
1282 				tcpclose(fd);
1283 				fd = -1;
1284 			}
1285 			pthread_mutex_unlock(&fdlock);
1286 			return NULL;
1287 		}
1288 		if (disconnect==0 && fd>=0) {
1289 			if (lastwrite+2<now) {	// NOP
1290 				ptr = hdr;
1291 				put32bit(&ptr,ANTOAN_NOP);
1292 				put32bit(&ptr,4);
1293 				put32bit(&ptr,0);
1294 				if (tcptowrite(fd,hdr,12,1000)!=12) {
1295 					disconnect=1;
1296 				} else {
1297 					master_stats_add(MASTER_BYTESSENT,12);
1298 					master_stats_inc(MASTER_PACKETSSENT);
1299 				}
1300 				lastwrite=now;
1301 			}
1302 			if (inodeswritecnt<=0 || inodeswritecnt>60) {
1303 				inodeswritecnt=60;
1304 			} else {
1305 				inodeswritecnt--;
1306 			}
1307 			if (inodeswritecnt==0) {	// HELD INODES
1308 				if (donotsendsustainedinodes) {
1309 					inodeswritecnt=1;
1310 				} else {
1311 					fs_send_open_inodes();
1312 				}
1313 			}
1314 		}
1315 		pthread_mutex_unlock(&fdlock);
1316 		sleep(1);
1317 	}
1318 }
1319 
fs_receive_thread(void * arg)1320 void* fs_receive_thread(void *arg) {
1321 	const uint8_t *ptr;
1322 	uint8_t hdr[12];
1323 	threc *rec;
1324 	uint32_t cmd,size,packetid;
1325 	uint32_t rcvd;
1326 //	static uint8_t *notify_buff=NULL;
1327 //	static uint32_t notify_buff_size=0;
1328 	int r;
1329 
1330 	(void)arg;
1331 	for (;;) {
1332 		pthread_mutex_lock(&fdlock);
1333 		if (fterm) {
1334 			fterm=2;
1335 			pthread_mutex_unlock(&fdlock);
1336 			return NULL;
1337 		}
1338 		if (disconnect) {
1339 //			dir_cache_remove_all();
1340 			tcpclose(fd);
1341 			fd=-1;
1342 			disconnect=0;
1343 			// send to any threc status error and unlock them
1344 			pthread_mutex_lock(&reclock);
1345 			for (rec=threchead ; rec ; rec=rec->next) {
1346 				pthread_mutex_lock(&(rec->mutex));
1347 				if (rec->sent) {
1348 					rec->status = 1;
1349 					rec->rcvd = 1;
1350 					if (rec->waiting) {
1351 						pthread_cond_signal(&(rec->cond));
1352 					}
1353 				}
1354 				pthread_mutex_unlock(&(rec->mutex));
1355 			}
1356 			pthread_mutex_unlock(&reclock);
1357 		}
1358 		if (fd==-1 && sessionid!=0) {
1359 			fs_reconnect();		// try to register using the same session id
1360 		}
1361 		if (fd==-1) {	// still not connected
1362 			if (sessionlost) {	// if previous session is lost then try to register as a new session
1363 				if (fs_connect(0,&connect_args)==0) {
1364 					sessionlost=0;
1365 				}
1366 			} else {	// if other problem occurred then try to resolve hostname and portname then try to reconnect using the same session id
1367 				if (fs_resolve(0,connect_args.bindhostname,connect_args.masterhostname,connect_args.masterportname)==0) {
1368 					fs_reconnect();
1369 				}
1370 			}
1371 		}
1372 		if (fd==-1) {
1373 			pthread_mutex_unlock(&fdlock);
1374 			sleep(2);	// reconnect every 2 seconds
1375 			continue;
1376 		}
1377 		pthread_mutex_unlock(&fdlock);
1378 		r = tcptoread(fd,hdr,12,RECEIVE_TIMEOUT*1000);	// read timeout
1379 		// syslog(LOG_NOTICE,"master: header size: %d",r);
1380 		if (r==0) {
1381 			syslog(LOG_WARNING,"master: connection lost (header)");
1382 			disconnect=1;
1383 			continue;
1384 		}
1385 		if (r!=12) {
1386 			syslog(LOG_WARNING,"master: tcp recv error: %s (header)",strerr(errno));
1387 			disconnect=1;
1388 			continue;
1389 		}
1390 		master_stats_add(MASTER_BYTESRCVD,12);
1391 		master_stats_inc(MASTER_PACKETSRCVD);
1392 
1393 		ptr = hdr;
1394 		cmd = get32bit(&ptr);
1395 		size = get32bit(&ptr);
1396 		packetid = get32bit(&ptr);
1397 		if (size<4) {
1398 			syslog(LOG_WARNING,"master: packet too small");
1399 			disconnect=1;
1400 			continue;
1401 		}
1402 		size -= 4;
1403 		if (packetid==0) {
1404 			if (cmd==ANTOAN_NOP && size==0) {
1405 				// syslog(LOG_NOTICE,"master: got nop");
1406 				continue;
1407 			}
1408 			if (cmd==ANTOAN_UNKNOWN_COMMAND || cmd==ANTOAN_BAD_COMMAND_SIZE) { // just ignore these packets with packetid==0
1409 				continue;
1410 			}
1411 /*
1412 			if (cmd==MATOCL_FUSE_NOTIFY_END && size==0) {
1413 				dir_cache_transaction_end();
1414 				continue;
1415 			}
1416 			if (cmd==MATOCL_FUSE_NOTIFY_ATTR || cmd==MATOCL_FUSE_NOTIFY_LINK || cmd==MATOCL_FUSE_NOTIFY_UNLINK || cmd==MATOCL_FUSE_NOTIFY_REMOVE || cmd==MATOCL_FUSE_NOTIFY_PARENT) {
1417 				if (size>DEFAULT_INPUT_BUFFSIZE) {
1418 #ifdef MMAP_ALLOC
1419 					if (notify_buff) {
1420 						munmap(notify_buff,notify_buff_size);
1421 					}
1422 					notify_buff = mmap(NULL,size,PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,-1,0);
1423 #else
1424 					if (notify_buff) {
1425 						free(notify_buff);
1426 					}
1427 					notify_buff = malloc(size);
1428 #endif
1429 					notify_buff_size = size;
1430 				} else if (notify_buff_size!=DEFAULT_INPUT_BUFFSIZE) {
1431 #ifdef MMAP_ALLOC
1432 					if (notify_buff) {
1433 						munmap(notify_buff,notify_buff_size);
1434 					}
1435 					notify_buff = mmap(NULL,DEFAULT_INPUT_BUFFSIZE,PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,-1,0);
1436 #else
1437 					if (notify_buff) {
1438 						free(notify_buff);
1439 					}
1440 					notify_buff = malloc(DEFAULT_INPUT_BUFFSIZE);
1441 #endif
1442 					notify_buff_size = DEFAULT_INPUT_BUFFSIZE;
1443 				}
1444 				if (notify_buff==NULL) {
1445 					notify_buff_size = 0;
1446 					disconnect=1;
1447 					continue;
1448 				}
1449 				if (size>0) {
1450 					r = tcptoread(fd,notify_buff,size,1000);
1451 					// syslog(LOG_NOTICE,"master: data size: %d",r);
1452 					if (r==0) {
1453 						syslog(LOG_WARNING,"master: connection lost (2)");
1454 						disconnect=1;
1455 						continue;
1456 					}
1457 					if (r!=(int32_t)(size)) {
1458 						syslog(LOG_WARNING,"master: tcp recv error: %s (2)",strerr(errno));
1459 						disconnect=1;
1460 						continue;
1461 					}
1462 					master_stats_add(MASTER_BYTESRCVD,size);
1463 				}
1464 				switch (cmd) {
1465 					case MATOCL_FUSE_NOTIFY_ATTR:
1466 						fs_notify_attr(notify_buff,size);
1467 						break;
1468 					case MATOCL_FUSE_NOTIFY_LINK:
1469 						fs_notify_link(notify_buff,size);
1470 						break;
1471 					case MATOCL_FUSE_NOTIFY_UNLINK:
1472 						fs_notify_unlink(notify_buff,size);
1473 						break;
1474 					case MATOCL_FUSE_NOTIFY_REMOVE:
1475 						fs_notify_remove(notify_buff,size);
1476 						break;
1477 					case MATOCL_FUSE_NOTIFY_PARENT:
1478 						fs_notify_parent(notify_buff,size);
1479 						break;
1480 				}
1481 				continue;
1482 			}
1483 */
1484 		}
1485 		rec = fs_get_threc_by_id(packetid);
1486 		if (rec==NULL) {
1487 			syslog(LOG_WARNING,"master: got unexpected queryid");
1488 			disconnect=1;
1489 			continue;
1490 		}
1491 		pthread_mutex_lock(&(rec->mutex));	// make helgrind happy
1492 		fs_input_buffer_init(rec,size);
1493 		if (rec->ibuff==NULL) {
1494 			pthread_mutex_unlock(&(rec->mutex));
1495 			disconnect=1;
1496 			continue;
1497 		}
1498 		// syslog(LOG_NOTICE,"master: expected data size: %"PRIu32,size);
1499 		rcvd = 0;
1500 		while (size-rcvd>65536) {
1501 			r = tcptoread(fd,rec->ibuff+rcvd,65536,RECEIVE_TIMEOUT*1000);
1502 			// syslog(LOG_NOTICE,"master: data size: %d",r);
1503 			if (r==0) {
1504 				syslog(LOG_WARNING,"master: connection lost (data)");
1505 				pthread_mutex_unlock(&(rec->mutex));
1506 				disconnect=1;
1507 				break;
1508 			}
1509 			if (r!=65536) {
1510 				syslog(LOG_WARNING,"master: tcp recv error: %s (data)",strerr(errno));
1511 				pthread_mutex_unlock(&(rec->mutex));
1512 				disconnect=1;
1513 				break;
1514 			}
1515 			master_stats_add(MASTER_BYTESRCVD,65536);
1516 			rcvd += 65536;
1517 		}
1518 		if (disconnect) {
1519 			continue;
1520 		}
1521 		if (size-rcvd>0) {
1522 			r = tcptoread(fd,rec->ibuff+rcvd,size-rcvd,RECEIVE_TIMEOUT*1000);
1523 			// syslog(LOG_NOTICE,"master: data size: %d",r);
1524 			if (r==0) {
1525 				syslog(LOG_WARNING,"master: connection lost (data)");
1526 				pthread_mutex_unlock(&(rec->mutex));
1527 				disconnect=1;
1528 				continue;
1529 			}
1530 			if (r!=(int32_t)(size-rcvd)) {
1531 				syslog(LOG_WARNING,"master: tcp recv error: %s (data)",strerr(errno));
1532 				pthread_mutex_unlock(&(rec->mutex));
1533 				disconnect=1;
1534 				continue;
1535 			}
1536 			master_stats_add(MASTER_BYTESRCVD,size-rcvd);
1537 		}
1538 		rec->sent = 0;
1539 		rec->status = 0;
1540 		rec->idataleng = size;
1541 		rec->rcvd_cmd = cmd;
1542 		// syslog(LOG_NOTICE,"master: unlock: %"PRIu32,rec->packetid);
1543 		rec->rcvd = 1;
1544 		if (rec->waiting) {
1545 			pthread_cond_signal(&(rec->cond));
1546 		}
1547 		pthread_mutex_unlock(&(rec->mutex));
1548 	}
1549 }
1550 
1551 // called before fork
fs_init_master_connection(const char * bindhostname,const char * masterhostname,const char * masterportname,uint8_t meta,const char * info,const char * subfolder,const uint8_t passworddigest[16],uint8_t donotrememberpassword,uint8_t bgregister)1552 int fs_init_master_connection(const char *bindhostname,const char *masterhostname,const char *masterportname,uint8_t meta,const char *info,const char *subfolder,const uint8_t passworddigest[16],uint8_t donotrememberpassword,uint8_t bgregister) {
1553 	master_statsptr_init();
1554 
1555 	fd = -1;
1556 	sessionlost = bgregister;
1557 	sessionid = 0;
1558 	disconnect = 0;
1559 	donotsendsustainedinodes = 0;
1560 
1561 	if (bindhostname) {
1562 		connect_args.bindhostname = strdup(bindhostname);
1563 	} else {
1564 		connect_args.bindhostname = NULL;
1565 	}
1566 	connect_args.masterhostname = strdup(masterhostname);
1567 	connect_args.masterportname = strdup(masterportname);
1568 	connect_args.meta = meta;
1569 	connect_args.clearpassword = donotrememberpassword;
1570 	connect_args.info = strdup(info);
1571 	connect_args.subfolder = strdup(subfolder);
1572 	if (passworddigest==NULL) {
1573 		connect_args.passworddigest = NULL;
1574 	} else {
1575 		connect_args.passworddigest = malloc(16);
1576 		memcpy(connect_args.passworddigest,passworddigest,16);
1577 	}
1578 
1579 	if (bgregister) {
1580 		return 1;
1581 	}
1582 	return fs_connect(1,&connect_args);
1583 }
1584 
1585 // called after fork
fs_init_threads(uint32_t retries)1586 void fs_init_threads(uint32_t retries) {
1587 	pthread_attr_t thattr;
1588 	maxretries = retries;
1589 	fterm = 0;
1590 	pthread_mutex_init(&reclock,NULL);
1591 	pthread_mutex_init(&fdlock,NULL);
1592 	pthread_mutex_init(&aflock,NULL);
1593 	pthread_attr_init(&thattr);
1594 	pthread_attr_setstacksize(&thattr,0x100000);
1595 	pthread_create(&rpthid,&thattr,fs_receive_thread,NULL);
1596 	pthread_create(&npthid,&thattr,fs_nop_thread,NULL);
1597 	pthread_attr_destroy(&thattr);
1598 }
1599 
fs_term(void)1600 void fs_term(void) {
1601 	threc *tr,*trn;
1602 	acquired_file *af,*afn;
1603 
1604 	pthread_mutex_lock(&fdlock);
1605 	fterm = 1;
1606 	pthread_mutex_unlock(&fdlock);
1607 	pthread_join(npthid,NULL);
1608 	pthread_join(rpthid,NULL);
1609 	pthread_mutex_destroy(&aflock);
1610 	pthread_mutex_destroy(&fdlock);
1611 	pthread_mutex_destroy(&reclock);
1612 	for (tr = threchead ; tr ; tr = trn) {
1613 		trn = tr->next;
1614 		if (tr->obuff) {
1615 #ifdef MMAP_ALLOC
1616 			munmap((void*)(tr->obuff),tr->obuffsize);
1617 #else
1618 			free(tr->obuff);
1619 #endif
1620 		}
1621 		if (tr->ibuff) {
1622 #ifdef MMAP_ALLOC
1623 			munmap((void*)(tr->ibuff),tr->ibuffsize);
1624 #else
1625 			free(tr->ibuff);
1626 #endif
1627 		}
1628 		pthread_mutex_destroy(&(tr->mutex));
1629 		pthread_cond_destroy(&(tr->cond));
1630 		free(tr);
1631 	}
1632 	for (af = afhead ; af ; af = afn) {
1633 		afn = af->next;
1634 		free(af);
1635 	}
1636 	if (fd>=0) {
1637 		tcpclose(fd);
1638 	}
1639 	if (connect_args.bindhostname) {
1640 		free(connect_args.bindhostname);
1641 	}
1642 	free(connect_args.masterhostname);
1643 	free(connect_args.masterportname);
1644 	free(connect_args.info);
1645 	free(connect_args.subfolder);
1646 	if (connect_args.passworddigest) {
1647 		free(connect_args.passworddigest);
1648 	}
1649 }
1650 
fs_statfs(uint64_t * totalspace,uint64_t * availspace,uint64_t * trashspace,uint64_t * sustainedspace,uint32_t * inodes)1651 void fs_statfs(uint64_t *totalspace,uint64_t *availspace,uint64_t *trashspace,uint64_t *sustainedspace,uint32_t *inodes) {
1652 	uint8_t *wptr;
1653 	const uint8_t *rptr;
1654 	uint32_t i;
1655 	threc *rec = fs_get_my_threc();
1656 	wptr = fs_createpacket(rec,CLTOMA_FUSE_STATFS,0);
1657 	if (wptr==NULL) {
1658 		*totalspace = 0;
1659 		*availspace = 0;
1660 		*trashspace = 0;
1661 		*sustainedspace = 0;
1662 		*inodes = 0;
1663 		return;
1664 	}
1665 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_STATFS,&i);
1666 	if (rptr==NULL || i!=36) {
1667 		*totalspace = 0;
1668 		*availspace = 0;
1669 		*trashspace = 0;
1670 		*sustainedspace = 0;
1671 		*inodes = 0;
1672 	} else {
1673 		*totalspace = get64bit(&rptr);
1674 		*availspace = get64bit(&rptr);
1675 		*trashspace = get64bit(&rptr);
1676 		*sustainedspace = get64bit(&rptr);
1677 		*inodes = get32bit(&rptr);
1678 	}
1679 }
1680 
fs_access(uint32_t inode,uint32_t uid,uint32_t gids,uint32_t * gid,uint16_t modemask)1681 uint8_t fs_access(uint32_t inode,uint32_t uid,uint32_t gids,uint32_t *gid,uint16_t modemask) {
1682 	uint8_t *wptr;
1683 	const uint8_t *rptr;
1684 	uint32_t i;
1685 	uint8_t ret;
1686 	threc *rec = fs_get_my_threc();
1687 	if (masterversion<VERSION2INT(2,0,0) || gids==0) {
1688 		wptr = fs_createpacket(rec,CLTOMA_FUSE_ACCESS,13);
1689 		if (wptr==NULL) {
1690 			return ERROR_IO;
1691 		}
1692 		put32bit(&wptr,inode);
1693 		put32bit(&wptr,uid);
1694 		if (gids>0) {
1695 			put32bit(&wptr,gid[0]);
1696 		} else {
1697 			put32bit(&wptr,0xFFFFFFFF);
1698 		}
1699 		put8bit(&wptr,modemask);
1700 	} else {
1701 		wptr = fs_createpacket(rec,CLTOMA_FUSE_ACCESS,14+4*gids);
1702 		if (wptr==NULL) {
1703 			return ERROR_IO;
1704 		}
1705 		put32bit(&wptr,inode);
1706 		put32bit(&wptr,uid);
1707 		put32bit(&wptr,gids);
1708 		for (i=0 ; i<gids ; i++) {
1709 			put32bit(&wptr,gid[i]);
1710 		}
1711 		put16bit(&wptr,modemask);
1712 	}
1713 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_ACCESS,&i);
1714 	if (!rptr || i!=1) {
1715 		ret = ERROR_IO;
1716 	} else {
1717 		ret = rptr[0];
1718 	}
1719 	return ret;
1720 }
1721 
fs_lookup(uint32_t parent,uint8_t nleng,const uint8_t * name,uint32_t uid,uint32_t gids,uint32_t * gid,uint32_t * inode,uint8_t attr[35])1722 uint8_t fs_lookup(uint32_t parent,uint8_t nleng,const uint8_t *name,uint32_t uid,uint32_t gids,uint32_t *gid,uint32_t *inode,uint8_t attr[35]) {
1723 	uint8_t *wptr;
1724 	const uint8_t *rptr;
1725 	uint32_t i;
1726 	uint8_t ret;
1727 	uint8_t packetver;
1728 	threc *rec = fs_get_my_threc();
1729 	if (masterversion<VERSION2INT(2,0,0)) {
1730 		wptr = fs_createpacket(rec,CLTOMA_FUSE_LOOKUP,13+nleng);
1731 		packetver = 0;
1732 	} else {
1733 		wptr = fs_createpacket(rec,CLTOMA_FUSE_LOOKUP,13+4*gids+nleng);
1734 		packetver = 1;
1735 	}
1736 	if (wptr==NULL) {
1737 		return ERROR_IO;
1738 	}
1739 	put32bit(&wptr,parent);
1740 	put8bit(&wptr,nleng);
1741 	memcpy(wptr,name,nleng);
1742 	wptr+=nleng;
1743 	put32bit(&wptr,uid);
1744 	if (packetver==0) {
1745 		if (gids>0) {
1746 			put32bit(&wptr,gid[0]);
1747 		} else {
1748 			put32bit(&wptr,0xFFFFFFFF);
1749 		}
1750 	} else {
1751 		if (gids>0) {
1752 			put32bit(&wptr,gids);
1753 			for (i=0 ; i<gids ; i++) {
1754 				put32bit(&wptr,gid[i]);
1755 			}
1756 		} else {
1757 			put32bit(&wptr,0xFFFFFFFF);
1758 		}
1759 	}
1760 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_LOOKUP,&i);
1761 	if (rptr==NULL) {
1762 		ret = ERROR_IO;
1763 	} else if (i==1) {
1764 		ret = rptr[0];
1765 	} else if (i!=39) {
1766 		pthread_mutex_lock(&fdlock);
1767 		disconnect = 1;
1768 		pthread_mutex_unlock(&fdlock);
1769 		ret = ERROR_IO;
1770 	} else {
1771 		*inode = get32bit(&rptr);
1772 		memcpy(attr,rptr,35);
1773 		ret = STATUS_OK;
1774 	}
1775 	return ret;
1776 }
1777 
fs_getattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gid,uint8_t attr[35])1778 uint8_t fs_getattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gid,uint8_t attr[35]) {
1779 	uint8_t *wptr;
1780 	const uint8_t *rptr;
1781 	uint32_t i;
1782 	uint8_t ret;
1783 	uint8_t packetver;
1784 	threc *rec = fs_get_my_threc();
1785 	if (masterversion<VERSION2INT(1,6,28)) {
1786 		wptr = fs_createpacket(rec,CLTOMA_FUSE_GETATTR,12);
1787 		packetver = 0;
1788 	} else {
1789 		wptr = fs_createpacket(rec,CLTOMA_FUSE_GETATTR,13);
1790 		packetver = 1;
1791 	}
1792 	if (wptr==NULL) {
1793 		return ERROR_IO;
1794 	}
1795 	put32bit(&wptr,inode);
1796 	if (packetver>=1) {
1797 		put8bit(&wptr,opened);
1798 	}
1799 	put32bit(&wptr,uid);
1800 	put32bit(&wptr,gid);
1801 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETATTR,&i);
1802 	if (rptr==NULL) {
1803 		ret = ERROR_IO;
1804 	} else if (i==1) {
1805 		ret = rptr[0];
1806 	} else if (i!=35) {
1807 		pthread_mutex_lock(&fdlock);
1808 		disconnect = 1;
1809 		pthread_mutex_unlock(&fdlock);
1810 		ret = ERROR_IO;
1811 	} else {
1812 		memcpy(attr,rptr,35);
1813 		ret = STATUS_OK;
1814 	}
1815 	return ret;
1816 }
1817 
fs_setattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t setmask,uint16_t attrmode,uint32_t attruid,uint32_t attrgid,uint32_t attratime,uint32_t attrmtime,uint8_t sugidclearmode,uint8_t attr[35])1818 uint8_t fs_setattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t setmask,uint16_t attrmode,uint32_t attruid,uint32_t attrgid,uint32_t attratime,uint32_t attrmtime,uint8_t sugidclearmode,uint8_t attr[35]) {
1819 	uint8_t *wptr;
1820 	const uint8_t *rptr;
1821 	uint32_t i;
1822 	uint8_t ret;
1823 	uint8_t packetver;
1824 	threc *rec = fs_get_my_threc();
1825 	if (masterversion<VERSION2INT(1,6,25)) {
1826 		wptr = fs_createpacket(rec,CLTOMA_FUSE_SETATTR,31);
1827 		packetver = 0;
1828 	} else if (masterversion<VERSION2INT(1,6,28)) {
1829 		wptr = fs_createpacket(rec,CLTOMA_FUSE_SETATTR,32);
1830 		packetver = 1;
1831 	} else if (masterversion<VERSION2INT(2,0,0)) {
1832 		wptr = fs_createpacket(rec,CLTOMA_FUSE_SETATTR,33);
1833 		packetver = 2;
1834 	} else {
1835 		wptr = fs_createpacket(rec,CLTOMA_FUSE_SETATTR,33+gids*4);
1836 		packetver = 3;
1837 	}
1838 	if (wptr==NULL) {
1839 		return ERROR_IO;
1840 	}
1841 	put32bit(&wptr,inode);
1842 	if (packetver>=2) {
1843 		put8bit(&wptr,opened);
1844 	}
1845 	put32bit(&wptr,uid);
1846 	if (packetver<=2) {
1847 		if (gids>0) {
1848 			put32bit(&wptr,gid[0]);
1849 		} else {
1850 			put32bit(&wptr,0xFFFFFFFF);
1851 		}
1852 	} else {
1853 		if (gids>0) {
1854 			put32bit(&wptr,gids);
1855 			for (i=0 ; i<gids ; i++) {
1856 				put32bit(&wptr,gid[i]);
1857 			}
1858 		} else {
1859 			put32bit(&wptr,0xFFFFFFFF);
1860 		}
1861 	}
1862 	put8bit(&wptr,setmask);
1863 	put16bit(&wptr,attrmode);
1864 	put32bit(&wptr,attruid);
1865 	put32bit(&wptr,attrgid);
1866 	put32bit(&wptr,attratime);
1867 	put32bit(&wptr,attrmtime);
1868 	if (packetver>=1) {
1869 		put8bit(&wptr,sugidclearmode);
1870 	}
1871 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_SETATTR,&i);
1872 	if (rptr==NULL) {
1873 		ret = ERROR_IO;
1874 	} else if (i==1) {
1875 		ret = rptr[0];
1876 	} else if (i!=35) {
1877 		pthread_mutex_lock(&fdlock);
1878 		disconnect = 1;
1879 		pthread_mutex_unlock(&fdlock);
1880 		ret = ERROR_IO;
1881 	} else {
1882 		memcpy(attr,rptr,35);
1883 		ret = STATUS_OK;
1884 	}
1885 	return ret;
1886 }
1887 
fs_truncate(uint32_t inode,uint8_t flags,uint32_t uid,uint32_t gids,uint32_t * gid,uint64_t attrlength,uint8_t attr[35])1888 uint8_t fs_truncate(uint32_t inode,uint8_t flags,uint32_t uid,uint32_t gids,uint32_t *gid,uint64_t attrlength,uint8_t attr[35]) {
1889 	uint8_t *wptr;
1890 	const uint8_t *rptr;
1891 	uint32_t i;
1892 	uint8_t ret;
1893 	uint8_t packetver;
1894 	threc *rec = fs_get_my_threc();
1895 	if (masterversion<VERSION2INT(2,0,0)) {
1896 		wptr = fs_createpacket(rec,CLTOMA_FUSE_TRUNCATE,21);
1897 		packetver = 0;
1898 	} else {
1899 		wptr = fs_createpacket(rec,CLTOMA_FUSE_TRUNCATE,21+4*gids);
1900 		packetver = 1;
1901 	}
1902 	if (wptr==NULL) {
1903 		return ERROR_IO;
1904 	}
1905 	put32bit(&wptr,inode);
1906 	put8bit(&wptr,flags);
1907 	put32bit(&wptr,uid);
1908 	if (packetver==0) {
1909 		if (gids>0) {
1910 			put32bit(&wptr,gid[0]);
1911 		} else {
1912 			put32bit(&wptr,0xFFFFFFFF);
1913 		}
1914 	} else {
1915 		if (gids>0) {
1916 			put32bit(&wptr,gids);
1917 			for (i=0 ; i<gids ; i++) {
1918 				put32bit(&wptr,gid[i]);
1919 			}
1920 		} else {
1921 			put32bit(&wptr,0xFFFFFFFF);
1922 		}
1923 	}
1924 	put64bit(&wptr,attrlength);
1925 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_TRUNCATE,&i);
1926 	if (rptr==NULL) {
1927 		ret = ERROR_IO;
1928 	} else if (i==1) {
1929 		ret = rptr[0];
1930 	} else if (i!=35) {
1931 		pthread_mutex_lock(&fdlock);
1932 		disconnect = 1;
1933 		pthread_mutex_unlock(&fdlock);
1934 		ret = ERROR_IO;
1935 	} else {
1936 		memcpy(attr,rptr,35);
1937 		ret = STATUS_OK;
1938 	}
1939 	return ret;
1940 }
1941 
fs_readlink(uint32_t inode,const uint8_t ** path)1942 uint8_t fs_readlink(uint32_t inode,const uint8_t **path) {
1943 	uint8_t *wptr;
1944 	const uint8_t *rptr;
1945 	uint32_t i;
1946 	uint32_t pleng;
1947 	uint8_t ret;
1948 	threc *rec = fs_get_my_threc();
1949 	wptr = fs_createpacket(rec,CLTOMA_FUSE_READLINK,4);
1950 	if (wptr==NULL) {
1951 		return ERROR_IO;
1952 	}
1953 	put32bit(&wptr,inode);
1954 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_READLINK,&i);
1955 	if (rptr==NULL) {
1956 		ret = ERROR_IO;
1957 	} else if (i==1) {
1958 		ret = rptr[0];
1959 	} else if (i<4) {
1960 		pthread_mutex_lock(&fdlock);
1961 		disconnect = 1;
1962 		pthread_mutex_unlock(&fdlock);
1963 		ret = ERROR_IO;
1964 	} else {
1965 		pleng = get32bit(&rptr);
1966 		if (i!=4+pleng || pleng==0 || rptr[pleng-1]!=0) {
1967 			pthread_mutex_lock(&fdlock);
1968 			disconnect = 1;
1969 			pthread_mutex_unlock(&fdlock);
1970 			ret = ERROR_IO;
1971 		} else {
1972 			*path = rptr;
1973 			//*path = malloc(pleng);
1974 			//memcpy(*path,ptr,pleng);
1975 			ret = STATUS_OK;
1976 		}
1977 	}
1978 	return ret;
1979 }
1980 
fs_symlink(uint32_t parent,uint8_t nleng,const uint8_t * name,const uint8_t * path,uint32_t uid,uint32_t gids,uint32_t * gid,uint32_t * inode,uint8_t attr[35])1981 uint8_t fs_symlink(uint32_t parent,uint8_t nleng,const uint8_t *name,const uint8_t *path,uint32_t uid,uint32_t gids,uint32_t *gid,uint32_t *inode,uint8_t attr[35]) {
1982 	uint8_t *wptr;
1983 	const uint8_t *rptr;
1984 	uint32_t i;
1985 	uint32_t pleng;
1986 	uint8_t ret;
1987 	uint8_t packetver;
1988 	threc *rec = fs_get_my_threc();
1989 	pleng = strlen((const char *)path)+1;
1990 	if (masterversion<VERSION2INT(2,0,0)) {
1991 		wptr = fs_createpacket(rec,CLTOMA_FUSE_SYMLINK,pleng+nleng+17);
1992 		packetver = 0;
1993 	} else {
1994 		wptr = fs_createpacket(rec,CLTOMA_FUSE_SYMLINK,pleng+nleng+17+4*gids);
1995 		packetver = 1;
1996 	}
1997 	if (wptr==NULL) {
1998 		return ERROR_IO;
1999 	}
2000 	put32bit(&wptr,parent);
2001 	put8bit(&wptr,nleng);
2002 	memcpy(wptr,name,nleng);
2003 	wptr+=nleng;
2004 	put32bit(&wptr,pleng);
2005 	memcpy(wptr,path,pleng);
2006 	wptr+=pleng;
2007 	put32bit(&wptr,uid);
2008 	if (packetver==0) {
2009 		if (gids>0) {
2010 			put32bit(&wptr,gid[0]);
2011 		} else {
2012 			put32bit(&wptr,0xFFFFFFFF);
2013 		}
2014 	} else {
2015 		if (gids>0) {
2016 			put32bit(&wptr,gids);
2017 			for (i=0 ; i<gids ; i++) {
2018 				put32bit(&wptr,gid[i]);
2019 			}
2020 		} else {
2021 			put32bit(&wptr,0xFFFFFFFF);
2022 		}
2023 	}
2024 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_SYMLINK,&i);
2025 	if (rptr==NULL) {
2026 		ret = ERROR_IO;
2027 	} else if (i==1) {
2028 		ret = rptr[0];
2029 	} else if (i!=39) {
2030 		pthread_mutex_lock(&fdlock);
2031 		disconnect = 1;
2032 		pthread_mutex_unlock(&fdlock);
2033 		ret = ERROR_IO;
2034 	} else {
2035 		*inode = get32bit(&rptr);
2036 		memcpy(attr,rptr,35);
2037 		ret = STATUS_OK;
2038 	}
2039 	return ret;
2040 }
2041 
fsnodes_type_back_convert(uint8_t type)2042 static inline uint8_t fsnodes_type_back_convert(uint8_t type) {
2043 	switch (type) {
2044 		case TYPE_FILE:
2045 			return DISP_TYPE_FILE;
2046 		case TYPE_DIRECTORY:
2047 			return DISP_TYPE_DIRECTORY;
2048 		case TYPE_SYMLINK:
2049 			return DISP_TYPE_SYMLINK;
2050 		case TYPE_FIFO:
2051 			return DISP_TYPE_FIFO;
2052 		case TYPE_BLOCKDEV:
2053 			return DISP_TYPE_BLOCKDEV;
2054 		case TYPE_CHARDEV:
2055 			return DISP_TYPE_CHARDEV;
2056 		case TYPE_SOCKET:
2057 			return DISP_TYPE_SOCKET;
2058 		case TYPE_TRASH:
2059 			return DISP_TYPE_TRASH;
2060 		case TYPE_SUSTAINED:
2061 			return DISP_TYPE_SUSTAINED;
2062 	}
2063 	return type;
2064 }
2065 
fs_mknod(uint32_t parent,uint8_t nleng,const uint8_t * name,uint8_t type,uint16_t mode,uint16_t cumask,uint32_t uid,uint32_t gids,uint32_t * gid,uint32_t rdev,uint32_t * inode,uint8_t attr[35])2066 uint8_t fs_mknod(uint32_t parent,uint8_t nleng,const uint8_t *name,uint8_t type,uint16_t mode,uint16_t cumask,uint32_t uid,uint32_t gids,uint32_t *gid,uint32_t rdev,uint32_t *inode,uint8_t attr[35]) {
2067 	uint8_t *wptr;
2068 	const uint8_t *rptr;
2069 	uint32_t i;
2070 	uint8_t ret;
2071 	uint8_t packetver;
2072 	threc *rec = fs_get_my_threc();
2073 
2074 	if (masterversion<VERSION2INT(2,0,0)) {
2075 		mode &= ~cumask;
2076 		wptr = fs_createpacket(rec,CLTOMA_FUSE_MKNOD,20+nleng);
2077 		packetver = 0;
2078 	} else {
2079 		wptr = fs_createpacket(rec,CLTOMA_FUSE_MKNOD,22+nleng+4*gids);
2080 		packetver = 1;
2081 	}
2082 	if (wptr==NULL) {
2083 		return ERROR_IO;
2084 	}
2085 	put32bit(&wptr,parent);
2086 	put8bit(&wptr,nleng);
2087 	memcpy(wptr,name,nleng);
2088 	wptr+=nleng;
2089 	if (masterversion<VERSION2INT(1,7,32)) {
2090 		type = fsnodes_type_back_convert(type);
2091 	}
2092 	put8bit(&wptr,type);
2093 	put16bit(&wptr,mode);
2094 	if (packetver>=1) {
2095 		put16bit(&wptr,cumask);
2096 	}
2097 	put32bit(&wptr,uid);
2098 	if (packetver==0) {
2099 		if (gids>0) {
2100 			put32bit(&wptr,gid[0]);
2101 		} else {
2102 			put32bit(&wptr,0xFFFFFFFF);
2103 		}
2104 	} else {
2105 		if (gids>0) {
2106 			put32bit(&wptr,gids);
2107 			for (i=0 ; i<gids ; i++) {
2108 				put32bit(&wptr,gid[i]);
2109 			}
2110 		} else {
2111 			put32bit(&wptr,0xFFFFFFFF);
2112 		}
2113 	}
2114 	put32bit(&wptr,rdev);
2115 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_MKNOD,&i);
2116 	if (rptr==NULL) {
2117 		ret = ERROR_IO;
2118 	} else if (i==1) {
2119 		ret = rptr[0];
2120 	} else if (i!=39) {
2121 		pthread_mutex_lock(&fdlock);
2122 		disconnect = 1;
2123 		pthread_mutex_unlock(&fdlock);
2124 		ret = ERROR_IO;
2125 	} else {
2126 		*inode = get32bit(&rptr);
2127 		memcpy(attr,rptr,35);
2128 		ret = STATUS_OK;
2129 	}
2130 	return ret;
2131 }
2132 
fs_mkdir(uint32_t parent,uint8_t nleng,const uint8_t * name,uint16_t mode,uint16_t cumask,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t copysgid,uint32_t * inode,uint8_t attr[35])2133 uint8_t fs_mkdir(uint32_t parent,uint8_t nleng,const uint8_t *name,uint16_t mode,uint16_t cumask,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t copysgid,uint32_t *inode,uint8_t attr[35]) {
2134 	uint8_t *wptr;
2135 	const uint8_t *rptr;
2136 	uint32_t i;
2137 	uint8_t ret;
2138 	uint8_t packetver;
2139 	threc *rec = fs_get_my_threc();
2140 	if (masterversion<VERSION2INT(1,6,25)) {
2141 		mode &= ~cumask;
2142 		wptr = fs_createpacket(rec,CLTOMA_FUSE_MKDIR,15+nleng);
2143 		packetver = 0;
2144 	} else if (masterversion<VERSION2INT(2,0,0)) {
2145 		mode &= ~cumask;
2146 		wptr = fs_createpacket(rec,CLTOMA_FUSE_MKDIR,16+nleng);
2147 		packetver = 1;
2148 	} else {
2149 		wptr = fs_createpacket(rec,CLTOMA_FUSE_MKDIR,18+nleng+4*gids);
2150 		packetver = 2;
2151 	}
2152 	if (wptr==NULL) {
2153 		return ERROR_IO;
2154 	}
2155 	put32bit(&wptr,parent);
2156 	put8bit(&wptr,nleng);
2157 	memcpy(wptr,name,nleng);
2158 	wptr+=nleng;
2159 	put16bit(&wptr,mode);
2160 	if (packetver>=2) {
2161 		put16bit(&wptr,cumask);
2162 	}
2163 	put32bit(&wptr,uid);
2164 	if (packetver<2) {
2165 		if (gids>0) {
2166 			put32bit(&wptr,gid[0]);
2167 		} else {
2168 			put32bit(&wptr,0xFFFFFFFF);
2169 		}
2170 	} else {
2171 		if (gids>0) {
2172 			put32bit(&wptr,gids);
2173 			for (i=0 ; i<gids ; i++) {
2174 				put32bit(&wptr,gid[i]);
2175 			}
2176 		} else {
2177 			put32bit(&wptr,0xFFFFFFFF);
2178 		}
2179 	}
2180 	if (packetver>=1) {
2181 		put8bit(&wptr,copysgid);
2182 	}
2183 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_MKDIR,&i);
2184 	if (rptr==NULL) {
2185 		ret = ERROR_IO;
2186 	} else if (i==1) {
2187 		ret = rptr[0];
2188 	} else if (i!=39) {
2189 		pthread_mutex_lock(&fdlock);
2190 		disconnect = 1;
2191 		pthread_mutex_unlock(&fdlock);
2192 		ret = ERROR_IO;
2193 	} else {
2194 		*inode = get32bit(&rptr);
2195 		memcpy(attr,rptr,35);
2196 		ret = STATUS_OK;
2197 	}
2198 	return ret;
2199 }
2200 
fs_unlink(uint32_t parent,uint8_t nleng,const uint8_t * name,uint32_t uid,uint32_t gids,uint32_t * gid)2201 uint8_t fs_unlink(uint32_t parent,uint8_t nleng,const uint8_t *name,uint32_t uid,uint32_t gids,uint32_t *gid) {
2202 	uint8_t *wptr;
2203 	const uint8_t *rptr;
2204 	uint32_t i;
2205 	uint8_t ret;
2206 	uint8_t packetver;
2207 	threc *rec = fs_get_my_threc();
2208 	if (masterversion<VERSION2INT(2,0,0)) {
2209 		wptr = fs_createpacket(rec,CLTOMA_FUSE_UNLINK,13+nleng);
2210 		packetver = 0;
2211 	} else {
2212 		wptr = fs_createpacket(rec,CLTOMA_FUSE_UNLINK,13+nleng+4*gids);
2213 		packetver = 1;
2214 	}
2215 	if (wptr==NULL) {
2216 		return ERROR_IO;
2217 	}
2218 	put32bit(&wptr,parent);
2219 	put8bit(&wptr,nleng);
2220 	memcpy(wptr,name,nleng);
2221 	wptr+=nleng;
2222 	put32bit(&wptr,uid);
2223 	if (packetver==0) {
2224 		if (gids>0) {
2225 			put32bit(&wptr,gid[0]);
2226 		} else {
2227 			put32bit(&wptr,0xFFFFFFFF);
2228 		}
2229 	} else {
2230 		if (gids>0) {
2231 			put32bit(&wptr,gids);
2232 			for (i=0 ; i<gids ; i++) {
2233 				put32bit(&wptr,gid[i]);
2234 			}
2235 		} else {
2236 			put32bit(&wptr,0xFFFFFFFF);
2237 		}
2238 	}
2239 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_UNLINK,&i);
2240 	if (rptr==NULL) {
2241 		ret = ERROR_IO;
2242 	} else if (i==1) {
2243 		ret = rptr[0];
2244 	} else {
2245 		pthread_mutex_lock(&fdlock);
2246 		disconnect = 1;
2247 		pthread_mutex_unlock(&fdlock);
2248 		ret = ERROR_IO;
2249 	}
2250 	return ret;
2251 }
2252 
fs_rmdir(uint32_t parent,uint8_t nleng,const uint8_t * name,uint32_t uid,uint32_t gids,uint32_t * gid)2253 uint8_t fs_rmdir(uint32_t parent,uint8_t nleng,const uint8_t *name,uint32_t uid,uint32_t gids,uint32_t *gid) {
2254 	uint8_t *wptr;
2255 	const uint8_t *rptr;
2256 	uint32_t i;
2257 	uint8_t ret;
2258 	uint8_t packetver;
2259 	threc *rec = fs_get_my_threc();
2260 	if (masterversion<VERSION2INT(2,0,0)) {
2261 		wptr = fs_createpacket(rec,CLTOMA_FUSE_RMDIR,13+nleng);
2262 		packetver = 0;
2263 	} else {
2264 		wptr = fs_createpacket(rec,CLTOMA_FUSE_RMDIR,13+nleng+4*gids);
2265 		packetver = 1;
2266 	}
2267 	if (wptr==NULL) {
2268 		return ERROR_IO;
2269 	}
2270 	put32bit(&wptr,parent);
2271 	put8bit(&wptr,nleng);
2272 	memcpy(wptr,name,nleng);
2273 	wptr+=nleng;
2274 	put32bit(&wptr,uid);
2275 	if (packetver==0) {
2276 		if (gids>0) {
2277 			put32bit(&wptr,gid[0]);
2278 		} else {
2279 			put32bit(&wptr,0xFFFFFFFF);
2280 		}
2281 	} else {
2282 		if (gids>0) {
2283 			put32bit(&wptr,gids);
2284 			for (i=0 ; i<gids ; i++) {
2285 				put32bit(&wptr,gid[i]);
2286 			}
2287 		} else {
2288 			put32bit(&wptr,0xFFFFFFFF);
2289 		}
2290 	}
2291 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_RMDIR,&i);
2292 	if (rptr==NULL) {
2293 		ret = ERROR_IO;
2294 	} else if (i==1) {
2295 		ret = rptr[0];
2296 	} else {
2297 		pthread_mutex_lock(&fdlock);
2298 		disconnect = 1;
2299 		pthread_mutex_unlock(&fdlock);
2300 		ret = ERROR_IO;
2301 	}
2302 	return ret;
2303 }
2304 
fs_rename(uint32_t parent_src,uint8_t nleng_src,const uint8_t * name_src,uint32_t parent_dst,uint8_t nleng_dst,const uint8_t * name_dst,uint32_t uid,uint32_t gids,uint32_t * gid,uint32_t * inode,uint8_t attr[35])2305 uint8_t fs_rename(uint32_t parent_src,uint8_t nleng_src,const uint8_t *name_src,uint32_t parent_dst,uint8_t nleng_dst,const uint8_t *name_dst,uint32_t uid,uint32_t gids,uint32_t *gid,uint32_t *inode,uint8_t attr[35]) {
2306 	uint8_t *wptr;
2307 	const uint8_t *rptr;
2308 	uint32_t i;
2309 	uint8_t ret;
2310 	uint8_t packetver;
2311 	threc *rec = fs_get_my_threc();
2312 	if (masterversion<VERSION2INT(2,0,0)) {
2313 		wptr = fs_createpacket(rec,CLTOMA_FUSE_RENAME,18+nleng_src+nleng_dst);
2314 		packetver = 0;
2315 	} else {
2316 		wptr = fs_createpacket(rec,CLTOMA_FUSE_RENAME,18+nleng_src+nleng_dst+4*gids);
2317 		packetver = 1;
2318 	}
2319 	if (wptr==NULL) {
2320 		return ERROR_IO;
2321 	}
2322 	put32bit(&wptr,parent_src);
2323 	put8bit(&wptr,nleng_src);
2324 	memcpy(wptr,name_src,nleng_src);
2325 	wptr+=nleng_src;
2326 	put32bit(&wptr,parent_dst);
2327 	put8bit(&wptr,nleng_dst);
2328 	memcpy(wptr,name_dst,nleng_dst);
2329 	wptr+=nleng_dst;
2330 	put32bit(&wptr,uid);
2331 	if (packetver==0) {
2332 		if (gids>0) {
2333 			put32bit(&wptr,gid[0]);
2334 		} else {
2335 			put32bit(&wptr,0xFFFFFFFF);
2336 		}
2337 	} else {
2338 		if (gids>0) {
2339 			put32bit(&wptr,gids);
2340 			for (i=0 ; i<gids ; i++) {
2341 				put32bit(&wptr,gid[i]);
2342 			}
2343 		} else {
2344 			put32bit(&wptr,0xFFFFFFFF);
2345 		}
2346 	}
2347 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_RENAME,&i);
2348 	if (rptr==NULL) {
2349 		ret = ERROR_IO;
2350 	} else if (i==1) {
2351 		ret = rptr[0];
2352 		*inode = 0;
2353 		memset(attr,0,35);
2354 	} else if (i!=39) {
2355 		pthread_mutex_lock(&fdlock);
2356 		disconnect = 1;
2357 		pthread_mutex_unlock(&fdlock);
2358 		ret = ERROR_IO;
2359 	} else {
2360 		*inode = get32bit(&rptr);
2361 		memcpy(attr,rptr,35);
2362 		ret = STATUS_OK;
2363 	}
2364 	return ret;
2365 }
2366 
fs_link(uint32_t inode_src,uint32_t parent_dst,uint8_t nleng_dst,const uint8_t * name_dst,uint32_t uid,uint32_t gids,uint32_t * gid,uint32_t * inode,uint8_t attr[35])2367 uint8_t fs_link(uint32_t inode_src,uint32_t parent_dst,uint8_t nleng_dst,const uint8_t *name_dst,uint32_t uid,uint32_t gids,uint32_t *gid,uint32_t *inode,uint8_t attr[35]) {
2368 	uint8_t *wptr;
2369 	const uint8_t *rptr;
2370 	uint32_t i;
2371 	uint8_t ret;
2372 	uint8_t packetver;
2373 	threc *rec = fs_get_my_threc();
2374 	if (masterversion<VERSION2INT(2,0,0)) {
2375 		wptr = fs_createpacket(rec,CLTOMA_FUSE_LINK,17+nleng_dst);
2376 		packetver = 0;
2377 	} else {
2378 		wptr = fs_createpacket(rec,CLTOMA_FUSE_LINK,17+nleng_dst+4*gids);
2379 		packetver = 1;
2380 	}
2381 	if (wptr==NULL) {
2382 		return ERROR_IO;
2383 	}
2384 	put32bit(&wptr,inode_src);
2385 	put32bit(&wptr,parent_dst);
2386 	put8bit(&wptr,nleng_dst);
2387 	memcpy(wptr,name_dst,nleng_dst);
2388 	wptr+=nleng_dst;
2389 	put32bit(&wptr,uid);
2390 	if (packetver==0) {
2391 		if (gids>0) {
2392 			put32bit(&wptr,gid[0]);
2393 		} else {
2394 			put32bit(&wptr,0xFFFFFFFF);
2395 		}
2396 	} else {
2397 		if (gids>0) {
2398 			put32bit(&wptr,gids);
2399 			for (i=0 ; i<gids ; i++) {
2400 				put32bit(&wptr,gid[i]);
2401 			}
2402 		} else {
2403 			put32bit(&wptr,0xFFFFFFFF);
2404 		}
2405 	}
2406 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_LINK,&i);
2407 	if (rptr==NULL) {
2408 		ret = ERROR_IO;
2409 	} else if (i==1) {
2410 		ret = rptr[0];
2411 	} else if (i!=39) {
2412 		pthread_mutex_lock(&fdlock);
2413 		disconnect = 1;
2414 		pthread_mutex_unlock(&fdlock);
2415 		ret = ERROR_IO;
2416 	} else {
2417 		*inode = get32bit(&rptr);
2418 		memcpy(attr,rptr,35);
2419 		ret = STATUS_OK;
2420 	}
2421 	return ret;
2422 }
2423 /*
2424 uint8_t fs_getdir(uint32_t inode,uint32_t uid,uint32_t gid,const uint8_t **dbuff,uint32_t *dbuffsize) {
2425 	uint8_t *wptr;
2426 	const uint8_t *rptr;
2427 	uint32_t i;
2428 	uint8_t ret;
2429 	threc *rec = fs_get_my_threc();
2430 	wptr = fs_createpacket(rec,CLTOMA_FUSE_READDIR,12);
2431 	if (wptr==NULL) {
2432 		return ERROR_IO;
2433 	}
2434 	put32bit(&wptr,inode);
2435 	put32bit(&wptr,uid);
2436 	put32bit(&wptr,gid);
2437 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_READDIR,&i);
2438 	if (rptr==NULL) {
2439 		ret = ERROR_IO;
2440 	} else if (i==1) {
2441 		ret = rptr[0];
2442 	} else {
2443 		*dbuff = rptr;
2444 		*dbuffsize = i;
2445 		ret = STATUS_OK;
2446 	}
2447 	return ret;
2448 }
2449 */
2450 
fs_readdir(uint32_t inode,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t wantattr,uint8_t addtocache,const uint8_t ** dbuff,uint32_t * dbuffsize)2451 uint8_t fs_readdir(uint32_t inode,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t wantattr,uint8_t addtocache,const uint8_t **dbuff,uint32_t *dbuffsize) {
2452 	uint8_t *wptr;
2453 	const uint8_t *rptr;
2454 	uint32_t i;
2455 	uint8_t ret;
2456 	uint8_t packetver;
2457 	uint8_t flags;
2458 	threc *rec = fs_get_my_threc();
2459 	if (masterversion<VERSION2INT(2,0,0)) {
2460 		wptr = fs_createpacket(rec,CLTOMA_FUSE_READDIR,13);
2461 		packetver = 0;
2462 	} else {
2463 		wptr = fs_createpacket(rec,CLTOMA_FUSE_READDIR,25+4*gids);
2464 		packetver = 1;
2465 	}
2466 	if (wptr==NULL) {
2467 		return ERROR_IO;
2468 	}
2469 	put32bit(&wptr,inode);
2470 	put32bit(&wptr,uid);
2471 	if (packetver==0) {
2472 		if (gids>0) {
2473 			put32bit(&wptr,gid[0]);
2474 		} else {
2475 			put32bit(&wptr,0xFFFFFFFF);
2476 		}
2477 	} else {
2478 		if (gids>0) {
2479 			put32bit(&wptr,gids);
2480 			for (i=0 ; i<gids ; i++) {
2481 				put32bit(&wptr,gid[i]);
2482 			}
2483 		} else {
2484 			put32bit(&wptr,0xFFFFFFFF);
2485 		}
2486 	}
2487 	flags = 0;
2488 	if (wantattr) {
2489 		flags |= GETDIR_FLAG_WITHATTR;
2490 	}
2491 	if (addtocache) {
2492 		flags |= GETDIR_FLAG_ADDTOCACHE;
2493 	}
2494 	put8bit(&wptr,flags);
2495 	if (packetver>=1) {
2496 		put32bit(&wptr,0xFFFFFFFFU);
2497 		put64bit(&wptr,0);
2498 	}
2499 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_READDIR,&i);
2500 	if (rptr==NULL) {
2501 		ret = ERROR_IO;
2502 	} else if (i==1) {
2503 		ret = rptr[0];
2504 	} else {
2505 		if (packetver>=1) { // skip 'read-next' handler
2506 			rptr+=8;
2507 			i-=8;
2508 		}
2509 		*dbuff = rptr;
2510 		*dbuffsize = i;
2511 		ret = STATUS_OK;
2512 	}
2513 	return ret;
2514 }
2515 
2516 /*
2517 uint8_t fs_check(uint32_t inode,uint8_t dbuff[22]) {
2518 	uint8_t *wptr;
2519 	const uint8_t *rptr;
2520 	uint32_t i;
2521 	uint8_t ret;
2522 	uint16_t cbuff[11];
2523 	uint8_t copies;
2524 	uint16_t chunks;
2525 	threc *rec = fs_get_my_threc();
2526 	wptr = fs_createpacket(rec,CLTOMA_FUSE_CHECK,4);
2527 	if (wptr==NULL) {
2528 		return ERROR_IO;
2529 	}
2530 	put32bit(&wptr,inode);
2531 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_CHECK,&i);
2532 	if (rptr==NULL) {
2533 		ret = ERROR_IO;
2534 	} else if (i==1) {
2535 		ret = rptr[0];
2536 	} else if (i%3!=0) {
2537 		pthread_mutex_lock(&fdlock);
2538 		disconnect = 1;
2539 		pthread_mutex_unlock(&fdlock);
2540 		ret = ERROR_IO;
2541 	} else {
2542 		for (copies=0 ; copies<11 ; copies++) {
2543 			cbuff[copies]=0;
2544 		}
2545 		while (i>0) {
2546 			copies = get8bit(&rptr);
2547 			chunks = get16bit(&rptr);
2548 			if (copies<10) {
2549 				cbuff[copies]+=chunks;
2550 			} else {
2551 				cbuff[10]+=chunks;
2552 			}
2553 			i-=3;
2554 		}
2555 		wptr = dbuff;
2556 		for (copies=0 ; copies<11 ; copies++) {
2557 			chunks = cbuff[copies];
2558 			put16bit(&wptr,chunks);
2559 		}
2560 		ret = STATUS_OK;
2561 	}
2562 	return ret;
2563 }
2564 */
2565 // FUSE - I/O
2566 
fs_create(uint32_t parent,uint8_t nleng,const uint8_t * name,uint16_t mode,uint16_t cumask,uint32_t uid,uint32_t gids,uint32_t * gid,uint32_t * inode,uint8_t attr[35])2567 uint8_t fs_create(uint32_t parent,uint8_t nleng,const uint8_t *name,uint16_t mode,uint16_t cumask,uint32_t uid,uint32_t gids,uint32_t *gid,uint32_t *inode,uint8_t attr[35]) {
2568 	uint8_t *wptr;
2569 	const uint8_t *rptr;
2570 	uint32_t i;
2571 	uint8_t ret;
2572 	uint8_t packetver;
2573 	threc *rec = fs_get_my_threc();
2574 	if (masterversion<VERSION2INT(1,7,25)) {
2575 		return ERROR_ENOTSUP;
2576 	}
2577 	if (masterversion<VERSION2INT(2,0,0)) {
2578 		mode &= ~cumask;
2579 		wptr = fs_createpacket(rec,CLTOMA_FUSE_CREATE,15+nleng);
2580 		packetver = 0;
2581 	} else {
2582 		wptr = fs_createpacket(rec,CLTOMA_FUSE_CREATE,17+nleng+4*gids);
2583 		packetver = 1;
2584 	}
2585 	if (wptr==NULL) {
2586 		return ERROR_IO;
2587 	}
2588 	put32bit(&wptr,parent);
2589 	put8bit(&wptr,nleng);
2590 	memcpy(wptr,name,nleng);
2591 	wptr+=nleng;
2592 	put16bit(&wptr,mode);
2593 	if (packetver>=1) {
2594 		put16bit(&wptr,cumask);
2595 	}
2596 	put32bit(&wptr,uid);
2597 	if (packetver==0) {
2598 		if (gids>0) {
2599 			put32bit(&wptr,gid[0]);
2600 		} else {
2601 			put32bit(&wptr,0xFFFFFFFF);
2602 		}
2603 	} else {
2604 		if (gids>0) {
2605 			put32bit(&wptr,gids);
2606 			for (i=0 ; i<gids ; i++) {
2607 				put32bit(&wptr,gid[i]);
2608 			}
2609 		} else {
2610 			put32bit(&wptr,0xFFFFFFFF);
2611 		}
2612 	}
2613 	pthread_mutex_lock(&fdlock);
2614 	donotsendsustainedinodes = 1;
2615 	pthread_mutex_unlock(&fdlock);
2616 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_CREATE,&i);
2617 	if (rptr==NULL) {
2618 		ret = ERROR_IO;
2619 	} else if (i==1) {
2620 		ret = rptr[0];
2621 	} else if (i!=39) {
2622 		pthread_mutex_lock(&fdlock);
2623 		disconnect = 1;
2624 		pthread_mutex_unlock(&fdlock);
2625 		ret = ERROR_IO;
2626 	} else {
2627 		fs_inc_acnt((*inode = get32bit(&rptr)));
2628 		memcpy(attr,rptr,35);
2629 		ret = STATUS_OK;
2630 	}
2631 	pthread_mutex_lock(&fdlock);
2632 	donotsendsustainedinodes = 0;
2633 	pthread_mutex_unlock(&fdlock);
2634 	return ret;
2635 }
2636 
fs_opencheck(uint32_t inode,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t flags,uint8_t attr[35])2637 uint8_t fs_opencheck(uint32_t inode,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t flags,uint8_t attr[35]) {
2638 	uint8_t *wptr;
2639 	const uint8_t *rptr;
2640 	uint32_t i;
2641 	uint8_t ret;
2642 	uint8_t packetver;
2643 	threc *rec = fs_get_my_threc();
2644 	if (masterversion<VERSION2INT(2,0,0) || gids==0) {
2645 		wptr = fs_createpacket(rec,CLTOMA_FUSE_OPEN,13);
2646 		packetver = 0;
2647 	} else {
2648 		wptr = fs_createpacket(rec,CLTOMA_FUSE_OPEN,13+4*gids);
2649 		packetver = 1;
2650 	}
2651 	if (wptr==NULL) {
2652 		return ERROR_IO;
2653 	}
2654 	put32bit(&wptr,inode);
2655 	put32bit(&wptr,uid);
2656 	if (packetver==0) {
2657 		if (gids>0) { // should be always true)
2658 			put32bit(&wptr,gid[0]);
2659 		} else {
2660 			put32bit(&wptr,0xFFFFFFFF);
2661 		}
2662 	} else {
2663 		put32bit(&wptr,gids);
2664 		for (i=0 ; i<gids ; i++) {
2665 			put32bit(&wptr,gid[i]);
2666 		}
2667 	}
2668 	put8bit(&wptr,flags);
2669 	fs_inc_acnt(inode);
2670 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_OPEN,&i);
2671 	if (rptr==NULL) {
2672 		ret = ERROR_IO;
2673 	} else if (i==1) {
2674 		if (attr) {
2675 			memset(attr,0,35);
2676 		}
2677 		ret = rptr[0];
2678 	} else if (i==35) {
2679 		if (attr) {
2680 			memcpy(attr,rptr,35);
2681 		}
2682 		ret = STATUS_OK;
2683 	} else {
2684 		pthread_mutex_lock(&fdlock);
2685 		disconnect = 1;
2686 		pthread_mutex_unlock(&fdlock);
2687 		ret = ERROR_IO;
2688 	}
2689 	if (ret) {	// release on error
2690 		fs_dec_acnt(inode);
2691 	}
2692 	return ret;
2693 }
2694 
fs_release(uint32_t inode)2695 void fs_release(uint32_t inode) {
2696 	fs_dec_acnt(inode);
2697 }
2698 
2699 // release - decrease acquire cnt - if reach 0 send CLTOMA_FUSE_RELEASE
2700 /*
2701 uint8_t fs_release(uint32_t inode) {
2702 	uint8_t *ptr;
2703 	uint32_t i;
2704 	uint8_t ret;
2705 	ptr = fs_createpacket(rec,CLTOMA_FUSE_RELEASE,4);
2706 	if (wptr==NULL) {
2707 		return ERROR_IO;
2708 	}
2709 	put32bit(&ptr,inode);
2710 	ptr = fs_sendandreceive(rec,MATOCL_FUSE_RELEASE,&i);
2711 	if (ptr==NULL) {
2712 		ret = ERROR_IO;
2713 	} else if (i==1) {
2714 		ret = ptr[0];
2715 	} else {
2716 		pthread_mutex_lock(&fdlock);
2717 		disconnect = 1;
2718 		pthread_mutex_unlock(&fdlock);
2719 		ret = ERROR_IO;
2720 	}
2721 	return ret;
2722 }
2723 */
2724 
fs_readchunk(uint32_t inode,uint32_t indx,uint8_t * csdataver,uint64_t * length,uint64_t * chunkid,uint32_t * version,const uint8_t ** csdata,uint32_t * csdatasize)2725 uint8_t fs_readchunk(uint32_t inode,uint32_t indx,uint8_t *csdataver,uint64_t *length,uint64_t *chunkid,uint32_t *version,const uint8_t **csdata,uint32_t *csdatasize) {
2726 	uint8_t *wptr;
2727 	const uint8_t *rptr;
2728 	uint32_t i;
2729 	uint8_t ret;
2730 	threc *rec = fs_get_my_threc();
2731 
2732 	*csdata = NULL;
2733 	*csdatasize = 0;
2734 
2735 	wptr = fs_createpacket(rec,CLTOMA_FUSE_READ_CHUNK,8);
2736 	if (wptr==NULL) {
2737 		return ERROR_IO;
2738 	}
2739 	put32bit(&wptr,inode);
2740 	put32bit(&wptr,indx);
2741 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_READ_CHUNK,&i);
2742 	if (rptr==NULL) {
2743 		ret = ERROR_IO;
2744 	} else if (i==1) {
2745 		ret = rptr[0];
2746 	} else {
2747 		if (i&1) {
2748 			*csdataver = get8bit(&rptr);
2749 			if (i<21 || ((i-21)%10)!=0) {
2750 				ret = ERROR_IO;
2751 			} else {
2752 				*csdatasize = i-21;
2753 				ret = STATUS_OK;
2754 			}
2755 		} else {
2756 			*csdataver = 0;
2757 			if (i<20 || ((i-20)%6)!=0) {
2758 				ret = ERROR_IO;
2759 			} else {
2760 				*csdatasize = i-20;
2761 				ret = STATUS_OK;
2762 			}
2763 		}
2764 		if (ret!=STATUS_OK) {
2765 			pthread_mutex_lock(&fdlock);
2766 			disconnect = 1;
2767 			pthread_mutex_unlock(&fdlock);
2768 		} else {
2769 			*length = get64bit(&rptr);
2770 			*chunkid = get64bit(&rptr);
2771 			*version = get32bit(&rptr);
2772 			*csdata = rptr;
2773 		}
2774 	}
2775 	return ret;
2776 }
2777 
fs_writechunk(uint32_t inode,uint32_t indx,uint8_t * csdataver,uint64_t * length,uint64_t * chunkid,uint32_t * version,const uint8_t ** csdata,uint32_t * csdatasize)2778 uint8_t fs_writechunk(uint32_t inode,uint32_t indx,uint8_t *csdataver,uint64_t *length,uint64_t *chunkid,uint32_t *version,const uint8_t **csdata,uint32_t *csdatasize) {
2779 	uint8_t *wptr;
2780 	const uint8_t *rptr;
2781 	uint32_t i;
2782 	uint8_t ret;
2783 	threc *rec = fs_get_my_threc();
2784 
2785 	*csdata = NULL;
2786 	*csdatasize = 0;
2787 
2788 	wptr = fs_createpacket(rec,CLTOMA_FUSE_WRITE_CHUNK,8);
2789 	if (wptr==NULL) {
2790 		return ERROR_IO;
2791 	}
2792 	put32bit(&wptr,inode);
2793 	put32bit(&wptr,indx);
2794 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_WRITE_CHUNK,&i);
2795 	if (rptr==NULL) {
2796 		ret = ERROR_IO;
2797 	} else if (i==1) {
2798 		ret = rptr[0];
2799 	} else {
2800 		if (i&1) {
2801 			*csdataver = get8bit(&rptr);
2802 			if (i<21 || ((i-21)%10)!=0) {
2803 				ret = ERROR_IO;
2804 			} else {
2805 				*csdatasize = i-21;
2806 				ret = STATUS_OK;
2807 			}
2808 		} else {
2809 			*csdataver = 0;
2810 			if (i<20 || ((i-20)%6)!=0) {
2811 				ret = ERROR_IO;
2812 			} else {
2813 				*csdatasize = i-20;
2814 				ret = STATUS_OK;
2815 			}
2816 		}
2817 		if (ret!=STATUS_OK) {
2818 			pthread_mutex_lock(&fdlock);
2819 			disconnect = 1;
2820 			pthread_mutex_unlock(&fdlock);
2821 		} else {
2822 			*length = get64bit(&rptr);
2823 			*chunkid = get64bit(&rptr);
2824 			*version = get32bit(&rptr);
2825 			*csdata = rptr;
2826 		}
2827 	}
2828 	return ret;
2829 }
2830 
fs_writeend(uint64_t chunkid,uint32_t inode,uint64_t length)2831 uint8_t fs_writeend(uint64_t chunkid,uint32_t inode,uint64_t length) {
2832 	uint8_t *wptr;
2833 	const uint8_t *rptr;
2834 	uint32_t i;
2835 	uint8_t ret;
2836 	threc *rec = fs_get_my_threc();
2837 	wptr = fs_createpacket(rec,CLTOMA_FUSE_WRITE_CHUNK_END,20);
2838 	if (wptr==NULL) {
2839 		return ERROR_IO;
2840 	}
2841 	put64bit(&wptr,chunkid);
2842 	put32bit(&wptr,inode);
2843 	put64bit(&wptr,length);
2844 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_WRITE_CHUNK_END,&i);
2845 	if (rptr==NULL) {
2846 		ret = ERROR_IO;
2847 	} else if (i==1) {
2848 		ret = rptr[0];
2849 	} else {
2850 		pthread_mutex_lock(&fdlock);
2851 		disconnect = 1;
2852 		pthread_mutex_unlock(&fdlock);
2853 		ret = ERROR_IO;
2854 	}
2855 	return ret;
2856 }
2857 
2858 
2859 // FUSE - META
2860 
2861 
fs_getsustained(const uint8_t ** dbuff,uint32_t * dbuffsize)2862 uint8_t fs_getsustained(const uint8_t **dbuff,uint32_t *dbuffsize) {
2863 	uint8_t *wptr;
2864 	const uint8_t *rptr;
2865 	uint32_t i;
2866 	uint8_t ret;
2867 	threc *rec = fs_get_my_threc();
2868 	wptr = fs_createpacket(rec,CLTOMA_FUSE_GETSUSTAINED,0);
2869 	if (wptr==NULL) {
2870 		return ERROR_IO;
2871 	}
2872 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETSUSTAINED,&i);
2873 	if (rptr==NULL) {
2874 		ret = ERROR_IO;
2875 	} else if (i==1) {
2876 		ret = rptr[0];
2877 	} else {
2878 		*dbuff = rptr;
2879 		*dbuffsize = i;
2880 		ret = STATUS_OK;
2881 	}
2882 	return ret;
2883 }
2884 
fs_gettrash(const uint8_t ** dbuff,uint32_t * dbuffsize)2885 uint8_t fs_gettrash(const uint8_t **dbuff,uint32_t *dbuffsize) {
2886 	uint8_t *wptr;
2887 	const uint8_t *rptr;
2888 	uint32_t i;
2889 	uint8_t ret;
2890 	threc *rec = fs_get_my_threc();
2891 	wptr = fs_createpacket(rec,CLTOMA_FUSE_GETTRASH,0);
2892 	if (wptr==NULL) {
2893 		return ERROR_IO;
2894 	}
2895 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETTRASH,&i);
2896 	if (rptr==NULL) {
2897 		ret = ERROR_IO;
2898 	} else if (i==1) {
2899 		ret = rptr[0];
2900 	} else {
2901 		*dbuff = rptr;
2902 		*dbuffsize = i;
2903 		ret = STATUS_OK;
2904 	}
2905 	return ret;
2906 }
2907 
fs_getdetachedattr(uint32_t inode,uint8_t attr[35])2908 uint8_t fs_getdetachedattr(uint32_t inode,uint8_t attr[35]) {
2909 	uint8_t *wptr;
2910 	const uint8_t *rptr;
2911 	uint32_t i;
2912 	uint8_t ret;
2913 	threc *rec = fs_get_my_threc();
2914 	wptr = fs_createpacket(rec,CLTOMA_FUSE_GETDETACHEDATTR,4);
2915 	if (wptr==NULL) {
2916 		return ERROR_IO;
2917 	}
2918 	put32bit(&wptr,inode);
2919 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETDETACHEDATTR,&i);
2920 	if (rptr==NULL) {
2921 		ret = ERROR_IO;
2922 	} else if (i==1) {
2923 		ret = rptr[0];
2924 	} else if (i!=35) {
2925 		pthread_mutex_lock(&fdlock);
2926 		disconnect = 1;
2927 		pthread_mutex_unlock(&fdlock);
2928 		ret = ERROR_IO;
2929 	} else {
2930 		memcpy(attr,rptr,35);
2931 		ret = STATUS_OK;
2932 	}
2933 	return ret;
2934 }
2935 
fs_gettrashpath(uint32_t inode,const uint8_t ** path)2936 uint8_t fs_gettrashpath(uint32_t inode,const uint8_t **path) {
2937 	uint8_t *wptr;
2938 	const uint8_t *rptr;
2939 	uint32_t i;
2940 	uint32_t pleng;
2941 	uint8_t ret;
2942 	threc *rec = fs_get_my_threc();
2943 	wptr = fs_createpacket(rec,CLTOMA_FUSE_GETTRASHPATH,4);
2944 	if (wptr==NULL) {
2945 		return ERROR_IO;
2946 	}
2947 	put32bit(&wptr,inode);
2948 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETTRASHPATH,&i);
2949 	if (rptr==NULL) {
2950 		ret = ERROR_IO;
2951 	} else if (i==1) {
2952 		ret = rptr[0];
2953 	} else if (i<4) {
2954 		pthread_mutex_lock(&fdlock);
2955 		disconnect = 1;
2956 		pthread_mutex_unlock(&fdlock);
2957 		ret = ERROR_IO;
2958 	} else {
2959 		pleng = get32bit(&rptr);
2960 		if (i!=4+pleng || pleng==0 || rptr[pleng-1]!=0) {
2961 			pthread_mutex_lock(&fdlock);
2962 			disconnect = 1;
2963 			pthread_mutex_unlock(&fdlock);
2964 			ret = ERROR_IO;
2965 		} else {
2966 			*path = rptr;
2967 			ret = STATUS_OK;
2968 		}
2969 	}
2970 	return ret;
2971 }
2972 
fs_settrashpath(uint32_t inode,const uint8_t * path)2973 uint8_t fs_settrashpath(uint32_t inode,const uint8_t *path) {
2974 	uint8_t *wptr;
2975 	const uint8_t *rptr;
2976 	uint32_t i;
2977 	uint32_t pleng;
2978 	uint8_t ret;
2979 	threc *rec = fs_get_my_threc();
2980 	pleng = strlen((const char *)path)+1;
2981 	wptr = fs_createpacket(rec,CLTOMA_FUSE_SETTRASHPATH,pleng+8);
2982 	if (wptr==NULL) {
2983 		return ERROR_IO;
2984 	}
2985 	put32bit(&wptr,inode);
2986 	put32bit(&wptr,pleng);
2987 	memcpy(wptr,path,pleng);
2988 //	ptr+=pleng;
2989 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_SETTRASHPATH,&i);
2990 	if (rptr==NULL) {
2991 		ret = ERROR_IO;
2992 	} else if (i==1) {
2993 		ret = rptr[0];
2994 	} else {
2995 		pthread_mutex_lock(&fdlock);
2996 		disconnect = 1;
2997 		pthread_mutex_unlock(&fdlock);
2998 		ret = ERROR_IO;
2999 	}
3000 	return ret;
3001 }
3002 
fs_undel(uint32_t inode)3003 uint8_t fs_undel(uint32_t inode) {
3004 	uint8_t *wptr;
3005 	const uint8_t *rptr;
3006 	uint32_t i;
3007 	uint8_t ret;
3008 	threc *rec = fs_get_my_threc();
3009 	wptr = fs_createpacket(rec,CLTOMA_FUSE_UNDEL,4);
3010 	if (wptr==NULL) {
3011 		return ERROR_IO;
3012 	}
3013 	put32bit(&wptr,inode);
3014 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_UNDEL,&i);
3015 	if (rptr==NULL) {
3016 		ret = ERROR_IO;
3017 	} else if (i==1) {
3018 		ret = rptr[0];
3019 	} else {
3020 		pthread_mutex_lock(&fdlock);
3021 		disconnect = 1;
3022 		pthread_mutex_unlock(&fdlock);
3023 		ret = ERROR_IO;
3024 	}
3025 	return ret;
3026 }
3027 
fs_purge(uint32_t inode)3028 uint8_t fs_purge(uint32_t inode) {
3029 	uint8_t *wptr;
3030 	const uint8_t *rptr;
3031 	uint32_t i;
3032 	uint8_t ret;
3033 	threc *rec = fs_get_my_threc();
3034 	wptr = fs_createpacket(rec,CLTOMA_FUSE_PURGE,4);
3035 	if (wptr==NULL) {
3036 		return ERROR_IO;
3037 	}
3038 	put32bit(&wptr,inode);
3039 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_PURGE,&i);
3040 	if (rptr==NULL) {
3041 		ret = ERROR_IO;
3042 	} else if (i==1) {
3043 		ret = rptr[0];
3044 	} else {
3045 		pthread_mutex_lock(&fdlock);
3046 		disconnect = 1;
3047 		pthread_mutex_unlock(&fdlock);
3048 		ret = ERROR_IO;
3049 	}
3050 	return ret;
3051 }
3052 
fs_getacl(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t acltype,uint16_t * userperm,uint16_t * groupperm,uint16_t * otherperm,uint16_t * maskperm,uint16_t * namedusers,uint16_t * namedgroups,const uint8_t ** namedacls,uint32_t * namedaclssize)3053 uint8_t fs_getacl(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t acltype,uint16_t *userperm,uint16_t *groupperm,uint16_t *otherperm,uint16_t *maskperm,uint16_t *namedusers,uint16_t *namedgroups,const uint8_t **namedacls,uint32_t *namedaclssize) {
3054 	uint8_t *wptr;
3055 	const uint8_t *rptr;
3056 	uint32_t i;
3057 	uint8_t ret;
3058 	threc *rec = fs_get_my_threc();
3059 	*namedacls = NULL;
3060 	*namedaclssize = 0;
3061 	if (masterversion<VERSION2INT(2,0,0)) {
3062 		return ERROR_ENOTSUP;
3063 	}
3064 	wptr = fs_createpacket(rec,CLTOMA_FUSE_GETACL,14+4*gids);
3065 	if (wptr==NULL) {
3066 		return ERROR_IO;
3067 	}
3068 	put32bit(&wptr,inode);
3069 	put8bit(&wptr,acltype);
3070 	put8bit(&wptr,opened);
3071 	put32bit(&wptr,uid);
3072 	if (gids>0) {
3073 		put32bit(&wptr,gids);
3074 		for (i=0 ; i<gids ; i++) {
3075 			put32bit(&wptr,gid[i]);
3076 		}
3077 	} else {
3078 		put32bit(&wptr,0xFFFFFFFFU);
3079 	}
3080 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETACL,&i);
3081 	if (rptr==NULL) {
3082 		ret = ERROR_IO;
3083 	} else if (i==1) {
3084 		ret = rptr[0];
3085 	} else if (i<12) {
3086 		pthread_mutex_lock(&fdlock);
3087 		disconnect = 1;
3088 		pthread_mutex_unlock(&fdlock);
3089 		ret = ERROR_IO;
3090 	} else {
3091 		*userperm = get16bit(&rptr);
3092 		*groupperm = get16bit(&rptr);
3093 		*otherperm = get16bit(&rptr);
3094 		*maskperm = get16bit(&rptr);
3095 		*namedusers = get16bit(&rptr);
3096 		*namedgroups = get16bit(&rptr);
3097 		*namedacls = rptr;
3098 		*namedaclssize = i-12;
3099 		ret = STATUS_OK;
3100 	}
3101 	return ret;
3102 }
3103 
fs_setacl(uint32_t inode,uint32_t uid,uint8_t acltype,uint16_t userperm,uint16_t groupperm,uint16_t otherperm,uint16_t maskperm,uint16_t namedusers,uint16_t namedgroups,uint8_t * namedacls,uint32_t namedaclssize)3104 uint8_t fs_setacl(uint32_t inode,uint32_t uid,uint8_t acltype,uint16_t userperm,uint16_t groupperm,uint16_t otherperm,uint16_t maskperm,uint16_t namedusers,uint16_t namedgroups,uint8_t *namedacls,uint32_t namedaclssize) {
3105 	uint8_t *wptr;
3106 	const uint8_t *rptr;
3107 	uint32_t i;
3108 	uint8_t ret;
3109 	threc *rec = fs_get_my_threc();
3110 	if (masterversion<VERSION2INT(2,0,0)) {
3111 		return ERROR_ENOTSUP;
3112 	}
3113 	wptr = fs_createpacket(rec,CLTOMA_FUSE_SETACL,21+namedaclssize);
3114 	if (wptr==NULL) {
3115 		return ERROR_IO;
3116 	}
3117 	put32bit(&wptr,inode);
3118 	put32bit(&wptr,uid);
3119 	put8bit(&wptr,acltype);
3120 	put16bit(&wptr,userperm);
3121 	put16bit(&wptr,groupperm);
3122 	put16bit(&wptr,otherperm);
3123 	put16bit(&wptr,maskperm);
3124 	put16bit(&wptr,namedusers);
3125 	put16bit(&wptr,namedgroups);
3126 	memcpy(wptr,namedacls,namedaclssize);
3127 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_SETACL,&i);
3128 	if (rptr==NULL) {
3129 		ret = ERROR_IO;
3130 	} else if (i==1) {
3131 		ret = rptr[0];
3132 	} else {
3133 		pthread_mutex_lock(&fdlock);
3134 		disconnect = 1;
3135 		pthread_mutex_unlock(&fdlock);
3136 		ret = ERROR_IO;
3137 	}
3138 	return ret;
3139 }
3140 
fs_getxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t nleng,const uint8_t * name,uint8_t mode,const uint8_t ** vbuff,uint32_t * vleng)3141 uint8_t fs_getxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t nleng,const uint8_t *name,uint8_t mode,const uint8_t **vbuff,uint32_t *vleng) {
3142 	uint8_t *wptr;
3143 	const uint8_t *rptr;
3144 	uint32_t i;
3145 	uint8_t ret;
3146 	uint8_t packetver;
3147 	threc *rec = fs_get_my_threc();
3148 	*vbuff = NULL;
3149 	*vleng = 0;
3150 	if (masterversion<VERSION2INT(1,7,0)) {
3151 		return ERROR_ENOTSUP;
3152 	}
3153 	if (masterversion<VERSION2INT(2,0,0)) {
3154 		wptr = fs_createpacket(rec,CLTOMA_FUSE_GETXATTR,15+nleng);
3155 		packetver = 0;
3156 	} else {
3157 		wptr = fs_createpacket(rec,CLTOMA_FUSE_GETXATTR,15+nleng+4*gids);
3158 		packetver = 1;
3159 	}
3160 	if (wptr==NULL) {
3161 		return ERROR_IO;
3162 	}
3163 	put32bit(&wptr,inode);
3164 	if (packetver==0) {
3165 		put8bit(&wptr,opened);
3166 		put32bit(&wptr,uid);
3167 		if (gids>0) {
3168 			put32bit(&wptr,gid[0]);
3169 		} else {
3170 			put32bit(&wptr,0xFFFFFFFFU);
3171 		}
3172 	}
3173 	put8bit(&wptr,nleng);
3174 	memcpy(wptr,name,nleng);
3175 	wptr+=nleng;
3176 	put8bit(&wptr,mode);
3177 	if (packetver>=1) {
3178 		put8bit(&wptr,opened);
3179 		put32bit(&wptr,uid);
3180 		if (gids>0) {
3181 			put32bit(&wptr,gids);
3182 			for (i=0 ; i<gids ; i++) {
3183 				put32bit(&wptr,gid[i]);
3184 			}
3185 		} else {
3186 			put32bit(&wptr,0xFFFFFFFFU);
3187 		}
3188 	}
3189 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETXATTR,&i);
3190 	if (rptr==NULL) {
3191 		ret = ERROR_IO;
3192 	} else if (i==1) {
3193 		ret = rptr[0];
3194 	} else if (i<4) {
3195 		pthread_mutex_lock(&fdlock);
3196 		disconnect = 1;
3197 		pthread_mutex_unlock(&fdlock);
3198 		ret = ERROR_IO;
3199 	} else {
3200 		*vleng = get32bit(&rptr);
3201 		*vbuff = (mode==MFS_XATTR_GETA_DATA)?rptr:NULL;
3202 		if ((mode==MFS_XATTR_GETA_DATA && i!=(*vleng)+4) || (mode==MFS_XATTR_LENGTH_ONLY && i!=4)) {
3203 			pthread_mutex_lock(&fdlock);
3204 			disconnect = 1;
3205 			pthread_mutex_unlock(&fdlock);
3206 			ret = ERROR_IO;
3207 		} else {
3208 			ret = STATUS_OK;
3209 		}
3210 	}
3211 	return ret;
3212 }
3213 
fs_listxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t mode,const uint8_t ** dbuff,uint32_t * dleng)3214 uint8_t fs_listxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t mode,const uint8_t **dbuff,uint32_t *dleng) {
3215 	uint8_t *wptr;
3216 	const uint8_t *rptr;
3217 	uint32_t i;
3218 	uint8_t ret;
3219 	uint8_t packetver;
3220 	threc *rec = fs_get_my_threc();
3221 	if (masterversion<VERSION2INT(1,7,0)) {
3222 		return ERROR_ENOTSUP;
3223 	}
3224 	if (masterversion<VERSION2INT(2,0,0)) {
3225 		wptr = fs_createpacket(rec,CLTOMA_FUSE_GETXATTR,15);
3226 		packetver = 0;
3227 	} else {
3228 		wptr = fs_createpacket(rec,CLTOMA_FUSE_GETXATTR,15+4*gids);
3229 		packetver = 1;
3230 	}
3231 	if (wptr==NULL) {
3232 		return ERROR_IO;
3233 	}
3234 	put32bit(&wptr,inode);
3235 	if (packetver==0) {
3236 		put8bit(&wptr,opened);
3237 		put32bit(&wptr,uid);
3238 		if (gids>0) {
3239 			put32bit(&wptr,gid[0]);
3240 		} else {
3241 			put32bit(&wptr,0xFFFFFFFFU);
3242 		}
3243 	}
3244 	put8bit(&wptr,0);
3245 	put8bit(&wptr,mode);
3246 	if (packetver>=1) {
3247 		put8bit(&wptr,opened);
3248 		put32bit(&wptr,uid);
3249 		if (gids>0) {
3250 			put32bit(&wptr,gids);
3251 			for (i=0 ; i<gids ; i++) {
3252 				put32bit(&wptr,gid[i]);
3253 			}
3254 		} else {
3255 			put32bit(&wptr,0xFFFFFFFFU);
3256 		}
3257 	}
3258 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETXATTR,&i);
3259 	if (rptr==NULL) {
3260 		ret = ERROR_IO;
3261 	} else if (i==1) {
3262 		ret = rptr[0];
3263 	} else if (i<4) {
3264 		pthread_mutex_lock(&fdlock);
3265 		disconnect = 1;
3266 		pthread_mutex_unlock(&fdlock);
3267 		ret = ERROR_IO;
3268 	} else {
3269 		*dleng = get32bit(&rptr);
3270 		*dbuff = (mode==MFS_XATTR_GETA_DATA)?rptr:NULL;
3271 		if ((mode==MFS_XATTR_GETA_DATA && i!=(*dleng)+4) || (mode==MFS_XATTR_LENGTH_ONLY && i!=4)) {
3272 			pthread_mutex_lock(&fdlock);
3273 			disconnect = 1;
3274 			pthread_mutex_unlock(&fdlock);
3275 			ret = ERROR_IO;
3276 		} else {
3277 			ret = STATUS_OK;
3278 		}
3279 	}
3280 	return ret;
3281 }
3282 
fs_setxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t nleng,const uint8_t * name,uint32_t vleng,const uint8_t * value,uint8_t mode)3283 uint8_t fs_setxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t nleng,const uint8_t *name,uint32_t vleng,const uint8_t *value,uint8_t mode) {
3284 	uint8_t *wptr;
3285 	const uint8_t *rptr;
3286 	uint32_t i;
3287 	uint8_t ret;
3288 	uint8_t packetver;
3289 	threc *rec = fs_get_my_threc();
3290 	if (masterversion<VERSION2INT(1,7,0)) {
3291 		return ERROR_ENOTSUP;
3292 	}
3293 	if (mode>=MFS_XATTR_REMOVE) {
3294 		return ERROR_EINVAL;
3295 	}
3296 	if (masterversion<VERSION2INT(2,0,0)) {
3297 		wptr = fs_createpacket(rec,CLTOMA_FUSE_SETXATTR,19+nleng+vleng);
3298 		packetver = 0;
3299 	} else {
3300 		wptr = fs_createpacket(rec,CLTOMA_FUSE_SETXATTR,19+nleng+vleng+4*gids);
3301 		packetver = 1;
3302 	}
3303 	if (wptr==NULL) {
3304 		return ERROR_IO;
3305 	}
3306 	put32bit(&wptr,inode);
3307 	if (packetver==0) {
3308 		put8bit(&wptr,opened);
3309 		put32bit(&wptr,uid);
3310 		if (gids>0) {
3311 			put32bit(&wptr,gid[0]);
3312 		} else {
3313 			put32bit(&wptr,0xFFFFFFFFU);
3314 		}
3315 	}
3316 	put8bit(&wptr,nleng);
3317 	memcpy(wptr,name,nleng);
3318 	wptr+=nleng;
3319 	put32bit(&wptr,vleng);
3320 	memcpy(wptr,value,vleng);
3321 	wptr+=vleng;
3322 	put8bit(&wptr,mode);
3323 	if (packetver>=1) {
3324 		put8bit(&wptr,opened);
3325 		put32bit(&wptr,uid);
3326 		if (gids>0) {
3327 			put32bit(&wptr,gids);
3328 			for (i=0 ; i<gids ; i++) {
3329 				put32bit(&wptr,gid[i]);
3330 			}
3331 		} else {
3332 			put32bit(&wptr,0xFFFFFFFFU);
3333 		}
3334 	}
3335 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_SETXATTR,&i);
3336 	if (rptr==NULL) {
3337 		ret = ERROR_IO;
3338 	} else if (i==1) {
3339 		ret = rptr[0];
3340 	} else {
3341 		pthread_mutex_lock(&fdlock);
3342 		disconnect = 1;
3343 		pthread_mutex_unlock(&fdlock);
3344 		ret = ERROR_IO;
3345 	}
3346 	return ret;
3347 }
3348 
fs_removexattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t nleng,const uint8_t * name)3349 uint8_t fs_removexattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t nleng,const uint8_t *name) {
3350 	uint8_t *wptr;
3351 	const uint8_t *rptr;
3352 	uint32_t i;
3353 	uint8_t ret;
3354 	uint8_t packetver;
3355 	threc *rec = fs_get_my_threc();
3356 	if (masterversion<VERSION2INT(1,7,0)) {
3357 		return ERROR_ENOTSUP;
3358 	}
3359 	if (masterversion<VERSION2INT(2,0,0)) {
3360 		wptr = fs_createpacket(rec,CLTOMA_FUSE_SETXATTR,19+nleng);
3361 		packetver = 0;
3362 	} else {
3363 		wptr = fs_createpacket(rec,CLTOMA_FUSE_SETXATTR,19+nleng+4*gids);
3364 		packetver = 1;
3365 	}
3366 	if (wptr==NULL) {
3367 		return ERROR_IO;
3368 	}
3369 	put32bit(&wptr,inode);
3370 	if (packetver==0) {
3371 		put8bit(&wptr,opened);
3372 		put32bit(&wptr,uid);
3373 		if (gids>0) {
3374 			put32bit(&wptr,gid[0]);
3375 		} else {
3376 			put32bit(&wptr,0xFFFFFFFFU);
3377 		}
3378 	}
3379 	put8bit(&wptr,nleng);
3380 	memcpy(wptr,name,nleng);
3381 	wptr+=nleng;
3382 	put32bit(&wptr,0);
3383 	put8bit(&wptr,MFS_XATTR_REMOVE);
3384 	if (packetver>=1) {
3385 		put8bit(&wptr,opened);
3386 		put32bit(&wptr,uid);
3387 		if (gids>0) {
3388 			put32bit(&wptr,gids);
3389 			for (i=0 ; i<gids ; i++) {
3390 				put32bit(&wptr,gid[i]);
3391 			}
3392 		} else {
3393 			put32bit(&wptr,0xFFFFFFFFU);
3394 		}
3395 	}
3396 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_SETXATTR,&i);
3397 	if (rptr==NULL) {
3398 		ret = ERROR_IO;
3399 	} else if (i==1) {
3400 		ret = rptr[0];
3401 	} else {
3402 		pthread_mutex_lock(&fdlock);
3403 		disconnect = 1;
3404 		pthread_mutex_unlock(&fdlock);
3405 		ret = ERROR_IO;
3406 	}
3407 	return ret;
3408 }
3409 
fs_custom(uint32_t qcmd,const uint8_t * query,uint32_t queryleng,uint32_t * acmd,uint8_t * answer,uint32_t * answerleng)3410 uint8_t fs_custom(uint32_t qcmd,const uint8_t *query,uint32_t queryleng,uint32_t *acmd,uint8_t *answer,uint32_t *answerleng) {
3411 	uint8_t *wptr;
3412 	const uint8_t *rptr;
3413 	uint32_t i;
3414 	uint8_t ret;
3415 	threc *rec = fs_get_my_threc();
3416 	wptr = fs_createpacket(rec,qcmd,queryleng);
3417 	if (wptr==NULL) {
3418 		return ERROR_IO;
3419 	}
3420 	memcpy(wptr,query,queryleng);
3421 	rptr = fs_sendandreceive_any(rec,acmd,&i);
3422 	if (rptr==NULL) {
3423 		ret = ERROR_IO;
3424 	} else {
3425 		if (*answerleng<i) {
3426 			ret = ERROR_EINVAL;
3427 		} else {
3428 			*answerleng = i;
3429 			memcpy(answer,rptr,i);
3430 			ret = STATUS_OK;
3431 		}
3432 	}
3433 	return ret;
3434 }
3435 
3436 /*
3437 uint8_t fs_append(uint32_t inode,uint32_t ainode,uint32_t uid,uint32_t gid) {
3438 	uint8_t *wptr;
3439 	const uint8_t *rptr;
3440 	uint32_t i;
3441 	uint8_t ret;
3442 	threc *rec = fs_get_my_threc();
3443 	wptr = fs_createpacket(rec,CLTOMA_FUSE_APPEND,16);
3444 	if (wptr==NULL) {
3445 		return ERROR_IO;
3446 	}
3447 	put32bit(&wptr,inode);
3448 	put32bit(&wptr,ainode);
3449 	put32bit(&wptr,uid);
3450 	put32bit(&wptr,gid);
3451 	rptr = fs_sendandreceive(rec,MATOCL_FUSE_APPEND,&i);
3452 	if (rptr==NULL) {
3453 		ret = ERROR_IO;
3454 	} else if (i==1) {
3455 		ret = rptr[0];
3456 	} else {
3457 		pthread_mutex_lock(&fdlock);
3458 		disconnect = 1;
3459 		pthread_mutex_unlock(&fdlock);
3460 		ret = ERROR_IO;
3461 	}
3462 	return ret;
3463 }
3464 */
3465