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 #include <stdio.h>
26 #include <stddef.h>
27 #include <time.h>
28 #include <sys/types.h>
29 #include <sys/uio.h>
30 #include <unistd.h>
31 #include <fcntl.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <syslog.h>
35 #include <errno.h>
36 #include <inttypes.h>
37 #include <netinet/in.h>
38 #include <sys/resource.h>
39 #ifdef HAVE_WRITEV
40 #include <sys/uio.h>
41 #endif
42 
43 #include "MFSCommunication.h"
44 
45 #include "datapack.h"
46 #include "matoclserv.h"
47 #include "matocsserv.h"
48 #include "matomlserv.h"
49 #include "sessions.h"
50 #include "csdb.h"
51 #include "chunks.h"
52 #include "filesystem.h"
53 #include "openfiles.h"
54 #include "metadata.h"
55 #include "random.h"
56 #include "exports.h"
57 #include "datacachemgr.h"
58 #include "charts.h"
59 #include "chartsdata.h"
60 #include "cfg.h"
61 #include "main.h"
62 #include "sockets.h"
63 #include "slogger.h"
64 #include "massert.h"
65 #include "clocks.h"
66 #include "missinglog.h"
67 
68 #define MaxPacketSize CLTOMA_MAXPACKETSIZE
69 
70 // matoclserventry.mode
71 enum {KILL,DATA,FINISH};
72 // chunklis.type
73 enum {FUSE_WRITE,FUSE_TRUNCATE};
74 
75 // #define SESSION_STATS 16
76 
77 /* CACHENOTIFY
78 // hash size should be at least 1.5 * 10000 * # of connected mounts
79 // it also should be the prime number
80 // const 10000 is defined in mfsmount/dircache.c file as DIRS_REMOVE_THRESHOLD_MAX
81 // current const is calculated as nextprime(1.5 * 10000 * 500) and is enough for up to about 500 mounts
82 #define DIRINODE_HASH_SIZE 7500013
83 */
84 
85 struct matoclserventry;
86 
87 /* CACHENOTIFY
88 // directories in external caches
89 typedef struct dirincache {
90 	struct matoclserventry *eptr;
91 	uint32_t dirinode;
92 	struct dirincache *nextnode,**prevnode;
93 	struct dirincache *nextcu,**prevcu;
94 } dirincache;
95 
96 static dirincache **dirinodehash;
97 */
98 
99 // locked chunks
100 typedef struct chunklist {
101 	uint64_t chunkid;
102 	uint64_t fleng;		// file length
103 	uint32_t qid;		// queryid for answer
104 	uint32_t inode;		// inode
105 	uint32_t uid;
106 	uint32_t gid;
107 	uint32_t auid;
108 	uint32_t agid;
109 	uint8_t type;
110 	struct chunklist *next;
111 } chunklist;
112 
113 // opened files
114 /*
115 typedef struct filelist {
116 	uint32_t inode;
117 	struct filelist *next;
118 } filelist;
119 
120 typedef struct session {
121 	uint32_t sessionid;
122 	char *info;
123 	uint32_t peerip;
124 	uint8_t newsession;
125 	uint8_t sesflags;
126 	uint8_t mingoal;
127 	uint8_t maxgoal;
128 	uint32_t mintrashtime;
129 	uint32_t maxtrashtime;
130 	uint32_t rootuid;
131 	uint32_t rootgid;
132 	uint32_t mapalluid;
133 	uint32_t mapallgid;
134 	uint32_t rootinode;
135 	uint32_t disconnected;	// 0 = connected ; other = disconnection timestamp
136 	uint32_t nsocks;	// >0 - connected (number of active connections) ; 0 - not connected
137 	uint32_t currentopstats[SESSION_STATS];
138 	uint32_t lasthouropstats[SESSION_STATS];
139 	filelist *openedfiles;
140 	struct session *next;
141 } session;
142 */
143 
144 typedef struct out_packetstruct {
145 	struct out_packetstruct *next;
146 	uint8_t *startptr;
147 	uint32_t bytesleft;
148 	uint8_t data[1];
149 } out_packetstruct;
150 
151 typedef struct in_packetstruct {
152 	struct in_packetstruct *next;
153 	uint32_t type,leng;
154 	uint8_t data[1];
155 } in_packetstruct;
156 
157 typedef struct matoclserventry {
158 	uint8_t registered;
159 	uint8_t mode;				//0 - not active, 1 - read header, 2 - read packet
160 /* CACHENOTIFY
161 	uint8_t notifications;
162 */
163 	int sock;				//socket number
164 	int32_t pdescpos;
165 	double lastread,lastwrite;		//time of last activity
166 	uint8_t input_hdr[8];
167 	uint8_t *input_startptr;
168 	uint32_t input_bytesleft;
169 	uint8_t input_end;
170 	in_packetstruct *input_packet;
171 	in_packetstruct *inputhead,**inputtail;
172 	out_packetstruct *outputhead,**outputtail;
173 	uint32_t version;
174 	uint32_t peerip;
175 
176 	uint8_t passwordrnd[32];
177 //	session *sesdata;
178 	void *sesdata;
179 	chunklist *chunkdelayedops;
180 /* CACHENOTIFY
181 	dirincache *cacheddirs;
182 */
183 //	filelist *openedfiles;
184 
185 	struct matoclserventry *next;
186 } matoclserventry;
187 
188 //static session *sessionshead=NULL;
189 static matoclserventry *matoclservhead=NULL;
190 static int lsock;
191 static int32_t lsockpdescpos;
192 static int starting;
193 
194 // from config
195 static char *ListenHost;
196 static char *ListenPort;
197 //static uint32_t SessionSustainTime;
198 //static uint32_t Timeout;
199 
200 static uint32_t stats_prcvd = 0;
201 static uint32_t stats_psent = 0;
202 static uint64_t stats_brcvd = 0;
203 static uint64_t stats_bsent = 0;
204 
matoclserv_stats(uint64_t stats[5])205 void matoclserv_stats(uint64_t stats[5]) {
206 	stats[0] = stats_prcvd;
207 	stats[1] = stats_psent;
208 	stats[2] = stats_brcvd;
209 	stats[3] = stats_bsent;
210 	stats_prcvd = 0;
211 	stats_psent = 0;
212 	stats_brcvd = 0;
213 	stats_bsent = 0;
214 }
215 
216 /* CACHENOTIFY
217 // cache notification routines
218 
219 static inline void matoclserv_dircache_init(void) {
220 	dirinodehash = (dirincache**)malloc(sizeof(dirincache*)*DIRINODE_HASH_SIZE);
221 	passert(dirinodehash);
222 }
223 
224 static inline void matoclserv_dircache_remove_entry(dirincache *dc) {
225 	*(dc->prevnode) = dc->nextnode;
226 	if (dc->nextnode) {
227 		dc->nextnode->prevnode = dc->prevnode;
228 	}
229 	*(dc->prevcu) = dc->nextcu;
230 	if (dc->nextcu) {
231 		dc->nextcu->prevcu = dc->prevcu;
232 	}
233 	free(dc);
234 }
235 
236 static inline void matoclserv_notify_add_dir(matoclserventry *eptr,uint32_t inode) {
237 	uint32_t hash = (inode*0x5F2318BD)%DIRINODE_HASH_SIZE;
238 	dirincache *dc;
239 
240 	dc = (dirincache*)malloc(sizeof(dirincache));
241 	passert(dc);
242 	dc->eptr = eptr;
243 	dc->dirinode = inode;
244 	// by inode
245 	dc->nextnode = dirinodehash[hash];
246 	dc->prevnode = (dirinodehash+hash);
247 	if (dirinodehash[hash]) {
248 		dirinodehash[hash]->prevnode = &(dc->nextnode);
249 	}
250 	dirinodehash[hash] = dc;
251 	// by eptr
252 	dc->nextcu = eptr->cacheddirs;
253 	dc->prevcu = &(eptr->cacheddirs);
254 	if (eptr->cacheddirs) {
255 		eptr->cacheddirs->prevcu = &(dc->nextcu);
256 	}
257 	eptr->cacheddirs = dc;
258 
259 //	syslog(LOG_NOTICE,"rcvd from: '%s' ; add inode: %"PRIu32,eptr->sesdata->info,inode);
260 }
261 
262 static inline void matoclserv_notify_remove_dir(matoclserventry *eptr,uint32_t inode) {
263 	uint32_t hash = (inode*0x5F2318BD)%DIRINODE_HASH_SIZE;
264 	dirincache *dc,*ndc;
265 
266 	for (dc=dirinodehash[hash] ; dc ; dc=ndc) {
267 		ndc = dc->nextnode;
268 		if (dc->eptr==eptr && dc->dirinode==inode) {
269 			matoclserv_dircache_remove_entry(dc);
270 		}
271 	}
272 //	syslog(LOG_NOTICE,"rcvd from: '%s' ; remove inode: %"PRIu32,eptr->sesdata->info,inode);
273 }
274 
275 static inline void matoclserv_notify_disconnected(matoclserventry *eptr) {
276 	while (eptr->cacheddirs) {
277 		matoclserv_dircache_remove_entry(eptr->cacheddirs);
278 	}
279 }
280 
281 static inline void matoclserv_show_notification_dirs(void) {
282 	uint32_t hash;
283 	dirincache *dc;
284 
285 	for (hash=0 ; hash<DIRINODE_HASH_SIZE ; hash++) {
286 		for (dc=dirinodehash[hash] ; dc ; dc=dc->nextnode) {
287 			syslog(LOG_NOTICE,"session: %u ; dir inode: %u",dc->eptr->sesdata->sessionid,dc->dirinode);
288 		}
289 	}
290 }
291 */
292 
293 /* new registration procedure */
294 /*
295 session* matoclserv_new_session(uint8_t newsession,uint8_t nonewid) {
296 	session *asesdata;
297 	asesdata = (session*)malloc(sizeof(session));
298 	passert(asesdata);
299 	if (newsession==0 && nonewid) {
300 		asesdata->sessionid = 0;
301 	} else {
302 		asesdata->sessionid = fs_newsessionid();
303 	}
304 	asesdata->info = NULL;
305 	asesdata->peerip = 0;
306 	asesdata->sesflags = 0;
307 	asesdata->rootuid = 0;
308 	asesdata->rootgid = 0;
309 	asesdata->mapalluid = 0;
310 	asesdata->mapallgid = 0;
311 	asesdata->newsession = newsession;
312 	asesdata->rootinode = MFS_ROOT_ID;
313 	asesdata->openedfiles = NULL;
314 	asesdata->disconnected = 0;
315 	asesdata->nsocks = 1;
316 	memset(asesdata->currentopstats,0,4*SESSION_STATS);
317 	memset(asesdata->lasthouropstats,0,4*SESSION_STATS);
318 	asesdata->next = sessionshead;
319 	sessionshead = asesdata;
320 	return asesdata;
321 }
322 
323 void matoclserv_attach_session(session* sesdata) {
324 //	syslog(LOG_NOTICE,"found: %u ; before ; nsocks: %u ; state: %u",sessionid,asesdata->nsocks,asesdata->newsession);
325 	if (sesdata->newsession>=2) {
326 		sesdata->newsession-=2;
327 	}
328 	sesdata->nsocks++;
329 //	syslog(LOG_NOTICE,"found: %u ; after ; nsocks: %u ; state: %u",sessionid,asesdata->nsocks,asesdata->newsession);
330 	sesdata->disconnected = 0;
331 }
332 
333 session* matoclserv_find_session(uint32_t sessionid) {
334 	session *asesdata;
335 	if (sessionid==0) {
336 		return NULL;
337 	}
338 	for (asesdata = sessionshead ; asesdata ; asesdata=asesdata->next) {
339 		if (asesdata->sessionid==sessionid) {
340 			return asesdata;
341 		}
342 	}
343 	return NULL;
344 }
345 
346 void matoclserv_close_session(uint32_t sessionid) {
347 	session *asesdata;
348 	if (sessionid==0) {
349 		return;
350 	}
351 	for (asesdata = sessionshead ; asesdata ; asesdata=asesdata->next) {
352 		if (asesdata->sessionid==sessionid) {
353 //			syslog(LOG_NOTICE,"close: %u ; before ; nsocks: %u ; state: %u",sessionid,asesdata->nsocks,asesdata->newsession);
354 			if (asesdata->nsocks==1 && asesdata->newsession<2) {
355 				asesdata->newsession+=2;
356 			}
357 //			syslog(LOG_NOTICE,"close: %u ; after ; nsocks: %u ; state: %u",sessionid,asesdata->nsocks,asesdata->newsession);
358 		}
359 	}
360 	return;
361 }
362 
363 void matoclserv_store_sessions() {
364 	session *asesdata;
365 	uint32_t ileng;
366 	uint8_t fsesrecord[43+SESSION_STATS*8];	// 4+4+4+4+1+1+1+4+4+4+4+4+4+SESSION_STATS*4+SESSION_STATS*4
367 	uint8_t *ptr;
368 	int i;
369 	FILE *fd;
370 
371 	fd = fopen("sessions.mfs.tmp","w");
372 	if (fd==NULL) {
373 		mfs_errlog_silent(LOG_WARNING,"can't store sessions, open error");
374 		return;
375 	}
376 	memcpy(fsesrecord,MFSSIGNATURE "S \001\006\004",8);
377 	ptr = fsesrecord+8;
378 	put16bit(&ptr,SESSION_STATS);
379 	if (fwrite(fsesrecord,10,1,fd)!=1) {
380 		syslog(LOG_WARNING,"can't store sessions, fwrite error");
381 		fclose(fd);
382 		return;
383 	}
384 	for (asesdata = sessionshead ; asesdata ; asesdata=asesdata->next) {
385 		if (asesdata->newsession==1) {
386 			ptr = fsesrecord;
387 			if (asesdata->info) {
388 				ileng = strlen(asesdata->info);
389 			} else {
390 				ileng = 0;
391 			}
392 			put32bit(&ptr,asesdata->sessionid);
393 			put32bit(&ptr,ileng);
394 			put32bit(&ptr,asesdata->peerip);
395 			put32bit(&ptr,asesdata->rootinode);
396 			put8bit(&ptr,asesdata->sesflags);
397 			put8bit(&ptr,asesdata->mingoal);
398 			put8bit(&ptr,asesdata->maxgoal);
399 			put32bit(&ptr,asesdata->mintrashtime);
400 			put32bit(&ptr,asesdata->maxtrashtime);
401 			put32bit(&ptr,asesdata->rootuid);
402 			put32bit(&ptr,asesdata->rootgid);
403 			put32bit(&ptr,asesdata->mapalluid);
404 			put32bit(&ptr,asesdata->mapallgid);
405 			for (i=0 ; i<SESSION_STATS ; i++) {
406 				put32bit(&ptr,asesdata->currentopstats[i]);
407 			}
408 			for (i=0 ; i<SESSION_STATS ; i++) {
409 				put32bit(&ptr,asesdata->lasthouropstats[i]);
410 			}
411 			if (fwrite(fsesrecord,(43+SESSION_STATS*8),1,fd)!=1) {
412 				syslog(LOG_WARNING,"can't store sessions, fwrite error");
413 				fclose(fd);
414 				return;
415 			}
416 			if (ileng>0) {
417 				if (fwrite(asesdata->info,ileng,1,fd)!=1) {
418 					syslog(LOG_WARNING,"can't store sessions, fwrite error");
419 					fclose(fd);
420 					return;
421 				}
422 			}
423 		}
424 	}
425 	if (fclose(fd)!=0) {
426 		mfs_errlog_silent(LOG_WARNING,"can't store sessions, fclose error");
427 		return;
428 	}
429 	if (rename("sessions.mfs.tmp","sessions.mfs")<0) {
430 		mfs_errlog_silent(LOG_WARNING,"can't store sessions, rename error");
431 	}
432 }
433 
434 int matoclserv_load_sessions() {
435 	session *asesdata;
436 	uint32_t ileng;
437 //	uint8_t fsesrecord[33+SESSION_STATS*8];	// 4+4+4+4+1+4+4+4+4+SESSION_STATS*4+SESSION_STATS*4
438 	uint8_t hdr[8];
439 	uint8_t *fsesrecord;
440 	const uint8_t *ptr;
441 	uint8_t mapalldata;
442 	uint8_t goaltrashdata;
443 	uint32_t i,statsinfile;
444 	int r;
445 	FILE *fd;
446 
447 	fd = fopen("sessions.mfs","r");
448 	if (fd==NULL) {
449 		mfs_errlog_silent(LOG_WARNING,"can't load sessions, fopen error");
450 		if (errno==ENOENT) {	// it's ok if file does not exist
451 			return 0;
452 		} else {
453 			return -1;
454 		}
455 	}
456 	if (fread(hdr,8,1,fd)!=1) {
457 		syslog(LOG_WARNING,"can't load sessions, fread error");
458 		fclose(fd);
459 		return -1;
460 	}
461 	if (memcmp(hdr,MFSSIGNATURE "S 1.5",8)==0) {
462 		mapalldata = 0;
463 		goaltrashdata = 0;
464 		statsinfile = 16;
465 	} else if (memcmp(hdr,MFSSIGNATURE "S \001\006\001",8)==0) {
466 		mapalldata = 1;
467 		goaltrashdata = 0;
468 		statsinfile = 16;
469 	} else if (memcmp(hdr,MFSSIGNATURE "S \001\006\002",8)==0) {
470 		mapalldata = 1;
471 		goaltrashdata = 0;
472 		statsinfile = 21;
473 	} else if (memcmp(hdr,MFSSIGNATURE "S \001\006\003",8)==0) {
474 		mapalldata = 1;
475 		goaltrashdata = 0;
476 		if (fread(hdr,2,1,fd)!=1) {
477 			syslog(LOG_WARNING,"can't load sessions, fread error");
478 			fclose(fd);
479 			return -1;
480 		}
481 		ptr = hdr;
482 		statsinfile = get16bit(&ptr);
483 	} else if (memcmp(hdr,MFSSIGNATURE "S \001\006\004",8)==0) {
484 		mapalldata = 1;
485 		goaltrashdata = 1;
486 		if (fread(hdr,2,1,fd)!=1) {
487 			syslog(LOG_WARNING,"can't load sessions, fread error");
488 			fclose(fd);
489 			return -1;
490 		}
491 		ptr = hdr;
492 		statsinfile = get16bit(&ptr);
493 	} else {
494 		syslog(LOG_WARNING,"can't load sessions, bad header");
495 		fclose(fd);
496 		return -1;
497 	}
498 
499 	if (mapalldata==0) {
500 		fsesrecord = malloc(25+statsinfile*8);
501 	} else if (goaltrashdata==0) {
502 		fsesrecord = malloc(33+statsinfile*8);
503 	} else {
504 		fsesrecord = malloc(43+statsinfile*8);
505 	}
506 	passert(fsesrecord);
507 
508 	while (!feof(fd)) {
509 		if (mapalldata==0) {
510 			r = fread(fsesrecord,25+statsinfile*8,1,fd);
511 		} else if (goaltrashdata==0) {
512 			r = fread(fsesrecord,33+statsinfile*8,1,fd);
513 		} else {
514 			r = fread(fsesrecord,43+statsinfile*8,1,fd);
515 		}
516 		if (r==1) {
517 			ptr = fsesrecord;
518 			asesdata = (session*)malloc(sizeof(session));
519 			passert(asesdata);
520 			asesdata->sessionid = get32bit(&ptr);
521 			ileng = get32bit(&ptr);
522 			asesdata->peerip = get32bit(&ptr);
523 			asesdata->rootinode = get32bit(&ptr);
524 			asesdata->sesflags = get8bit(&ptr);
525 			if (goaltrashdata) {
526 				asesdata->mingoal = get8bit(&ptr);
527 				asesdata->maxgoal = get8bit(&ptr);
528 				asesdata->mintrashtime = get32bit(&ptr);
529 				asesdata->maxtrashtime = get32bit(&ptr);
530 			} else { // set defaults (no limits)
531 				asesdata->mingoal = 1;
532 				asesdata->maxgoal = 9;
533 				asesdata->mintrashtime = 0;
534 				asesdata->maxtrashtime = UINT32_C(0xFFFFFFFF);
535 			}
536 			asesdata->rootuid = get32bit(&ptr);
537 			asesdata->rootgid = get32bit(&ptr);
538 			if (mapalldata) {
539 				asesdata->mapalluid = get32bit(&ptr);
540 				asesdata->mapallgid = get32bit(&ptr);
541 			} else {
542 				asesdata->mapalluid = 0;
543 				asesdata->mapallgid = 0;
544 			}
545 			asesdata->info = NULL;
546 			asesdata->newsession = 1;
547 			asesdata->openedfiles = NULL;
548 			asesdata->disconnected = main_time();
549 			asesdata->nsocks = 0;
550 			for (i=0 ; i<SESSION_STATS ; i++) {
551 				asesdata->currentopstats[i] = (i<statsinfile)?get32bit(&ptr):0;
552 			}
553 			if (statsinfile>SESSION_STATS) {
554 				ptr+=4*(statsinfile-SESSION_STATS);
555 			}
556 			for (i=0 ; i<SESSION_STATS ; i++) {
557 				asesdata->lasthouropstats[i] = (i<statsinfile)?get32bit(&ptr):0;
558 			}
559 			if (ileng>0) {
560 				asesdata->info = malloc(ileng+1);
561 				passert(asesdata->info);
562 				if (fread(asesdata->info,ileng,1,fd)!=1) {
563 					free(asesdata->info);
564 					free(asesdata);
565 					free(fsesrecord);
566 					syslog(LOG_WARNING,"can't load sessions, fread error");
567 					fclose(fd);
568 					return -1;
569 				}
570 				asesdata->info[ileng]=0;
571 			}
572 			asesdata->next = sessionshead;
573 			sessionshead = asesdata;
574 		}
575 		if (ferror(fd)) {
576 			free(fsesrecord);
577 			syslog(LOG_WARNING,"can't load sessions, fread error");
578 			fclose(fd);
579 			return -1;
580 		}
581 	}
582 	free(fsesrecord);
583 	syslog(LOG_NOTICE,"sessions have been loaded");
584 	fclose(fd);
585 	return 1;
586 }
587 */
588 /* old registration procedure */
589 /*
590 session* matoclserv_get_session(uint32_t sessionid) {
591 	// if sessionid==0 - create new record with next id
592 	session *asesdata;
593 
594 	if (sessionid>0) {
595 		for (asesdata = sessionshead ; asesdata ; asesdata=asesdata->next) {
596 			if (asesdata->sessionid==sessionid) {
597 				asesdata->nsocks++;
598 				asesdata->disconnected = 0;
599 				return asesdata;
600 			}
601 		}
602 	}
603 	asesdata = (session*)malloc(sizeof(session));
604 	passert(asesdata);
605 	if (sessionid==0) {
606 		asesdata->sessionid = fs_newsessionid();
607 	} else {
608 		asesdata->sessionid = sessionid;
609 	}
610 	asesdata->openedfiles = NULL;
611 	asesdata->disconnected = 0;
612 	asesdata->nsocks = 1;
613 	memset(asesdata->currentopstats,0,4*SESSION_STATS);
614 	memset(asesdata->lasthouropstats,0,4*SESSION_STATS);
615 	asesdata->next = sessionshead;
616 	sessionshead = asesdata;
617 	return asesdata;
618 }
619 */
620 
621 #if 0
622 int matoclserv_insert_openfile(session* cr,uint32_t inode) {
623 	filelist *ofptr,**ofpptr;
624 	int status;
625 
626 	ofpptr = &(cr->openedfiles);
627 	while ((ofptr=*ofpptr)) {
628 		if (ofptr->inode==inode) {
629 			return STATUS_OK;	// file already acquired - nothing to do
630 		}
631 		if (ofptr->inode>inode) {
632 			break;
633 		}
634 		ofpptr = &(ofptr->next);
635 	}
636 	status = fs_acquire(inode,cr->sessionid);
637 	if (status==STATUS_OK) {
638 		ofptr = (filelist*)malloc(sizeof(filelist));
639 		passert(ofptr);
640 		ofptr->inode = inode;
641 		ofptr->next = *ofpptr;
642 		*ofpptr = ofptr;
643 	}
644 	return status;
645 }
646 
647 void matoclserv_init_sessions(uint32_t sessionid,uint32_t inode) {
648 	session *asesdata;
649 	filelist *ofptr,**ofpptr;
650 
651 	for (asesdata = sessionshead ; asesdata && asesdata->sessionid!=sessionid; asesdata=asesdata->next) ;
652 	if (asesdata==NULL) {
653 		asesdata = (session*)malloc(sizeof(session));
654 		passert(asesdata);
655 		asesdata->sessionid = sessionid;
656 /* session created by filesystem - only for old clients (pre 1.5.13) */
657 		asesdata->info = NULL;
658 		asesdata->peerip = 0;
659 		asesdata->sesflags = 0;
660 		asesdata->mingoal = 1;
661 		asesdata->maxgoal = 9;
662 		asesdata->mintrashtime = 0;
663 		asesdata->maxtrashtime = UINT32_C(0xFFFFFFFF);
664 		asesdata->rootuid = 0;
665 		asesdata->rootgid = 0;
666 		asesdata->mapalluid = 0;
667 		asesdata->mapallgid = 0;
668 		asesdata->newsession = 0;
669 		asesdata->rootinode = MFS_ROOT_ID;
670 		asesdata->openedfiles = NULL;
671 		asesdata->disconnected = main_time();
672 		asesdata->nsocks = 0;
673 		memset(asesdata->currentopstats,0,4*SESSION_STATS);
674 		memset(asesdata->lasthouropstats,0,4*SESSION_STATS);
675 		asesdata->next = sessionshead;
676 		sessionshead = asesdata;
677 	}
678 
679 	ofpptr = &(asesdata->openedfiles);
680 	while ((ofptr=*ofpptr)) {
681 		if (ofptr->inode==inode) {
682 			return;
683 		}
684 		if (ofptr->inode>inode) {
685 			break;
686 		}
687 		ofpptr = &(ofptr->next);
688 	}
689 	ofptr = (filelist*)malloc(sizeof(filelist));
690 	passert(ofptr);
691 	ofptr->inode = inode;
692 	ofptr->next = *ofpptr;
693 	*ofpptr = ofptr;
694 }
695 #endif
696 
matoclserv_createpacket(matoclserventry * eptr,uint32_t type,uint32_t size)697 uint8_t* matoclserv_createpacket(matoclserventry *eptr,uint32_t type,uint32_t size) {
698 	out_packetstruct *outpacket;
699 	uint8_t *ptr;
700 	uint32_t psize;
701 
702 	psize = size+8;
703 	outpacket=malloc(offsetof(out_packetstruct,data)+psize);
704 	passert(outpacket);
705 	outpacket->bytesleft = psize;
706 	ptr = outpacket->data;
707 	put32bit(&ptr,type);
708 	put32bit(&ptr,size);
709 	outpacket->startptr = outpacket->data;
710 	outpacket->next = NULL;
711 	*(eptr->outputtail) = outpacket;
712 	eptr->outputtail = &(outpacket->next);
713 	return ptr;
714 }
715 
716 /*
717 int matoclserv_open_check(matoclserventry *eptr,uint32_t fid) {
718 	filelist *fl;
719 	for (fl=eptr->openedfiles ; fl ; fl=fl->next) {
720 		if (fl->fid==fid) {
721 			return 0;
722 		}
723 	}
724 	return -1;
725 }
726 */
727 
matoclserv_chunk_status(uint64_t chunkid,uint8_t status)728 void matoclserv_chunk_status(uint64_t chunkid,uint8_t status) {
729 	uint32_t qid,inode,uid,gid,auid,agid;
730 	uint64_t fleng;
731 	uint8_t type,attr[35];
732 	uint32_t version;
733 //	uint8_t rstat;
734 //	uint32_t ip;
735 //	uint16_t port;
736 	uint8_t *ptr;
737 	uint8_t count;
738 	uint8_t cs_data[100*10];
739 	chunklist *cl,**acl;
740 	matoclserventry *eptr,*eaptr;
741 
742 	eptr=NULL;
743 	qid=0;
744 	fleng=0;
745 	type=0;
746 	inode=0;
747 	uid=0;
748 	gid=0;
749 	auid=0;
750 	agid=0;
751 	for (eaptr = matoclservhead ; eaptr && eptr==NULL ; eaptr=eaptr->next) {
752 		if (eaptr->mode!=KILL) {
753 			acl = &(eaptr->chunkdelayedops);
754 			while (*acl && eptr==NULL) {
755 				cl = *acl;
756 				if (cl->chunkid==chunkid) {
757 					eptr = eaptr;
758 					qid = cl->qid;
759 					fleng = cl->fleng;
760 					type = cl->type;
761 					inode = cl->inode;
762 					uid = cl->uid;
763 					gid = cl->gid;
764 					auid = cl->auid;
765 					agid = cl->agid;
766 
767 					*acl = cl->next;
768 					free(cl);
769 				} else {
770 					acl = &(cl->next);
771 				}
772 			}
773 		}
774 	}
775 
776 	if (!eptr) {
777 		syslog(LOG_WARNING,"got chunk status, but don't want it");
778 		return;
779 	}
780 	if (status==STATUS_OK) {
781 		dcm_modify(inode,sessions_get_id(eptr->sesdata));
782 	}
783 	switch (type) {
784 	case FUSE_WRITE:
785 		if (status==STATUS_OK) {
786 			if (eptr->version>=VERSION2INT(1,7,32)) {
787 				status = chunk_get_version_and_csdata(1,chunkid,eptr->peerip,&version,&count,cs_data);
788 			} else {
789 				status = chunk_get_version_and_csdata(0,chunkid,eptr->peerip,&version,&count,cs_data);
790 			}
791 			//syslog(LOG_NOTICE,"get version for chunk %"PRIu64" -> %"PRIu32,chunkid,version);
792 		}
793 		if (status!=STATUS_OK) {
794 			ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,5);
795 			put32bit(&ptr,qid);
796 			put8bit(&ptr,status);
797 			fs_writeend(0,0,chunkid);	// ignore status - just do it.
798 			return;
799 		}
800 		if (eptr->version>=VERSION2INT(1,7,32)) {
801 			ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,25+count*10);
802 		} else {
803 			ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,24+count*6);
804 		}
805 		put32bit(&ptr,qid);
806 		if (eptr->version>=VERSION2INT(1,7,32)) {
807 			put8bit(&ptr,1);
808 		}
809 		put64bit(&ptr,fleng);
810 		put64bit(&ptr,chunkid);
811 		put32bit(&ptr,version);
812 		if (count>0) {
813 			if (eptr->version>=VERSION2INT(1,7,32)) {
814 				memcpy(ptr,cs_data,count*10);
815 			} else {
816 				memcpy(ptr,cs_data,count*6);
817 			}
818 		}
819 //		for (i=0 ; i<count ; i++) {
820 //			if (matocsserv_getlocation(sptr[i],&ip,&port)<0) {
821 //				put32bit(&ptr,0);
822 //				put16bit(&ptr,0);
823 //			} else {
824 //				put32bit(&ptr,ip);
825 //				put16bit(&ptr,port);
826 //			}
827 //		}
828 		return;
829 	case FUSE_TRUNCATE:
830 		fs_end_setlength(chunkid);
831 
832 		if (status!=STATUS_OK) {
833 			ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_TRUNCATE,5);
834 			put32bit(&ptr,qid);
835 			put8bit(&ptr,status);
836 			return;
837 		}
838 		fs_do_setlength(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,0,uid,gid,auid,agid,fleng,attr);
839 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_TRUNCATE,39);
840 		put32bit(&ptr,qid);
841 		memcpy(ptr,attr,35);
842 		return;
843 	default:
844 		syslog(LOG_WARNING,"got chunk status, but operation type is unknown");
845 	}
846 }
847 
matoclserv_cserv_list(matoclserventry * eptr,const uint8_t * data,uint32_t length)848 void matoclserv_cserv_list(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
849 	uint8_t *ptr;
850 	(void)data;
851 	if (length!=0) {
852 		syslog(LOG_NOTICE,"CLTOMA_CSERV_LIST - wrong size (%"PRIu32"/0)",length);
853 		eptr->mode = KILL;
854 		return;
855 	}
856 	ptr = matoclserv_createpacket(eptr,MATOCL_CSERV_LIST,csdb_servlist_size());
857 	csdb_servlist_data(ptr);
858 }
859 
matoclserv_cserv_command(matoclserventry * eptr,const uint8_t * data,uint32_t length)860 void matoclserv_cserv_command(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
861 	uint32_t ip;
862 	uint16_t port;
863 	uint8_t cmd,status;
864 	uint8_t *ptr;
865 	if (length!=6 && length!=7) {
866 		syslog(LOG_NOTICE,"CLTOMA_CSSERV_COMMAND - wrong size (%"PRIu32"/6|7)",length);
867 		eptr->mode = KILL;
868 		return;
869 	}
870 	if (length==7) {
871 		cmd = get8bit(&data);
872 	} else {
873 		cmd = MFS_CSSERV_COMMAND_REMOVE;
874 	}
875 	ip = get32bit(&data);
876 	port = get16bit(&data);
877 	if (cmd==MFS_CSSERV_COMMAND_REMOVE) {
878 		status = csdb_remove_server(ip,port);
879 	} else if (cmd==MFS_CSSERV_COMMAND_BACKTOWORK) {
880 		status = csdb_back_to_work(ip,port);
881 	} else if (cmd==MFS_CSSERV_COMMAND_MAINTENANCEON) {
882 		status = csdb_maintenance(ip,port,1);
883 	} else if (cmd==MFS_CSSERV_COMMAND_MAINTENANCEOFF) {
884 		status = csdb_maintenance(ip,port,0);
885 	} else {
886 		status = ERROR_EINVAL;
887 	}
888 	if (length==6) {
889 		matoclserv_createpacket(eptr,MATOCL_CSSERV_COMMAND,0);
890 	} else {
891 		ptr = matoclserv_createpacket(eptr,MATOCL_CSSERV_COMMAND,1);
892 		put8bit(&ptr,status);
893 	}
894 }
895 
matoclserv_session_list(matoclserventry * eptr,const uint8_t * data,uint32_t length)896 void matoclserv_session_list(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
897 	uint8_t *ptr;
898 //	matoclserventry *eaptr;
899 	uint32_t size; //,sessionid;
900 //	uint16_t statscnt;
901 	uint8_t vmode;
902 	(void)data;
903 	if (length!=0 && length!=1) {
904 		syslog(LOG_NOTICE,"CLTOMA_SESSION_LIST - wrong size (%"PRIu32"/0)",length);
905 		eptr->mode = KILL;
906 		return;
907 	}
908 	if (length==0) {
909 		vmode = 0;
910 	} else {
911 		vmode = get8bit(&data);
912 	}
913 	size = sessions_datasize(vmode);
914 /*
915 	size = 2;
916 	for (eaptr = matoclservhead ; eaptr ; eaptr=eaptr->next) {
917 		if (eaptr->mode!=KILL && eaptr->sesdata && eaptr->registered>0 && eaptr->registered<100) {
918 			size += 12+sessions_datasize(eaptr->sesdata,vmode);
919 		}
920 	}
921 */
922 	ptr = matoclserv_createpacket(eptr,MATOCL_SESSION_LIST,size);
923 	sessions_datafill(ptr,vmode);
924 /*
925 	statscnt = sessions_get_statscnt();
926 	put16bit(&ptr,statscnt);
927 	for (eaptr = matoclservhead ; eaptr ; eaptr=eaptr->next) {
928 		if (eaptr->mode!=KILL && eaptr->sesdata && eaptr->registered>0 && eaptr->registered<100) {
929 			sessionid = sessions_get_id(eaptr->sesdata);
930 //			tcpgetpeer(eaptr->sock,&ip,NULL);
931 			put32bit(&ptr,sessionid);
932 			put32bit(&ptr,eaptr->peerip);
933 			put32bit(&ptr,eaptr->version);
934 			size = sessions_datafill(ptr,eaptr->sesdata,vmode);
935 			ptr += size;
936 		}
937 	}
938 */
939 }
940 
matoclserv_session_command(matoclserventry * eptr,const uint8_t * data,uint32_t length)941 void matoclserv_session_command(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
942 	uint32_t sessionid;
943 	uint8_t cmd,status;
944 	uint8_t *ptr;
945 	if (length!=5) {
946 		syslog(LOG_NOTICE,"CLTOMA_SESSION_COMMAND - wrong size (%"PRIu32"/5)",length);
947 		eptr->mode = KILL;
948 		return;
949 	}
950 	cmd = get8bit(&data);
951 	sessionid = get32bit(&data);
952 	if (cmd==MFS_SESSION_COMMAND_REMOVE) {
953 		status = sessions_force_remove(sessionid);
954 	} else {
955 		status = ERROR_EINVAL;
956 	}
957 	ptr = matoclserv_createpacket(eptr,MATOCL_SESSION_COMMAND,1);
958 	put8bit(&ptr,status);
959 }
960 
matoclserv_chart(matoclserventry * eptr,const uint8_t * data,uint32_t length)961 void matoclserv_chart(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
962 	uint32_t chartid;
963 	uint8_t *ptr;
964 	uint32_t l;
965 	uint16_t w,h;
966 
967 	if (length!=4 && length!=8) {
968 		syslog(LOG_NOTICE,"CLTOAN_CHART - wrong size (%"PRIu32"/4|8)",length);
969 		eptr->mode = KILL;
970 		return;
971 	}
972 	chartid = get32bit(&data);
973 	if (length==8) {
974 		w = get16bit(&data);
975 		h = get16bit(&data);
976 	} else {
977 		w = 0;
978 		h = 0;
979 	}
980 	l = charts_make_png(chartid,w,h);
981 	ptr = matoclserv_createpacket(eptr,ANTOCL_CHART,l);
982 	if (l>0) {
983 		charts_get_png(ptr);
984 	}
985 }
986 
matoclserv_chart_data(matoclserventry * eptr,const uint8_t * data,uint32_t length)987 void matoclserv_chart_data(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
988 	uint32_t chartid;
989 	uint32_t maxentries;
990 	uint8_t *ptr;
991 	uint32_t l;
992 
993 	if (length!=4 && length!=8) {
994 		syslog(LOG_NOTICE,"CLTOAN_CHART_DATA - wrong size (%"PRIu32"/4|8)",length);
995 		eptr->mode = KILL;
996 		return;
997 	}
998 	chartid = get32bit(&data);
999 	if (length==8) {
1000 		maxentries = get32bit(&data);
1001 	} else {
1002 		maxentries = UINT32_C(0xFFFFFFFF);
1003 	}
1004 	l = charts_datasize(chartid,maxentries);
1005 	ptr = matoclserv_createpacket(eptr,ANTOCL_CHART_DATA,l);
1006 	if (l>0) {
1007 		charts_makedata(ptr,chartid,maxentries);
1008 	}
1009 }
1010 
matoclserv_get_version(matoclserventry * eptr,const uint8_t * data,uint32_t length)1011 void matoclserv_get_version(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1012 	uint32_t msgid = 0;
1013 	uint8_t *ptr;
1014 	static const char vstring[] = VERSSTR;
1015 	if (length!=0 && length!=4) {
1016 		syslog(LOG_NOTICE,"ANTOAN_GET_VERSION - wrong size (%"PRIu32"/4|0)",length);
1017 		eptr->mode = KILL;
1018 		return;
1019 	}
1020 	if (length==4) {
1021 		msgid = get32bit(&data);
1022 		ptr = matoclserv_createpacket(eptr,ANTOAN_VERSION,4+4+strlen(vstring));
1023 		put32bit(&ptr,msgid);
1024 	} else {
1025 		ptr = matoclserv_createpacket(eptr,ANTOAN_VERSION,4+strlen(vstring));
1026 	}
1027 	put16bit(&ptr,VERSMAJ);
1028 	put8bit(&ptr,VERSMID);
1029 	put8bit(&ptr,VERSMIN);
1030 	memcpy(ptr,vstring,strlen(vstring));
1031 }
1032 
matoclserv_module_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1033 void matoclserv_module_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1034 	uint32_t msgid = 0;
1035 	uint8_t *ptr;
1036 
1037 	if (length!=0 && length!=4) {
1038 		syslog(LOG_NOTICE,"ANTOAN_GET_VERSION - wrong size (%"PRIu32"/4|0)",length);
1039 		eptr->mode = KILL;
1040 		return;
1041 	}
1042 	if (length==4) {
1043 		msgid = get32bit(&data);
1044 		ptr = matoclserv_createpacket(eptr,ANTOCL_MODULE_INFO,25);
1045 		put32bit(&ptr,msgid);
1046 	} else {
1047 		ptr = matoclserv_createpacket(eptr,ANTOCL_MODULE_INFO,21);
1048 	}
1049 	put8bit(&ptr,MODULE_TYPE_MASTER);
1050 	put16bit(&ptr,VERSMAJ);
1051 	put8bit(&ptr,VERSMID);
1052 	put8bit(&ptr,VERSMIN);
1053 	put16bit(&ptr,0);
1054 	put64bit(&ptr,meta_get_fileid());
1055 	put32bit(&ptr,0);
1056 	put16bit(&ptr,0);
1057 }
1058 
matoclserv_mass_resolve_paths(matoclserventry * eptr,const uint8_t * data,uint32_t length)1059 void matoclserv_mass_resolve_paths(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1060 	static uint32_t *inodetab = NULL;
1061 	static uint32_t *psizetab = NULL;
1062 	static uint32_t tabsleng = 0;
1063 	uint32_t i,j;
1064 	uint32_t totalsize;
1065 	uint32_t psize;
1066 	uint8_t *ptr;
1067 	uint8_t status;
1068 	if ((length%4)!=0) {
1069 		syslog(LOG_NOTICE,"CLTOMA_MASS_RESOLVE_PATHS - wrong size (%"PRIu32"/N*4)",length);
1070 		eptr->mode = KILL;
1071 		return;
1072 	}
1073 	length>>=2;
1074 	if (length>tabsleng) {
1075 		if (inodetab) {
1076 			free(inodetab);
1077 		}
1078 		if (psizetab) {
1079 			free(psizetab);
1080 		}
1081 		tabsleng = ((length+0xFF)&0xFFFFFF00);
1082 		inodetab = malloc(sizeof(uint32_t)*tabsleng);
1083 		passert(inodetab);
1084 		psizetab = malloc(sizeof(uint32_t)*tabsleng);
1085 		passert(psizetab);
1086 	}
1087 	j = 0;
1088 	totalsize = 0;
1089 	while (length>0) {
1090 		i = get32bit(&data);
1091 		if (i>0) {
1092 			status = fs_get_paths_size(MFS_ROOT_ID,i,&psize);
1093 			if (status==STATUS_OK) {
1094 				inodetab[j] = i;
1095 				psizetab[j] = psize;
1096 				j++;
1097 				totalsize += 8 + psize;
1098 			}
1099 		}
1100 		length--;
1101 	}
1102 	ptr = matoclserv_createpacket(eptr,MATOCL_MASS_RESOLVE_PATHS,totalsize);
1103 	for (i=0 ; i<j ; i++) {
1104 		put32bit(&ptr,inodetab[i]);
1105 		put32bit(&ptr,psizetab[i]);
1106 		fs_get_paths_data(MFS_ROOT_ID,inodetab[i],ptr);
1107 		ptr+=psizetab[i];
1108 	}
1109 }
1110 
matoclserv_missing_chunks(matoclserventry * eptr,const uint8_t * data,uint32_t length)1111 void matoclserv_missing_chunks(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1112 	uint8_t *ptr;
1113 	uint8_t mode;
1114 	if (length!=0 && length!=1) {
1115 		syslog(LOG_NOTICE,"CLTOMA_MISSING_CHUNKS - wrong size (%"PRIu32"/0|1)",length);
1116 		eptr->mode = KILL;
1117 		return;
1118 	}
1119 	if (length==1) {
1120 		mode = get8bit(&data);
1121 	} else {
1122 		mode = 0;
1123 	}
1124 	ptr = matoclserv_createpacket(eptr,MATOCL_MISSING_CHUNKS,missing_log_getdata(NULL,mode));
1125 	missing_log_getdata(ptr,mode);
1126 }
1127 
matoclserv_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1128 void matoclserv_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1129 	uint64_t totalspace,availspace,trspace,respace;
1130 	uint64_t memusage,syscpu,usercpu;
1131 	uint32_t trnodes,renodes,inodes,dnodes,fnodes;
1132 	uint32_t chunks,chunkcopies,tdcopies;
1133 	uint32_t lsstore,lstime;
1134 	uint8_t lsstat;
1135 	uint8_t *ptr;
1136 	(void)data;
1137 	if (length!=0) {
1138 		syslog(LOG_NOTICE,"CLTOMA_INFO - wrong size (%"PRIu32"/0)",length);
1139 		eptr->mode = KILL;
1140 		return;
1141 	}
1142 	meta_info(&lsstore,&lstime,&lsstat);
1143 	fs_info(&totalspace,&availspace,&trspace,&trnodes,&respace,&renodes,&inodes,&dnodes,&fnodes);
1144 	chunk_info(&chunks,&chunkcopies,&tdcopies);
1145 	chartsdata_resusage(&memusage,&syscpu,&usercpu);
1146 	ptr = matoclserv_createpacket(eptr,MATOCL_INFO,121);
1147 	/* put32bit(&buff,VERSION): */
1148 	put16bit(&ptr,VERSMAJ);
1149 	put8bit(&ptr,VERSMID);
1150 	put8bit(&ptr,VERSMIN);
1151 	put64bit(&ptr,memusage);
1152 	put64bit(&ptr,syscpu);
1153 	put64bit(&ptr,usercpu);
1154 	put64bit(&ptr,totalspace);
1155 	put64bit(&ptr,availspace);
1156 	put64bit(&ptr,trspace);
1157 	put32bit(&ptr,trnodes);
1158 	put64bit(&ptr,respace);
1159 	put32bit(&ptr,renodes);
1160 	put32bit(&ptr,inodes);
1161 	put32bit(&ptr,dnodes);
1162 	put32bit(&ptr,fnodes);
1163 	put32bit(&ptr,chunks);
1164 	put32bit(&ptr,chunkcopies);
1165 	put32bit(&ptr,tdcopies);
1166 	put32bit(&ptr,lsstore);
1167 	put32bit(&ptr,lstime);
1168 	put8bit(&ptr,lsstat);
1169 	put8bit(&ptr,0xFF);
1170 	put8bit(&ptr,0xFF);
1171 	put8bit(&ptr,0xFF);
1172 	put8bit(&ptr,0xFF);
1173 	put32bit(&ptr,0);
1174 	put32bit(&ptr,0);
1175 	put64bit(&ptr,meta_version());
1176 }
1177 
matoclserv_memory_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1178 void matoclserv_memory_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1179 	uint8_t *ptr;
1180 	uint64_t allocated[8];
1181 	uint64_t used[8];
1182 	(void)data;
1183 	if (length!=0) {
1184 		syslog(LOG_NOTICE,"CLTOMA_MEMORY_INFO - wrong size (%"PRIu32"/0)",length);
1185 		eptr->mode = KILL;
1186 		return;
1187 	}
1188 	ptr = matoclserv_createpacket(eptr,MATOCL_MEMORY_INFO,176);
1189 	chunk_get_memusage(allocated,used);
1190 	put64bit(&ptr,allocated[0]);
1191 	put64bit(&ptr,used[0]);
1192 	put64bit(&ptr,allocated[1]);
1193 	put64bit(&ptr,used[1]);
1194 	put64bit(&ptr,allocated[2]);
1195 	put64bit(&ptr,used[2]);
1196 	fs_get_memusage(allocated,used);
1197 	put64bit(&ptr,allocated[0]);
1198 	put64bit(&ptr,used[0]);
1199 	put64bit(&ptr,allocated[1]);
1200 	put64bit(&ptr,used[1]);
1201 	put64bit(&ptr,allocated[2]);
1202 	put64bit(&ptr,used[2]);
1203 	put64bit(&ptr,allocated[3]);
1204 	put64bit(&ptr,used[3]);
1205 	put64bit(&ptr,allocated[4]);
1206 	put64bit(&ptr,used[4]);
1207 	put64bit(&ptr,allocated[5]);
1208 	put64bit(&ptr,used[5]);
1209 	put64bit(&ptr,allocated[6]);
1210 	put64bit(&ptr,used[6]);
1211 	put64bit(&ptr,allocated[7]);
1212 	put64bit(&ptr,used[7]);
1213 }
1214 
matoclserv_fstest_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1215 void matoclserv_fstest_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1216 	uint32_t loopstart,loopend,files,ugfiles,mfiles,mtfiles,msfiles,chunks,ugchunks,mchunks,msgbuffleng;
1217 	char *msgbuff;
1218 	uint8_t *ptr;
1219 	(void)data;
1220 	if (length!=0 && length!=1) {
1221 		syslog(LOG_NOTICE,"CLTOMA_FSTEST_INFO - wrong size (%"PRIu32"/0|1)",length);
1222 		eptr->mode = KILL;
1223 		return;
1224 	}
1225 	fs_test_getdata(&loopstart,&loopend,&files,&ugfiles,&mfiles,&mtfiles,&msfiles,&chunks,&ugchunks,&mchunks,&msgbuff,&msgbuffleng);
1226 	ptr = matoclserv_createpacket(eptr,MATOCL_FSTEST_INFO,msgbuffleng+((length==1)?44:36));
1227 	put32bit(&ptr,loopstart);
1228 	put32bit(&ptr,loopend);
1229 	put32bit(&ptr,files);
1230 	put32bit(&ptr,ugfiles);
1231 	put32bit(&ptr,mfiles);
1232 	if (length==1) {
1233 		put32bit(&ptr,mtfiles);
1234 		put32bit(&ptr,msfiles);
1235 	}
1236 	put32bit(&ptr,chunks);
1237 	put32bit(&ptr,ugchunks);
1238 	put32bit(&ptr,mchunks);
1239 	put32bit(&ptr,msgbuffleng);
1240 	if (msgbuffleng>0) {
1241 		memcpy(ptr,msgbuff,msgbuffleng);
1242 	}
1243 }
1244 
matoclserv_chunkstest_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1245 void matoclserv_chunkstest_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1246 	uint8_t *ptr;
1247 	(void)data;
1248 	if (length!=0) {
1249 		syslog(LOG_NOTICE,"CLTOMA_CHUNKSTEST_INFO - wrong size (%"PRIu32"/0)",length);
1250 		eptr->mode = KILL;
1251 		return;
1252 	}
1253 	ptr = matoclserv_createpacket(eptr,MATOCL_CHUNKSTEST_INFO,60);
1254 	chunk_store_info(ptr);
1255 }
1256 
matoclserv_chunks_matrix(matoclserventry * eptr,const uint8_t * data,uint32_t length)1257 void matoclserv_chunks_matrix(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1258 	uint8_t *ptr;
1259 	(void)data;
1260 	if (length>1) {
1261 		syslog(LOG_NOTICE,"CLTOMA_CHUNKS_MATRIX - wrong size (%"PRIu32"/0|1)",length);
1262 		eptr->mode = KILL;
1263 		return;
1264 	}
1265 	if (length==1) {
1266 		uint8_t matrixid;
1267 		matrixid = get8bit(&data);
1268 		ptr = matoclserv_createpacket(eptr,MATOCL_CHUNKS_MATRIX,484);
1269 		chunk_store_chunkcounters(ptr,matrixid);
1270 	} else {
1271 		uint8_t progressstatus;
1272 		ptr = matoclserv_createpacket(eptr,MATOCL_CHUNKS_MATRIX,969);
1273 		progressstatus = chunk_counters_in_progress();
1274 //		syslog(LOG_NOTICE,"progressstatus: %u",progressstatus);
1275 		put8bit(&ptr,progressstatus);
1276 		chunk_store_chunkcounters(ptr,0);
1277 		chunk_store_chunkcounters(ptr+484,1);
1278 	}
1279 }
1280 
matoclserv_quota_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1281 void matoclserv_quota_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1282 	uint8_t *ptr;
1283 	(void)data;
1284 	if (length!=0) {
1285 		syslog(LOG_NOTICE,"CLTOMA_QUOTA_INFO - wrong size (%"PRIu32"/0)",length);
1286 		eptr->mode = KILL;
1287 		return;
1288 	}
1289 	ptr = matoclserv_createpacket(eptr,MATOCL_QUOTA_INFO,fs_getquotainfo_size());
1290 	fs_getquotainfo_data(ptr);
1291 }
1292 
matoclserv_exports_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1293 void matoclserv_exports_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1294 	uint8_t *ptr;
1295 	uint8_t vmode;
1296 	if (length!=0 && length!=1) {
1297 		syslog(LOG_NOTICE,"CLTOMA_EXPORTS_INFO - wrong size (%"PRIu32"/0|1)",length);
1298 		eptr->mode = KILL;
1299 		return;
1300 	}
1301 	if (length==0) {
1302 		vmode = 0;
1303 	} else {
1304 		vmode = get8bit(&data);
1305 	}
1306 	ptr = matoclserv_createpacket(eptr,MATOCL_EXPORTS_INFO,exports_info_size(vmode));
1307 	exports_info_data(vmode,ptr);
1308 }
1309 
matoclserv_mlog_list(matoclserventry * eptr,const uint8_t * data,uint32_t length)1310 void matoclserv_mlog_list(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1311 	uint8_t *ptr;
1312 	(void)data;
1313 	if (length!=0) {
1314 		syslog(LOG_NOTICE,"CLTOMA_MLOG_LIST - wrong size (%"PRIu32"/0)",length);
1315 		eptr->mode = KILL;
1316 		return;
1317 	}
1318 	ptr = matoclserv_createpacket(eptr,MATOCL_MLOG_LIST,matomlserv_mloglist_size());
1319 	matomlserv_mloglist_data(ptr);
1320 }
1321 
1322 
1323 /* CACHENOTIFY
1324 void matoclserv_notify_attr(uint32_t dirinode,uint32_t inode,const uint8_t attr[35]) {
1325 	uint32_t hash = (dirinode*0x5F2318BD)%DIRINODE_HASH_SIZE;
1326 	dirincache *dc;
1327 	uint8_t *ptr;
1328 
1329 	for (dc=dirinodehash[hash] ; dc ; dc=dc->nextnode) {
1330 		if (dc->dirinode==dirinode) {
1331 //			syslog(LOG_NOTICE,"send to: '%s' ; attrs of inode: %"PRIu32,dc->eptr->sesdata->info,inode);
1332 			ptr = matoclserv_createpacket(dc->eptr,MATOCL_FUSE_NOTIFY_ATTR,43);
1333 			stats_notify++;
1334 			put32bit(&ptr,0);
1335 			put32bit(&ptr,inode);
1336 			memcpy(ptr,attr,35);
1337 			if (dc->eptr->sesdata) {
1338 				dc->eptr->sesdata->currentopstats[16]++;
1339 			}
1340 			dc->eptr->notifications = 1;
1341 		}
1342 	}
1343 }
1344 
1345 void matoclserv_notify_link(uint32_t dirinode,uint8_t nleng,const uint8_t *name,uint32_t inode,const uint8_t attr[35],uint32_t ts) {
1346 	uint32_t hash = (dirinode*0x5F2318BD)%DIRINODE_HASH_SIZE;
1347 	dirincache *dc;
1348 	uint8_t *ptr;
1349 
1350 	for (dc=dirinodehash[hash] ; dc ; dc=dc->nextnode) {
1351 		if (dc->dirinode==dirinode) {
1352 //			{
1353 //				char strname[256];
1354 //				memcpy(strname,name,nleng);
1355 //				strname[nleng]=0;
1356 //				syslog(LOG_NOTICE,"send to: '%s' ; new link (%"PRIu32",%s)->%"PRIu32,dc->eptr->sesdata->info,dirinode,strname,inode);
1357 //			}
1358 			ptr = matoclserv_createpacket(dc->eptr,MATOCL_FUSE_NOTIFY_LINK,52+nleng);
1359 			stats_notify++;
1360 			put32bit(&ptr,0);
1361 			put32bit(&ptr,ts);
1362 			if (dirinode==dc->eptr->sesdata->rootinode) {
1363 				put32bit(&ptr,MFS_ROOT_ID);
1364 			} else {
1365 				put32bit(&ptr,dirinode);
1366 			}
1367 			put8bit(&ptr,nleng);
1368 			memcpy(ptr,name,nleng);
1369 			ptr+=nleng;
1370 			put32bit(&ptr,inode);
1371 			memcpy(ptr,attr,35);
1372 			if (dc->eptr->sesdata) {
1373 				dc->eptr->sesdata->currentopstats[17]++;
1374 			}
1375 			dc->eptr->notifications = 1;
1376 		}
1377 	}
1378 }
1379 
1380 void matoclserv_notify_unlink(uint32_t dirinode,uint8_t nleng,const uint8_t *name,uint32_t ts) {
1381 	uint32_t hash = (dirinode*0x5F2318BD)%DIRINODE_HASH_SIZE;
1382 	dirincache *dc;
1383 	uint8_t *ptr;
1384 
1385 	for (dc=dirinodehash[hash] ; dc ; dc=dc->nextnode) {
1386 		if (dc->dirinode==dirinode) {
1387 //			{
1388 //				char strname[256];
1389 //				memcpy(strname,name,nleng);
1390 //				strname[nleng]=0;
1391 //				syslog(LOG_NOTICE,"send to: '%s' ; remove link (%"PRIu32",%s)",dc->eptr->sesdata->info,dirinode,strname);
1392 //			}
1393 			ptr = matoclserv_createpacket(dc->eptr,MATOCL_FUSE_NOTIFY_UNLINK,13+nleng);
1394 			stats_notify++;
1395 			put32bit(&ptr,0);
1396 			put32bit(&ptr,ts);
1397 			if (dirinode==dc->eptr->sesdata->rootinode) {
1398 				put32bit(&ptr,MFS_ROOT_ID);
1399 			} else {
1400 				put32bit(&ptr,dirinode);
1401 			}
1402 			put8bit(&ptr,nleng);
1403 			memcpy(ptr,name,nleng);
1404 			if (dc->eptr->sesdata) {
1405 				dc->eptr->sesdata->currentopstats[18]++;
1406 			}
1407 			dc->eptr->notifications = 1;
1408 		}
1409 	}
1410 }
1411 
1412 void matoclserv_notify_remove(uint32_t dirinode) {
1413 	uint32_t hash = (dirinode*0x5F2318BD)%DIRINODE_HASH_SIZE;
1414 	dirincache *dc;
1415 	uint8_t *ptr;
1416 
1417 	for (dc=dirinodehash[hash] ; dc ; dc=dc->nextnode) {
1418 		if (dc->dirinode==dirinode) {
1419 //			syslog(LOG_NOTICE,"send to: '%s' ; removed inode: %"PRIu32,dc->eptr->sesdata->info,dirinode);
1420 			ptr = matoclserv_createpacket(dc->eptr,MATOCL_FUSE_NOTIFY_REMOVE,8);
1421 			stats_notify++;
1422 			put32bit(&ptr,0);
1423 			if (dirinode==dc->eptr->sesdata->rootinode) {
1424 				put32bit(&ptr,MFS_ROOT_ID);
1425 			} else {
1426 				put32bit(&ptr,dirinode);
1427 			}
1428 			if (dc->eptr->sesdata) {
1429 				dc->eptr->sesdata->currentopstats[19]++;
1430 			}
1431 			dc->eptr->notifications = 1;
1432 		}
1433 	}
1434 }
1435 
1436 void matoclserv_notify_parent(uint32_t dirinode,uint32_t parent) {
1437 	uint32_t hash = (dirinode*0x5F2318BD)%DIRINODE_HASH_SIZE;
1438 	dirincache *dc;
1439 	uint8_t *ptr;
1440 
1441 	for (dc=dirinodehash[hash] ; dc ; dc=dc->nextnode) {
1442 		if (dc->dirinode==dirinode && dirinode!=dc->eptr->sesdata->rootinode) {
1443 //			syslog(LOG_NOTICE,"send to: '%s' ; new parent: %"PRIu32"->%"PRIu32,dc->eptr->sesdata->info,dirinode,parent);
1444 			ptr = matoclserv_createpacket(dc->eptr,MATOCL_FUSE_NOTIFY_PARENT,12);
1445 			stats_notify++;
1446 			put32bit(&ptr,0);
1447 			put32bit(&ptr,dirinode);
1448 			if (parent==dc->eptr->sesdata->rootinode) {
1449 				put32bit(&ptr,MFS_ROOT_ID);
1450 			} else {
1451 				put32bit(&ptr,parent);
1452 			}
1453 			if (dc->eptr->sesdata) {
1454 				dc->eptr->sesdata->currentopstats[20]++;
1455 			}
1456 			dc->eptr->notifications = 1;
1457 		}
1458 	}
1459 }
1460 */
1461 
matoclserv_fuse_register(matoclserventry * eptr,const uint8_t * data,uint32_t length)1462 void matoclserv_fuse_register(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1463 	const uint8_t *rptr;
1464 	uint8_t *wptr;
1465 	uint32_t sessionid;
1466 	uint8_t status;
1467 
1468 	if (length<64) {
1469 		syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER - wrong size (%"PRIu32"/<64)",length);
1470 		eptr->mode = KILL;
1471 		return;
1472 	}
1473 	if (memcmp(data,FUSE_REGISTER_BLOB_ACL,64)==0) {
1474 		uint32_t rootinode;
1475 		uint8_t sesflags;
1476 		uint8_t mingoal,maxgoal;
1477 		uint32_t mintrashtime,maxtrashtime;
1478 		uint32_t rootuid,rootgid;
1479 		uint32_t mapalluid,mapallgid;
1480 		uint32_t ileng,pleng;
1481 		uint8_t i,rcode;
1482 		const uint8_t *path;
1483 		const char *info;
1484 
1485 		if (length<65) {
1486 			syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL - wrong size (%"PRIu32"/<65)",length);
1487 			eptr->mode = KILL;
1488 			return;
1489 		}
1490 
1491 		rptr = data+64;
1492 		rcode = get8bit(&rptr);
1493 
1494 		if ((eptr->registered==0 && rcode==REGISTER_CLOSESESSION) || (eptr->registered && rcode!=REGISTER_CLOSESESSION)) {
1495 			syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL - wrong rcode (%d) for registered status (%d)",rcode,eptr->registered);
1496 			eptr->mode = KILL;
1497 			return;
1498 		}
1499 
1500 //		printf("rcode: %d\n",rcode);
1501 //
1502 		switch (rcode) {
1503 		case REGISTER_GETRANDOM:
1504 			if (length!=65) {
1505 				syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.1 - wrong size (%"PRIu32"/65)",length);
1506 				eptr->mode = KILL;
1507 				return;
1508 			}
1509 			wptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REGISTER,32);
1510 			for (i=0 ; i<32 ; i++) {
1511 				eptr->passwordrnd[i]=rndu8();
1512 			}
1513 			memcpy(wptr,eptr->passwordrnd,32);
1514 			return;
1515 		case REGISTER_NEWSESSION:
1516 			if (length<77) {
1517 				syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.2 - wrong size (%"PRIu32"/>=77)",length);
1518 				eptr->mode = KILL;
1519 				return;
1520 			}
1521 			if (starting) {
1522 				eptr->mode = KILL;
1523 				return;
1524 			}
1525 
1526 			eptr->version = get32bit(&rptr);
1527 			ileng = get32bit(&rptr);
1528 			if (length<77+ileng) {
1529 				syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.2 - wrong size (%"PRIu32"/>=77+ileng(%"PRIu32"))",length,ileng);
1530 				eptr->mode = KILL;
1531 				return;
1532 			}
1533 			info = (const char*)rptr;
1534 			rptr+=ileng;
1535 			pleng = get32bit(&rptr);
1536 			if (length!=77+ileng+pleng && length!=77+16+ileng+pleng) {
1537 				syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.2 - wrong size (%"PRIu32"/77+ileng(%"PRIu32")+pleng(%"PRIu32")[+16])",length,ileng,pleng);
1538 				eptr->mode = KILL;
1539 				return;
1540 			}
1541 			path = rptr;
1542 			rptr+=pleng;
1543 			if (pleng>0 && rptr[-1]!=0) {
1544 				syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.2 - received path without ending zero");
1545 				eptr->mode = KILL;
1546 				return;
1547 			}
1548 			if (pleng==0) {
1549 				path = (const uint8_t*)"";
1550 			}
1551 			if (length==77+16+ileng+pleng) {
1552 				status = exports_check(eptr->peerip,eptr->version,0,path,eptr->passwordrnd,rptr,&sesflags,&rootuid,&rootgid,&mapalluid,&mapallgid,&mingoal,&maxgoal,&mintrashtime,&maxtrashtime);
1553 			} else {
1554 				status = exports_check(eptr->peerip,eptr->version,0,path,NULL,NULL,&sesflags,&rootuid,&rootgid,&mapalluid,&mapallgid,&mingoal,&maxgoal,&mintrashtime,&maxtrashtime);
1555 			}
1556 			if (status==STATUS_OK) {
1557 				status = fs_getrootinode(&rootinode,path);
1558 			}
1559 			if (status==STATUS_OK) {
1560 				eptr->sesdata = sessions_new_session(rootinode,sesflags,rootuid,rootgid,mapalluid,mapallgid,mingoal,maxgoal,mintrashtime,maxtrashtime,eptr->peerip,info,ileng);
1561 				if (eptr->sesdata==NULL) {
1562 					syslog(LOG_NOTICE,"can't allocate session record");
1563 					eptr->mode = KILL;
1564 					return;
1565 				}
1566 			}
1567 			wptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REGISTER,(status==STATUS_OK)?((eptr->version>=VERSION2INT(1,6,26))?35:(eptr->version>=VERSION2INT(1,6,21))?25:(eptr->version>=VERSION2INT(1,6,1))?21:13):1);
1568 			if (status!=STATUS_OK) {
1569 				put8bit(&wptr,status);
1570 				eptr->sesdata = NULL;
1571 				return;
1572 			}
1573 			sessionid = sessions_get_id(eptr->sesdata);
1574 			if (eptr->version==VERSION2INT(1,6,21)) {
1575 				put32bit(&wptr,0);
1576 			} else if (eptr->version>=VERSION2INT(1,6,22)) {
1577 				put16bit(&wptr,VERSMAJ);
1578 				put8bit(&wptr,VERSMID);
1579 				put8bit(&wptr,VERSMIN);
1580 			}
1581 			put32bit(&wptr,sessionid);
1582 			put8bit(&wptr,sesflags);
1583 			put32bit(&wptr,rootuid);
1584 			put32bit(&wptr,rootgid);
1585 			if (eptr->version>=VERSION2INT(1,6,1)) {
1586 				put32bit(&wptr,mapalluid);
1587 				put32bit(&wptr,mapallgid);
1588 			}
1589 			if (eptr->version>=VERSION2INT(1,6,26)) {
1590 				put8bit(&wptr,mingoal);
1591 				put8bit(&wptr,maxgoal);
1592 				put32bit(&wptr,mintrashtime);
1593 				put32bit(&wptr,maxtrashtime);
1594 			}
1595 			sessions_attach_session(eptr->sesdata,eptr->peerip,eptr->version);
1596 			eptr->registered = 1;
1597 			syslog(LOG_NOTICE,"created new sessionid:%"PRIu32,sessionid);
1598 			return;
1599 		case REGISTER_NEWMETASESSION:
1600 			if (length<73) {
1601 				syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.5 - wrong size (%"PRIu32"/>=73)",length);
1602 				eptr->mode = KILL;
1603 				return;
1604 			}
1605 			if (starting) {
1606 				eptr->mode = KILL;
1607 				return;
1608 			}
1609 
1610 			eptr->version = get32bit(&rptr);
1611 			ileng = get32bit(&rptr);
1612 			if (length!=73+ileng && length!=73+16+ileng) {
1613 				syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.5 - wrong size (%"PRIu32"/73+ileng(%"PRIu32")[+16])",length,ileng);
1614 				eptr->mode = KILL;
1615 				return;
1616 			}
1617 			info = (const char*)rptr;
1618 			rptr+=ileng;
1619 			if (length==73+16+ileng) {
1620 				status = exports_check(eptr->peerip,eptr->version,1,NULL,eptr->passwordrnd,rptr,&sesflags,&rootuid,&rootgid,&mapalluid,&mapallgid,&mingoal,&maxgoal,&mintrashtime,&maxtrashtime);
1621 			} else {
1622 				status = exports_check(eptr->peerip,eptr->version,1,NULL,NULL,NULL,&sesflags,&rootuid,&rootgid,&mapalluid,&mapallgid,&mingoal,&maxgoal,&mintrashtime,&maxtrashtime);
1623 			}
1624 			if (status==STATUS_OK) {
1625 				eptr->sesdata = sessions_new_session(0,sesflags,0,0,0,0,mingoal,maxgoal,mintrashtime,maxtrashtime,eptr->peerip,info,ileng);
1626 				if (eptr->sesdata==NULL) {
1627 					syslog(LOG_NOTICE,"can't allocate session record");
1628 					eptr->mode = KILL;
1629 					return;
1630 				}
1631 			}
1632 			wptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REGISTER,(status==STATUS_OK)?((eptr->version>=VERSION2INT(1,6,26))?19:(eptr->version>=VERSION2INT(1,6,21))?9:5):1);
1633 			if (status!=STATUS_OK) {
1634 				put8bit(&wptr,status);
1635 				eptr->sesdata = NULL;
1636 				return;
1637 			}
1638 			sessionid = sessions_get_id(eptr->sesdata);
1639 			if (eptr->version>=VERSION2INT(1,6,21)) {
1640 				put16bit(&wptr,VERSMAJ);
1641 				put8bit(&wptr,VERSMID);
1642 				put8bit(&wptr,VERSMIN);
1643 			}
1644 			put32bit(&wptr,sessionid);
1645 			put8bit(&wptr,sesflags);
1646 			if (eptr->version>=VERSION2INT(1,6,26)) {
1647 				put8bit(&wptr,mingoal);
1648 				put8bit(&wptr,maxgoal);
1649 				put32bit(&wptr,mintrashtime);
1650 				put32bit(&wptr,maxtrashtime);
1651 			}
1652 			sessions_attach_session(eptr->sesdata,eptr->peerip,eptr->version);
1653 			eptr->registered = 1;
1654 			return;
1655 		case REGISTER_RECONNECT:
1656 		case REGISTER_TOOLS:
1657 			if (length<73) {
1658 				syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.%"PRIu8" - wrong size (%"PRIu32"/73)",rcode,length);
1659 				eptr->mode = KILL;
1660 				return;
1661 			}
1662 
1663 			sessionid = get32bit(&rptr);
1664 			if (starting) {
1665 				eptr->mode = KILL;
1666 				return;
1667 			}
1668 
1669 			eptr->version = get32bit(&rptr);
1670 			eptr->sesdata = sessions_find_session(sessionid);
1671 			if (eptr->sesdata==NULL || sessions_get_peerip(eptr->sesdata)==0) { // no such session or session created by entries in metadata
1672 				status = ERROR_BADSESSIONID;
1673 			} else {
1674 				if ((sessions_get_sesflags(eptr->sesdata)&SESFLAG_DYNAMICIP)==0 && eptr->peerip!=sessions_get_peerip(eptr->sesdata)) {
1675 					status = ERROR_EACCES;
1676 				} else {
1677 					status = STATUS_OK;
1678 				}
1679 			}
1680 			wptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REGISTER,1);
1681 			put8bit(&wptr,status);
1682 			if (status!=STATUS_OK) {
1683 				eptr->sesdata = NULL;
1684 				return;
1685 			}
1686 			sessions_attach_session(eptr->sesdata,eptr->peerip,eptr->version);
1687 			eptr->registered = (rcode==3)?1:100;
1688 			return;
1689 		case REGISTER_CLOSESESSION:
1690 			if (length<69) {
1691 				syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.6 - wrong size (%"PRIu32"/69)",length);
1692 				eptr->mode = KILL;
1693 				return;
1694 			}
1695 			sessionid = get32bit(&rptr);
1696 			sessions_close_session(sessionid);
1697 			if (eptr->version>=VERSION2INT(1,7,29)) {
1698 				wptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REGISTER,1);
1699 				put8bit(&wptr,0);
1700 			}
1701 			eptr->mode = FINISH;
1702 			return;
1703 		}
1704 		syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL - wrong rcode (%"PRIu8")",rcode);
1705 		eptr->mode = KILL;
1706 		return;
1707 	} else {
1708 		syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER - wrong register blob");
1709 		eptr->mode = KILL;
1710 		return;
1711 	}
1712 }
1713 
matoclserv_fuse_sustained_inodes(matoclserventry * eptr,const uint8_t * data,uint32_t length)1714 void matoclserv_fuse_sustained_inodes(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1715 	const uint8_t *rptr;
1716 	static uint32_t *inodetab = NULL;
1717 	static uint32_t inodetabsize = 0;
1718 	uint32_t i,j;
1719 
1720 	if ((length&0x3)!=0) {
1721 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SUSTAINED_INODES - wrong size (%"PRIu32"/N*4)",length);
1722 		eptr->mode = KILL;
1723 		return;
1724 	}
1725 
1726 	if (eptr->sesdata==NULL) {
1727 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SUSTAINED_INODES - session doesn't exist");
1728 		eptr->mode = KILL;
1729 		return;
1730 	}
1731 	length>>=2;
1732 	if (length>inodetabsize) {
1733 		if (inodetab) {
1734 			free(inodetab);
1735 		}
1736 		inodetabsize = ((length+0xFF)&0xFFFFFF00);
1737 		inodetab = malloc(sizeof(uint32_t)*inodetabsize);
1738 		passert(inodetab);
1739 	}
1740 	rptr = data;
1741 	j = 0;
1742 	while (length>0) {
1743 		i = get32bit(&rptr);
1744 		if (i>0) {
1745 			inodetab[j] = i;
1746 			j++;
1747 		}
1748 		length--;
1749 	}
1750 	of_sync(sessions_get_id(eptr->sesdata),inodetab,j);
1751 //	sessions_sync_open_files(eptr->sesdata,data,length>>2);
1752 }
1753 
matoclserv_gid_storage(uint32_t gids)1754 uint32_t* matoclserv_gid_storage(uint32_t gids) {
1755 	static uint32_t *gid=NULL;
1756 	static uint32_t gidleng=0;
1757 	if (gids==0) {
1758 		if (gid!=NULL) {
1759 			free(gid);
1760 		}
1761 		gidleng=0;
1762 		return NULL;
1763 	} else {
1764 		if (gidleng<gids) {
1765 			gidleng = (gids+255)&UINT32_C(0xFFFFFF00);
1766 			if (gid!=NULL) {
1767 				free(gid);
1768 			}
1769 			gid = malloc(sizeof(uint32_t)*gidleng);
1770 			passert(gid);
1771 		}
1772 		return gid;
1773 	}
1774 }
1775 
1776 /*
1777 static inline void matoclserv_ugid_remap(matoclserventry *eptr,uint32_t *auid,uint32_t *agid) {
1778 	if (*auid==0) {
1779 		*auid = eptr->sesdata->rootuid;
1780 		if (agid) {
1781 			*agid = eptr->sesdata->rootgid;
1782 		}
1783 	} else if (sessions_get_sesflags(eptr->sesdata)&SESFLAG_MAPALL) {
1784 		*auid = eptr->sesdata->mapalluid;
1785 		if (agid) {
1786 			*agid = eptr->sesdata->mapallgid;
1787 		}
1788 	}
1789 }
1790 */
1791 /*
1792 static inline void matoclserv_ugid_attr_remap(matoclserventry *eptr,uint8_t attr[35],uint32_t auid,uint32_t agid) {
1793 	uint8_t *wptr;
1794 	const uint8_t *rptr;
1795 	uint32_t fuid,fgid;
1796 	if (auid!=0 && (sessions_get_sesflags(eptr->sesdata)&SESFLAG_MAPALL)) {
1797 		rptr = attr+3;
1798 		fuid = get32bit(&rptr);
1799 		fgid = get32bit(&rptr);
1800 		fuid = (fuid==eptr->sesdata->mapalluid)?auid:0;
1801 		fgid = (fgid==eptr->sesdata->mapallgid)?agid:0;
1802 		wptr = attr+3;
1803 		put32bit(&wptr,fuid);
1804 		put32bit(&wptr,fgid);
1805 	}
1806 }
1807 */
matoclserv_fuse_statfs(matoclserventry * eptr,const uint8_t * data,uint32_t length)1808 void matoclserv_fuse_statfs(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1809 	uint64_t totalspace,availspace,trashspace,sustainedspace;
1810 	uint32_t msgid,inodes;
1811 	uint8_t *ptr;
1812 	if (length!=4) {
1813 		syslog(LOG_NOTICE,"CLTOMA_FUSE_STATFS - wrong size (%"PRIu32"/4)",length);
1814 		eptr->mode = KILL;
1815 		return;
1816 	}
1817 	msgid = get32bit(&data);
1818 	fs_statfs(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),&totalspace,&availspace,&trashspace,&sustainedspace,&inodes);
1819 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_STATFS,40);
1820 	put32bit(&ptr,msgid);
1821 	put64bit(&ptr,totalspace);
1822 	put64bit(&ptr,availspace);
1823 	put64bit(&ptr,trashspace);
1824 	put64bit(&ptr,sustainedspace);
1825 	put32bit(&ptr,inodes);
1826 	sessions_inc_stats(eptr->sesdata,0);
1827 }
1828 
matoclserv_fuse_access(matoclserventry * eptr,const uint8_t * data,uint32_t length)1829 void matoclserv_fuse_access(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1830 	uint32_t *gid;
1831 	uint32_t i;
1832 	uint32_t inode,uid,gids;
1833 	uint16_t modemask;
1834 	uint32_t msgid;
1835 	uint8_t *ptr;
1836 	uint8_t status;
1837 	if ((length&1)==1) {
1838 		if (length!=17) {
1839 			syslog(LOG_NOTICE,"CLTOMA_FUSE_ACCESS - wrong size (%"PRIu32"/17)",length);
1840 			eptr->mode = KILL;
1841 			return;
1842 		}
1843 		msgid = get32bit(&data);
1844 		inode = get32bit(&data);
1845 		uid = get32bit(&data);
1846 		gid = matoclserv_gid_storage(1);
1847 		gid[0] = get32bit(&data);
1848 		gids = 1;
1849 		sessions_ugid_remap(eptr->sesdata,&uid,gid);
1850 		modemask = get8bit(&data);
1851 	} else {
1852 		if (length<18) {
1853 			syslog(LOG_NOTICE,"CLTOMA_FUSE_ACCESS - wrong size (%"PRIu32"/18+4*N)",length);
1854 			eptr->mode = KILL;
1855 			return;
1856 		}
1857 		msgid = get32bit(&data);
1858 		inode = get32bit(&data);
1859 		uid = get32bit(&data);
1860 		gids = get32bit(&data);
1861 		if (length!=18+gids*4) {
1862 			syslog(LOG_NOTICE,"CLTOMA_FUSE_ACCESS - wrong size (%"PRIu32"/18+4*N)",length);
1863 			eptr->mode = KILL;
1864 			return;
1865 		}
1866 		gid = matoclserv_gid_storage(gids);
1867 		for (i=0 ; i<gids ; i++) {
1868 			gid[i] = get32bit(&data);
1869 		}
1870 		sessions_ugid_remap(eptr->sesdata,&uid,gid);
1871 		modemask = get16bit(&data);
1872 	}
1873 	status = fs_access(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,gids,gid,modemask);
1874 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_ACCESS,5);
1875 	put32bit(&ptr,msgid);
1876 	put8bit(&ptr,status);
1877 }
1878 
matoclserv_fuse_lookup(matoclserventry * eptr,const uint8_t * data,uint32_t length)1879 void matoclserv_fuse_lookup(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1880 	uint32_t inode,uid,gids,auid,agid;
1881 	uint32_t *gid;
1882 	uint32_t i;
1883 	uint8_t nleng;
1884 	const uint8_t *name;
1885 	uint32_t newinode;
1886 	uint8_t attr[35];
1887 	uint32_t msgid;
1888 	uint8_t *ptr;
1889 	uint8_t status;
1890 	if (length<17) {
1891 		syslog(LOG_NOTICE,"CLTOMA_FUSE_LOOKUP - wrong size (%"PRIu32")",length);
1892 		eptr->mode = KILL;
1893 		return;
1894 	}
1895 	msgid = get32bit(&data);
1896 	inode = get32bit(&data);
1897 	nleng = get8bit(&data);
1898 	if (length<17U+nleng) {
1899 		syslog(LOG_NOTICE,"CLTOMA_FUSE_LOOKUP - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
1900 		eptr->mode = KILL;
1901 		return;
1902 	}
1903 	name = data;
1904 	data += nleng;
1905 	auid = uid = get32bit(&data);
1906 	if (length==17U+nleng) {
1907 		gids = 1;
1908 		gid = matoclserv_gid_storage(gids);
1909 		agid = gid[0] = get32bit(&data);
1910 		sessions_ugid_remap(eptr->sesdata,&uid,gid);
1911 	} else {
1912 		gids = get32bit(&data);
1913 		if (length!=17U+nleng+4*gids) {
1914 			syslog(LOG_NOTICE,"CLTOMA_FUSE_LOOKUP - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
1915 			eptr->mode = KILL;
1916 			return;
1917 		}
1918 		gid = matoclserv_gid_storage(gids);
1919 		for (i=0 ; i<gids ; i++) {
1920 			gid[i] = get32bit(&data);
1921 		}
1922 		agid = gid[0];
1923 		sessions_ugid_remap(eptr->sesdata,&uid,gid);
1924 	}
1925 	status = fs_lookup(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,nleng,name,uid,gids,gid,auid,agid,&newinode,attr);
1926 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_LOOKUP,(status!=STATUS_OK)?5:43);
1927 	put32bit(&ptr,msgid);
1928 	if (status!=STATUS_OK) {
1929 		put8bit(&ptr,status);
1930 	} else {
1931 		put32bit(&ptr,newinode);
1932 		memcpy(ptr,attr,35);
1933 	}
1934 	sessions_inc_stats(eptr->sesdata,3);
1935 }
1936 
matoclserv_fuse_getattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)1937 void matoclserv_fuse_getattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1938 	uint32_t inode,uid,gid,auid,agid;
1939 	uint8_t opened;
1940 	uint8_t attr[35];
1941 	uint32_t msgid;
1942 	uint8_t *ptr;
1943 	uint8_t status;
1944 	if (length!=8 && length!=16 && length!=17) {
1945 		syslog(LOG_NOTICE,"CLTOMA_FUSE_GETATTR - wrong size (%"PRIu32"/8|16|17)",length);
1946 		eptr->mode = KILL;
1947 		return;
1948 	}
1949 	msgid = get32bit(&data);
1950 	inode = get32bit(&data);
1951 	if (length==17) {
1952 		opened = get8bit(&data);
1953 	} else {
1954 		opened = 0;
1955 	}
1956 	if (length>=16) {
1957 		auid = uid = get32bit(&data);
1958 		agid = gid = get32bit(&data);
1959 		sessions_ugid_remap(eptr->sesdata,&uid,&gid);
1960 	} else {
1961 		auid = uid = 12345;
1962 		agid = gid = 12345;
1963 	}
1964 	status = fs_getattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,opened,uid,gid,auid,agid,attr);
1965 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETATTR,(status!=STATUS_OK)?5:39);
1966 	put32bit(&ptr,msgid);
1967 	if (status!=STATUS_OK) {
1968 		put8bit(&ptr,status);
1969 	} else {
1970 		memcpy(ptr,attr,35);
1971 	}
1972 	sessions_inc_stats(eptr->sesdata,1);
1973 }
1974 
matoclserv_fuse_setattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)1975 void matoclserv_fuse_setattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1976 	uint32_t inode,uid,gids,auid,agid;
1977 	uint32_t *gid;
1978 	uint32_t i;
1979 	uint8_t opened;
1980 	uint16_t setmask;
1981 	uint8_t attr[35];
1982 	uint32_t msgid;
1983 	uint8_t *ptr;
1984 	uint8_t status;
1985 	uint8_t sugidclearmode;
1986 	uint16_t attrmode;
1987 	uint32_t attruid,attrgid,attratime,attrmtime;
1988 	if (length!=35 && length!=36 && length<37) {
1989 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SETATTR - wrong size (%"PRIu32"/35|36|37+N*4)",length);
1990 		eptr->mode = KILL;
1991 		return;
1992 	}
1993 	msgid = get32bit(&data);
1994 	inode = get32bit(&data);
1995 	if (length>=37) {
1996 		opened = get8bit(&data);
1997 	} else {
1998 		opened = 0;
1999 	}
2000 	auid = uid = get32bit(&data);
2001 	if (length<=37) {
2002 		gids = 1;
2003 		gid = matoclserv_gid_storage(gids);
2004 		agid = gid[0] = get32bit(&data);
2005 	} else {
2006 		gids = get32bit(&data);
2007 		if (length!=37+4*gids) {
2008 			syslog(LOG_NOTICE,"CLTOMA_FUSE_SETATTR - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
2009 			eptr->mode = KILL;
2010 			return;
2011 		}
2012 		gid = matoclserv_gid_storage(gids);
2013 		for (i=0 ; i<gids ; i++) {
2014 			gid[i] = get32bit(&data);
2015 		}
2016 		agid = gid[0];
2017 	}
2018 	sessions_ugid_remap(eptr->sesdata,&uid,gid);
2019 	setmask = get8bit(&data);
2020 	attrmode = get16bit(&data);
2021 	attruid = get32bit(&data);
2022 	attrgid = get32bit(&data);
2023 	attratime = get32bit(&data);
2024 	attrmtime = get32bit(&data);
2025 	if (length>=36) {
2026 		sugidclearmode = get8bit(&data);
2027 	} else {
2028 		sugidclearmode = SUGID_CLEAR_MODE_ALWAYS; // this is safest option
2029 	}
2030 	if (setmask&(SET_GOAL_FLAG|SET_LENGTH_FLAG|SET_OPENED_FLAG)) {
2031 		status = ERROR_EINVAL;
2032 	} else {
2033 		status = fs_setattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,opened,uid,gids,gid,auid,agid,setmask,attrmode,attruid,attrgid,attratime,attrmtime,sugidclearmode,attr);
2034 	}
2035 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETATTR,(status!=STATUS_OK)?5:39);
2036 	put32bit(&ptr,msgid);
2037 	if (status!=STATUS_OK) {
2038 		put8bit(&ptr,status);
2039 	} else {
2040 		memcpy(ptr,attr,35);
2041 	}
2042 	sessions_inc_stats(eptr->sesdata,2);
2043 }
2044 
matoclserv_fuse_truncate(matoclserventry * eptr,const uint8_t * data,uint32_t length)2045 void matoclserv_fuse_truncate(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2046 	uint32_t inode,uid,gids,auid,agid;
2047 	uint32_t *gid;
2048 	uint32_t i;
2049 	uint8_t attr[35];
2050 	uint32_t msgid;
2051 	uint8_t *ptr;
2052 	uint8_t flags;
2053 	uint8_t status;
2054 	uint64_t attrlength;
2055 	chunklist *cl;
2056 	uint64_t chunkid;
2057 	if (length!=24 && length<25) {
2058 		syslog(LOG_NOTICE,"CLTOMA_FUSE_TRUNCATE - wrong size (%"PRIu32"/24|25+N*4)",length);
2059 		eptr->mode = KILL;
2060 		return;
2061 	}
2062 	flags = 0;
2063 	msgid = get32bit(&data);
2064 	inode = get32bit(&data);
2065 	if (length>=25) {
2066 		flags = get8bit(&data);
2067 	}
2068 	auid = uid = get32bit(&data);
2069 	if (length<=25) {
2070 		gids = 1;
2071 		gid = matoclserv_gid_storage(gids);
2072 		agid = gid[0] = get32bit(&data);
2073 		if (length==24) {
2074 			if (uid==0 && gid[0]!=0) {	// stupid "opened" patch for old clients
2075 				flags |= TRUNCATE_FLAG_OPENED;
2076 			}
2077 		}
2078 		sessions_ugid_remap(eptr->sesdata,&uid,gid);
2079 	} else {
2080 		gids = get32bit(&data);
2081 		if (length!=25+4*gids) {
2082 			syslog(LOG_NOTICE,"CLTOMA_FUSE_TRUNCATE - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
2083 			eptr->mode = KILL;
2084 			return;
2085 		}
2086 		gid = matoclserv_gid_storage(gids);
2087 		for (i=0 ; i<gids ; i++) {
2088 			gid[i] = get32bit(&data);
2089 		}
2090 		agid = gid[0];
2091 		sessions_ugid_remap(eptr->sesdata,&uid,gid);
2092 	}
2093 	attrlength = get64bit(&data);
2094 	status = fs_try_setlength(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,flags,uid,gids,gid,auid,agid,attrlength,attr,&chunkid);
2095 	if (status==ERROR_DELAYED) {
2096 		cl = (chunklist*)malloc(sizeof(chunklist));
2097 		passert(cl);
2098 		cl->chunkid = chunkid;
2099 		cl->qid = msgid;
2100 		cl->inode = inode;
2101 		cl->uid = uid;
2102 		cl->gid = gid[0];
2103 		cl->auid = auid;
2104 		cl->agid = agid;
2105 		cl->fleng = attrlength;
2106 		cl->type = FUSE_TRUNCATE;
2107 		cl->next = eptr->chunkdelayedops;
2108 		eptr->chunkdelayedops = cl;
2109 		sessions_inc_stats(eptr->sesdata,2);
2110 		return;
2111 	}
2112 	if (status==STATUS_OK) {
2113 		status = fs_do_setlength(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,flags,uid,gid[0],auid,agid,attrlength,attr);
2114 	}
2115 	if (status==STATUS_OK) {
2116 		dcm_modify(inode,sessions_get_id(eptr->sesdata));
2117 	}
2118 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_TRUNCATE,(status!=STATUS_OK)?5:39);
2119 	put32bit(&ptr,msgid);
2120 	if (status!=STATUS_OK) {
2121 		put8bit(&ptr,status);
2122 	} else {
2123 		memcpy(ptr,attr,35);
2124 	}
2125 	sessions_inc_stats(eptr->sesdata,2);
2126 }
2127 
matoclserv_fuse_readlink(matoclserventry * eptr,const uint8_t * data,uint32_t length)2128 void matoclserv_fuse_readlink(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2129 	uint32_t inode;
2130 	uint32_t pleng;
2131 	uint8_t *path;
2132 	uint32_t msgid;
2133 	uint8_t *ptr;
2134 	uint8_t status;
2135 	if (length!=8) {
2136 		syslog(LOG_NOTICE,"CLTOMA_FUSE_READLINK - wrong size (%"PRIu32"/8)",length);
2137 		eptr->mode = KILL;
2138 		return;
2139 	}
2140 	msgid = get32bit(&data);
2141 	inode = get32bit(&data);
2142 	status = fs_readlink(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,&pleng,&path);
2143 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READLINK,(status!=STATUS_OK)?5:8+pleng+1);
2144 	put32bit(&ptr,msgid);
2145 	if (status!=STATUS_OK) {
2146 		put8bit(&ptr,status);
2147 	} else {
2148 		put32bit(&ptr,pleng+1);
2149 		if (pleng>0) {
2150 			memcpy(ptr,path,pleng);
2151 		}
2152 		ptr[pleng]=0;
2153 	}
2154 	sessions_inc_stats(eptr->sesdata,7);
2155 }
2156 
matoclserv_fuse_symlink(matoclserventry * eptr,const uint8_t * data,uint32_t length)2157 void matoclserv_fuse_symlink(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2158 	uint32_t inode;
2159 	uint8_t nleng;
2160 	const uint8_t *name,*path;
2161 	uint32_t uid,gids,auid,agid;
2162 	uint32_t *gid;
2163 	uint32_t i;
2164 	uint32_t pleng;
2165 	uint32_t newinode;
2166 	uint8_t attr[35];
2167 	uint32_t msgid;
2168 	uint8_t status;
2169 	uint8_t *ptr;
2170 	if (length<21) {
2171 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SYMLINK - wrong size (%"PRIu32")",length);
2172 		eptr->mode = KILL;
2173 		return;
2174 	}
2175 	msgid = get32bit(&data);
2176 	inode = get32bit(&data);
2177 	nleng = get8bit(&data);
2178 	if (length<21U+nleng) {
2179 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SYMLINK - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2180 		eptr->mode = KILL;
2181 		return;
2182 	}
2183 	name = data;
2184 	data += nleng;
2185 	pleng = get32bit(&data);
2186 	if (length<21U+nleng+pleng) {
2187 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SYMLINK - wrong size (%"PRIu32":nleng=%"PRIu8":pleng=%"PRIu32")",length,nleng,pleng);
2188 		eptr->mode = KILL;
2189 		return;
2190 	}
2191 	path = data;
2192 	data += pleng;
2193 	auid = uid = get32bit(&data);
2194 	if (length==21U+nleng+pleng) {
2195 		gids = 1;
2196 		gid = matoclserv_gid_storage(gids);
2197 		agid = gid[0] = get32bit(&data);
2198 	} else {
2199 		gids = get32bit(&data);
2200 		if (length!=21U+nleng+pleng+4*gids) {
2201 			syslog(LOG_NOTICE,"CLTOMA_FUSE_SYMLINK - wrong size (%"PRIu32":nleng=%"PRIu8":pleng=%"PRIu32":gids=%"PRIu32")",length,nleng,pleng,gids);
2202 			eptr->mode = KILL;
2203 			return;
2204 		}
2205 		gid = matoclserv_gid_storage(gids);
2206 		for (i=0 ; i<gids ; i++) {
2207 			gid[i] = get32bit(&data);
2208 		}
2209 		agid = gid[0];
2210 	}
2211 	sessions_ugid_remap(eptr->sesdata,&uid,gid);
2212 	while (pleng>0 && path[pleng-1]==0) {
2213 		pleng--;
2214 	}
2215 	status = fs_symlink(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,nleng,name,pleng,path,uid,gids,gid,auid,agid,&newinode,attr);
2216 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SYMLINK,(status!=STATUS_OK)?5:43);
2217 	put32bit(&ptr,msgid);
2218 	if (status!=STATUS_OK) {
2219 		put8bit(&ptr,status);
2220 	} else {
2221 		put32bit(&ptr,newinode);
2222 		memcpy(ptr,attr,35);
2223 	}
2224 	sessions_inc_stats(eptr->sesdata,6);
2225 }
2226 
matoclserv_fuse_mknod(matoclserventry * eptr,const uint8_t * data,uint32_t length)2227 void matoclserv_fuse_mknod(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2228 	uint32_t inode,uid,gids,auid,agid,rdev;
2229 	uint32_t *gid;
2230 	uint32_t i;
2231 	uint8_t nleng;
2232 	const uint8_t *name;
2233 	uint8_t type;
2234 	uint16_t mode,cumask;
2235 	uint32_t newinode;
2236 	uint8_t attr[35];
2237 	uint32_t msgid;
2238 	uint8_t *ptr;
2239 	uint8_t status;
2240 	if (length<24) {
2241 		syslog(LOG_NOTICE,"CLTOMA_FUSE_MKNOD - wrong size (%"PRIu32")",length);
2242 		eptr->mode = KILL;
2243 		return;
2244 	}
2245 	msgid = get32bit(&data);
2246 	inode = get32bit(&data);
2247 	nleng = get8bit(&data);
2248 	if (length!=24U+nleng && length<26U+nleng) {
2249 		syslog(LOG_NOTICE,"CLTOMA_FUSE_MKNOD - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2250 		eptr->mode = KILL;
2251 		return;
2252 	}
2253 	name = data;
2254 	data += nleng;
2255 	type = get8bit(&data);
2256 	mode = get16bit(&data);
2257 	if (length>=26U+nleng) {
2258 		cumask = get16bit(&data);
2259 	} else {
2260 		cumask = 0;
2261 	}
2262 	auid = uid = get32bit(&data);
2263 	if (length<=26U+nleng) {
2264 		gids = 1;
2265 		gid = matoclserv_gid_storage(gids);
2266 		agid = gid[0] = get32bit(&data);
2267 	} else {
2268 		gids = get32bit(&data);
2269 		if (length!=26U+nleng+4*gids) {
2270 			syslog(LOG_NOTICE,"CLTOMA_FUSE_MKNOD - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
2271 			eptr->mode = KILL;
2272 			return;
2273 		}
2274 		gid = matoclserv_gid_storage(gids);
2275 		for (i=0 ; i<gids ; i++) {
2276 			gid[i] = get32bit(&data);
2277 		}
2278 		agid = gid[0];
2279 	}
2280 	sessions_ugid_remap(eptr->sesdata,&uid,gid);
2281 	rdev = get32bit(&data);
2282 	status = fs_mknod(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,nleng,name,type,mode,cumask,uid,gids,gid,auid,agid,rdev,&newinode,attr);
2283 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_MKNOD,(status!=STATUS_OK)?5:43);
2284 	put32bit(&ptr,msgid);
2285 	if (status!=STATUS_OK) {
2286 		put8bit(&ptr,status);
2287 	} else {
2288 		put32bit(&ptr,newinode);
2289 		memcpy(ptr,attr,35);
2290 	}
2291 	sessions_inc_stats(eptr->sesdata,8);
2292 }
2293 
matoclserv_fuse_mkdir(matoclserventry * eptr,const uint8_t * data,uint32_t length)2294 void matoclserv_fuse_mkdir(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2295 	uint32_t inode,uid,gids,auid,agid;
2296 	uint32_t *gid;
2297 	uint32_t i;
2298 	uint8_t nleng;
2299 	const uint8_t *name;
2300 	uint16_t mode,cumask;
2301 	uint32_t newinode;
2302 	uint8_t attr[35];
2303 	uint32_t msgid;
2304 	uint8_t *ptr;
2305 	uint8_t status;
2306 	uint8_t copysgid;
2307 	if (length<19) {
2308 		syslog(LOG_NOTICE,"CLTOMA_FUSE_MKDIR - wrong size (%"PRIu32")",length);
2309 		eptr->mode = KILL;
2310 		return;
2311 	}
2312 	msgid = get32bit(&data);
2313 	inode = get32bit(&data);
2314 	nleng = get8bit(&data);
2315 	if (length!=19U+nleng && length!=20U+nleng && length<22U+nleng) {
2316 		syslog(LOG_NOTICE,"CLTOMA_FUSE_MKDIR - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2317 		eptr->mode = KILL;
2318 		return;
2319 	}
2320 	name = data;
2321 	data += nleng;
2322 	mode = get16bit(&data);
2323 	if (length>=22U+nleng) {
2324 		cumask = get16bit(&data);
2325 	} else {
2326 		cumask = 0;
2327 	}
2328 	auid = uid = get32bit(&data);
2329 	if (length<=22U+nleng) {
2330 		gids = 1;
2331 		gid = matoclserv_gid_storage(gids);
2332 		agid = gid[0] = get32bit(&data);
2333 	} else {
2334 		gids = get32bit(&data);
2335 		if (length!=22U+nleng+4*gids) {
2336 			syslog(LOG_NOTICE,"CLTOMA_FUSE_MKDIR - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
2337 			eptr->mode = KILL;
2338 			return;
2339 		}
2340 		gid = matoclserv_gid_storage(gids);
2341 		for (i=0 ; i<gids ; i++) {
2342 			gid[i] = get32bit(&data);
2343 		}
2344 		agid = gid[0];
2345 	}
2346 	sessions_ugid_remap(eptr->sesdata,&uid,gid);
2347 	if (length>20U+nleng) {
2348 		copysgid = get8bit(&data);
2349 	} else {
2350 		copysgid = 0; // by default do not copy sgid bit
2351 	}
2352 	status = fs_mkdir(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,nleng,name,mode,cumask,uid,gids,gid,auid,agid,copysgid,&newinode,attr);
2353 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_MKDIR,(status!=STATUS_OK)?5:43);
2354 	put32bit(&ptr,msgid);
2355 	if (status!=STATUS_OK) {
2356 		put8bit(&ptr,status);
2357 	} else {
2358 		put32bit(&ptr,newinode);
2359 		memcpy(ptr,attr,35);
2360 	}
2361 	sessions_inc_stats(eptr->sesdata,4);
2362 }
2363 
matoclserv_fuse_unlink(matoclserventry * eptr,const uint8_t * data,uint32_t length)2364 void matoclserv_fuse_unlink(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2365 	uint32_t inode,uid,gids;
2366 	uint32_t *gid;
2367 	uint32_t i;
2368 	uint8_t nleng;
2369 	const uint8_t *name;
2370 	uint32_t msgid;
2371 	uint8_t *ptr;
2372 	uint8_t status;
2373 	if (length<17) {
2374 		syslog(LOG_NOTICE,"CLTOMA_FUSE_UNLINK - wrong size (%"PRIu32")",length);
2375 		eptr->mode = KILL;
2376 		return;
2377 	}
2378 	msgid = get32bit(&data);
2379 	inode = get32bit(&data);
2380 	nleng = get8bit(&data);
2381 	if (length<17U+nleng) {
2382 		syslog(LOG_NOTICE,"CLTOMA_FUSE_UNLINK - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2383 		eptr->mode = KILL;
2384 		return;
2385 	}
2386 	name = data;
2387 	data += nleng;
2388 	uid = get32bit(&data);
2389 	if (length==17U+nleng) {
2390 		gids = 1;
2391 		gid = matoclserv_gid_storage(gids);
2392 		gid[0] = get32bit(&data);
2393 	} else {
2394 		gids = get32bit(&data);
2395 		if (length!=17U+nleng+4*gids) {
2396 			syslog(LOG_NOTICE,"CLTOMA_FUSE_UNLINK - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
2397 			eptr->mode = KILL;
2398 			return;
2399 		}
2400 		gid = matoclserv_gid_storage(gids);
2401 		for (i=0 ; i<gids ; i++) {
2402 			gid[i] = get32bit(&data);
2403 		}
2404 	}
2405 	sessions_ugid_remap(eptr->sesdata,&uid,gid);
2406 	status = fs_unlink(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,nleng,name,uid,gids,gid);
2407 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_UNLINK,5);
2408 	put32bit(&ptr,msgid);
2409 	put8bit(&ptr,status);
2410 	sessions_inc_stats(eptr->sesdata,9);
2411 }
2412 
matoclserv_fuse_rmdir(matoclserventry * eptr,const uint8_t * data,uint32_t length)2413 void matoclserv_fuse_rmdir(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2414 	uint32_t inode,uid,gids;
2415 	uint32_t *gid;
2416 	uint32_t i;
2417 	uint8_t nleng;
2418 	const uint8_t *name;
2419 	uint32_t msgid;
2420 	uint8_t *ptr;
2421 	uint8_t status;
2422 	if (length<17) {
2423 		syslog(LOG_NOTICE,"CLTOMA_FUSE_RMDIR - wrong size (%"PRIu32")",length);
2424 		eptr->mode = KILL;
2425 		return;
2426 	}
2427 	msgid = get32bit(&data);
2428 	inode = get32bit(&data);
2429 	nleng = get8bit(&data);
2430 	if (length<17U+nleng) {
2431 		syslog(LOG_NOTICE,"CLTOMA_FUSE_RMDIR - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2432 		eptr->mode = KILL;
2433 		return;
2434 	}
2435 	name = data;
2436 	data += nleng;
2437 	uid = get32bit(&data);
2438 	if (length==17U+nleng) {
2439 		gids = 1;
2440 		gid = matoclserv_gid_storage(gids);
2441 		gid[0] = get32bit(&data);
2442 	} else {
2443 		gids = get32bit(&data);
2444 		if (length!=17U+nleng+4*gids) {
2445 			syslog(LOG_NOTICE,"CLTOMA_FUSE_RMDIR - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
2446 			eptr->mode = KILL;
2447 			return;
2448 		}
2449 		gid = matoclserv_gid_storage(gids);
2450 		for (i=0 ; i<gids ; i++) {
2451 			gid[i] = get32bit(&data);
2452 		}
2453 	}
2454 	sessions_ugid_remap(eptr->sesdata,&uid,gid);
2455 	status = fs_rmdir(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,nleng,name,uid,gids,gid);
2456 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_RMDIR,5);
2457 	put32bit(&ptr,msgid);
2458 	put8bit(&ptr,status);
2459 	sessions_inc_stats(eptr->sesdata,5);
2460 }
2461 
matoclserv_fuse_rename(matoclserventry * eptr,const uint8_t * data,uint32_t length)2462 void matoclserv_fuse_rename(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2463 	uint32_t inode,inode_src,inode_dst;
2464 	uint8_t nleng_src,nleng_dst;
2465 	const uint8_t *name_src,*name_dst;
2466 	uint32_t uid,gids,auid,agid;
2467 	uint32_t *gid;
2468 	uint32_t i;
2469 	uint8_t attr[35];
2470 	uint32_t msgid;
2471 	uint8_t status;
2472 	uint8_t *ptr;
2473 	if (length<22) {
2474 		syslog(LOG_NOTICE,"CLTOMA_FUSE_RENAME - wrong size (%"PRIu32")",length);
2475 		eptr->mode = KILL;
2476 		return;
2477 	}
2478 	msgid = get32bit(&data);
2479 	inode_src = get32bit(&data);
2480 	nleng_src = get8bit(&data);
2481 	if (length<22U+nleng_src) {
2482 		syslog(LOG_NOTICE,"CLTOMA_FUSE_RENAME - wrong size (%"PRIu32":nleng_src=%"PRIu8")",length,nleng_src);
2483 		eptr->mode = KILL;
2484 		return;
2485 	}
2486 	name_src = data;
2487 	data += nleng_src;
2488 	inode_dst = get32bit(&data);
2489 	nleng_dst = get8bit(&data);
2490 	if (length<22U+nleng_src+nleng_dst) {
2491 		syslog(LOG_NOTICE,"CLTOMA_FUSE_RENAME - wrong size (%"PRIu32":nleng_src=%"PRIu8":nleng_dst=%"PRIu8")",length,nleng_src,nleng_dst);
2492 		eptr->mode = KILL;
2493 		return;
2494 	}
2495 	name_dst = data;
2496 	data += nleng_dst;
2497 	auid = uid = get32bit(&data);
2498 	if (length==22U+nleng_src+nleng_dst) {
2499 		gids = 1;
2500 		gid = matoclserv_gid_storage(gids);
2501 		agid = gid[0] = get32bit(&data);
2502 	} else {
2503 		gids = get32bit(&data);
2504 		if (length!=22U+nleng_src+nleng_dst+4*gids) {
2505 			syslog(LOG_NOTICE,"CLTOMA_FUSE_RENAME - wrong size (%"PRIu32":nleng_src=%"PRIu8":nleng_dst=%"PRIu8":gids=%"PRIu32")",length,nleng_src,nleng_dst,gids);
2506 			eptr->mode = KILL;
2507 			return;
2508 		}
2509 		gid = matoclserv_gid_storage(gids);
2510 		for (i=0 ; i<gids ; i++) {
2511 			gid[i] = get32bit(&data);
2512 		}
2513 		agid = gid[0];
2514 	}
2515 	sessions_ugid_remap(eptr->sesdata,&uid,gid);
2516 	status = fs_rename(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode_src,nleng_src,name_src,inode_dst,nleng_dst,name_dst,uid,gids,gid,auid,agid,&inode,attr);
2517 	if (eptr->version>=VERSION2INT(1,6,21) && status==STATUS_OK) {
2518 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_RENAME,43);
2519 	} else {
2520 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_RENAME,5);
2521 	}
2522 	put32bit(&ptr,msgid);
2523 	if (eptr->version>=VERSION2INT(1,6,21) && status==STATUS_OK) {
2524 		put32bit(&ptr,inode);
2525 		memcpy(ptr,attr,35);
2526 	} else {
2527 		put8bit(&ptr,status);
2528 	}
2529 	sessions_inc_stats(eptr->sesdata,10);
2530 }
2531 
matoclserv_fuse_link(matoclserventry * eptr,const uint8_t * data,uint32_t length)2532 void matoclserv_fuse_link(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2533 	uint32_t inode,inode_dst;
2534 	uint8_t nleng_dst;
2535 	const uint8_t *name_dst;
2536 	uint32_t uid,gids,auid,agid;
2537 	uint32_t *gid;
2538 	uint32_t i;
2539 	uint32_t newinode;
2540 	uint8_t attr[35];
2541 	uint32_t msgid;
2542 	uint8_t *ptr;
2543 	uint8_t status;
2544 	if (length<21) {
2545 		syslog(LOG_NOTICE,"CLTOMA_FUSE_LINK - wrong size (%"PRIu32")",length);
2546 		eptr->mode = KILL;
2547 		return;
2548 	}
2549 	msgid = get32bit(&data);
2550 	inode = get32bit(&data);
2551 	inode_dst = get32bit(&data);
2552 	nleng_dst = get8bit(&data);
2553 	if (length<21U+nleng_dst) {
2554 		syslog(LOG_NOTICE,"CLTOMA_FUSE_LINK - wrong size (%"PRIu32":nleng_dst=%"PRIu8")",length,nleng_dst);
2555 		eptr->mode = KILL;
2556 		return;
2557 	}
2558 	name_dst = data;
2559 	data += nleng_dst;
2560 	auid = uid = get32bit(&data);
2561 	if (length==21U+nleng_dst) {
2562 		gids = 1;
2563 		gid = matoclserv_gid_storage(gids);
2564 		agid = gid[0] = get32bit(&data);
2565 	} else {
2566 		gids = get32bit(&data);
2567 		if (length!=21U+nleng_dst+4*gids) {
2568 			syslog(LOG_NOTICE,"CLTOMA_FUSE_LINK - wrong size (%"PRIu32":nleng_dst=%"PRIu8":gids=%"PRIu32")",length,nleng_dst,gids);
2569 			eptr->mode = KILL;
2570 			return;
2571 		}
2572 		gid = matoclserv_gid_storage(gids);
2573 		for (i=0 ; i<gids ; i++) {
2574 			gid[i] = get32bit(&data);
2575 		}
2576 		agid = gid[0];
2577 	}
2578 	sessions_ugid_remap(eptr->sesdata,&uid,gid);
2579 	status = fs_link(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,inode_dst,nleng_dst,name_dst,uid,gids,gid,auid,agid,&newinode,attr);
2580 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_LINK,(status!=STATUS_OK)?5:43);
2581 	put32bit(&ptr,msgid);
2582 	if (status!=STATUS_OK) {
2583 		put8bit(&ptr,status);
2584 	} else {
2585 		put32bit(&ptr,newinode);
2586 		memcpy(ptr,attr,35);
2587 	}
2588 	sessions_inc_stats(eptr->sesdata,11);
2589 }
2590 
matoclserv_fuse_readdir(matoclserventry * eptr,const uint8_t * data,uint32_t length)2591 void matoclserv_fuse_readdir(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2592 	uint32_t inode,uid,gids,auid,agid;
2593 	uint32_t *gid;
2594 	uint32_t i;
2595 	uint8_t flags;
2596 	uint32_t msgid;
2597 	uint8_t *ptr;
2598 	uint8_t status;
2599 	uint32_t dleng;
2600 	uint32_t maxentries;
2601 	uint64_t nedgeid;
2602 	void *c1,*c2;
2603 	if (length!=16 && length!=17 && length<29) {
2604 		syslog(LOG_NOTICE,"CLTOMA_FUSE_READDIR - wrong size (%"PRIu32"/16|17|29+N*4)",length);
2605 		eptr->mode = KILL;
2606 		return;
2607 	}
2608 	msgid = get32bit(&data);
2609 	inode = get32bit(&data);
2610 	auid = uid = get32bit(&data);
2611 	if (length<=29) {
2612 		gids = 1;
2613 		gid = matoclserv_gid_storage(gids);
2614 		agid = gid[0] = get32bit(&data);
2615 	} else {
2616 		gids = get32bit(&data);
2617 		if (length!=29+4*gids) {
2618 			syslog(LOG_NOTICE,"CLTOMA_FUSE_READDIR - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
2619 			eptr->mode = KILL;
2620 			return;
2621 		}
2622 		gid = matoclserv_gid_storage(gids);
2623 		for (i=0 ; i<gids ; i++) {
2624 			gid[i] = get32bit(&data);
2625 		}
2626 		agid = gid[0];
2627 	}
2628 	sessions_ugid_remap(eptr->sesdata,&uid,gid);
2629 	if (length>=17) {
2630 		flags = get8bit(&data);
2631 	} else {
2632 		flags = 0;
2633 	}
2634 	if (length>=29) {
2635 		maxentries = get32bit(&data);
2636 		nedgeid = get64bit(&data);
2637 	} else {
2638 		maxentries = 0xFFFFFFFF;
2639 		nedgeid = 0;
2640 	}
2641 	status = fs_readdir_size(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,gids,gid,flags,maxentries,nedgeid,&c1,&c2,&dleng);
2642 	if (status!=STATUS_OK) {
2643 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READDIR,5);
2644 	} else if (length>=29) {
2645 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READDIR,12+dleng);
2646 	} else {
2647 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READDIR,4+dleng);
2648 	}
2649 	put32bit(&ptr,msgid);
2650 	if (status!=STATUS_OK) {
2651 		put8bit(&ptr,status);
2652 	} else {
2653 		if (length>=29) {
2654 			put64bit(&ptr,nedgeid);
2655 		}
2656 		fs_readdir_data(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),uid,gid[0],auid,agid,flags,maxentries,&nedgeid,c1,c2,ptr);
2657 /* CACHENOTIFY
2658 		if (flags&GETDIR_FLAG_ADDTOCACHE) {
2659 			if (inode==MFS_ROOT_ID) {
2660 				matoclserv_notify_add_dir(eptr,sessions_get_rootinode(eptr->sesdata));
2661 			} else {
2662 				matoclserv_notify_add_dir(eptr,inode);
2663 			}
2664 		}
2665 */
2666 	}
2667 	sessions_inc_stats(eptr->sesdata,12);
2668 }
2669 
2670 /* CACHENOTIFY
2671 void matoclserv_fuse_dir_removed(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2672 	uint32_t inode;
2673 	if (length%4!=0) {
2674 		syslog(LOG_NOTICE,"CLTOMA_FUSE_DIR_REMOVED - wrong size (%"PRIu32"/N*4)",length);
2675 		eptr->mode = KILL;
2676 		return;
2677 	}
2678 	if (get32bit(&data)) {
2679 		syslog(LOG_NOTICE,"CLTOMA_FUSE_DIR_REMOVED - wrong msgid");
2680 		eptr->mode = KILL;
2681 		return;
2682 	}
2683 	length-=4;
2684 	while (length) {
2685 		inode = get32bit(&data);
2686 		length-=4;
2687 		if (inode==MFS_ROOT_ID) {
2688 			matoclserv_notify_remove_dir(eptr,sessions_get_rootinode(eptr->sesdata));
2689 		} else {
2690 			matoclserv_notify_remove_dir(eptr,inode);
2691 		}
2692 	}
2693 }
2694 */
2695 
matoclserv_fuse_open(matoclserventry * eptr,const uint8_t * data,uint32_t length)2696 void matoclserv_fuse_open(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2697 	uint32_t inode,uid,gids,auid,agid;
2698 	uint32_t *gid;
2699 	uint32_t i;
2700 	uint8_t flags;
2701 	uint8_t sesflags;
2702 	uint8_t attr[35];
2703 	uint32_t msgid;
2704 	uint8_t *ptr;
2705 	uint8_t status;
2706 	int allowcache;
2707 	if (length<17) {
2708 		syslog(LOG_NOTICE,"CLTOMA_FUSE_OPEN - wrong size (%"PRIu32"/17+N*4)",length);
2709 		eptr->mode = KILL;
2710 		return;
2711 	}
2712 	msgid = get32bit(&data);
2713 	inode = get32bit(&data);
2714 	if (length==17) {
2715 		gids = 1;
2716 		gid = matoclserv_gid_storage(gids);
2717 		auid = uid = get32bit(&data);
2718 		agid = gid[0] = get32bit(&data);
2719 		sessions_ugid_remap(eptr->sesdata,&uid,gid);
2720 	} else {
2721 		auid = uid = get32bit(&data);
2722 		gids = get32bit(&data);
2723 		if (length!=17+gids*4) {
2724 			syslog(LOG_NOTICE,"CLTOMA_FUSE_OPEN - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
2725 			eptr->mode = KILL;
2726 			return;
2727 		}
2728 		gid = matoclserv_gid_storage(gids);
2729 		for (i=0 ; i<gids ; i++) {
2730 			gid[i] = get32bit(&data);
2731 		}
2732 		agid = gid[0];
2733 		sessions_ugid_remap(eptr->sesdata,&uid,gid);
2734 	}
2735 	flags = get8bit(&data);
2736 	sesflags = sessions_get_sesflags(eptr->sesdata);
2737 	status = fs_opencheck(sessions_get_rootinode(eptr->sesdata),sesflags,inode,uid,gids,gid,auid,agid,flags,attr);
2738 	if (status==STATUS_OK) {
2739 		of_openfile(sessions_get_id(eptr->sesdata),inode);
2740 	}
2741 	if (eptr->version>=VERSION2INT(1,6,9) && status==STATUS_OK) {
2742 		allowcache = dcm_open(inode,sessions_get_id(eptr->sesdata));
2743 		if (allowcache==0) {
2744 			if (sesflags&SESFLAG_ATTRBIT) {
2745 				attr[0]&=(0xFF^MATTR_ALLOWDATACACHE);
2746 			} else {
2747 				attr[1]&=(0xFF^(MATTR_ALLOWDATACACHE<<4));
2748 			}
2749 		}
2750 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_OPEN,39);
2751 	} else {
2752 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_OPEN,5);
2753 	}
2754 	put32bit(&ptr,msgid);
2755 	if (eptr->version>=VERSION2INT(1,6,9) && status==STATUS_OK) {
2756 		memcpy(ptr,attr,35);
2757 	} else {
2758 		put8bit(&ptr,status);
2759 	}
2760 	sessions_inc_stats(eptr->sesdata,13);
2761 }
2762 
matoclserv_fuse_create(matoclserventry * eptr,const uint8_t * data,uint32_t length)2763 void matoclserv_fuse_create(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2764 	uint32_t inode,uid,gids,auid,agid;
2765 	uint32_t *gid;
2766 	uint32_t i;
2767 	uint8_t nleng;
2768 	const uint8_t *name;
2769 	uint16_t mode,cumask;
2770 	uint32_t newinode;
2771 	uint8_t attr[35];
2772 	uint32_t msgid;
2773 	uint8_t *ptr;
2774 	uint8_t status;
2775 	uint8_t sesflags;
2776 	int allowcache;
2777 	if (length<19) {
2778 		syslog(LOG_NOTICE,"CLTOMA_FUSE_CREATE - wrong size (%"PRIu32")",length);
2779 		eptr->mode = KILL;
2780 		return;
2781 	}
2782 	msgid = get32bit(&data);
2783 	inode = get32bit(&data);
2784 	nleng = get8bit(&data);
2785 	if (length!=19U+nleng && length<21U+nleng) {
2786 		syslog(LOG_NOTICE,"CLTOMA_FUSE_CREATE - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2787 		eptr->mode = KILL;
2788 		return;
2789 	}
2790 	name = data;
2791 	data += nleng;
2792 	mode = get16bit(&data);
2793 	if (length>=21U+nleng) {
2794 		cumask = get16bit(&data);
2795 	} else {
2796 		cumask = 0;
2797 	}
2798 	auid = uid = get32bit(&data);
2799 	if (length<=21U+nleng) {
2800 		gids = 1;
2801 		gid = matoclserv_gid_storage(gids);
2802 		agid = gid[0] = get32bit(&data);
2803 	} else {
2804 		gids = get32bit(&data);
2805 		if (length!=21U+nleng+4*gids) {
2806 			syslog(LOG_NOTICE,"CLTOMA_FUSE_CREATE - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
2807 			eptr->mode = KILL;
2808 			return;
2809 		}
2810 		gid = matoclserv_gid_storage(gids);
2811 		for (i=0 ; i<gids ; i++) {
2812 			gid[i] = get32bit(&data);
2813 		}
2814 		agid = gid[0];
2815 	}
2816 	sessions_ugid_remap(eptr->sesdata,&uid,gid);
2817 	sesflags = sessions_get_sesflags(eptr->sesdata);
2818 	status = fs_mknod(sessions_get_rootinode(eptr->sesdata),sesflags,inode,nleng,name,TYPE_FILE,mode,cumask,uid,gids,gid,auid,agid,0,&newinode,attr);
2819 	if (status==STATUS_OK) {
2820 		of_openfile(sessions_get_id(eptr->sesdata),newinode);
2821 		allowcache = dcm_open(newinode,sessions_get_id(eptr->sesdata));
2822 		if (allowcache==0) {
2823 			if (sesflags&SESFLAG_ATTRBIT) {
2824 				attr[0]&=(0xFF^MATTR_ALLOWDATACACHE);
2825 			} else {
2826 				attr[1]&=(0xFF^(MATTR_ALLOWDATACACHE<<4));
2827 			}
2828 		}
2829 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CREATE,43);
2830 	} else {
2831 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CREATE,5);
2832 	}
2833 	put32bit(&ptr,msgid);
2834 	if (status!=STATUS_OK) {
2835 		put8bit(&ptr,status);
2836 	} else {
2837 		put32bit(&ptr,newinode);
2838 		memcpy(ptr,attr,35);
2839 	}
2840 	sessions_inc_stats(eptr->sesdata,8);
2841 	sessions_inc_stats(eptr->sesdata,13);
2842 }
2843 
matoclserv_fuse_read_chunk(matoclserventry * eptr,const uint8_t * data,uint32_t length)2844 void matoclserv_fuse_read_chunk(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2845 	uint8_t *ptr;
2846 	uint8_t status;
2847 	uint32_t inode;
2848 	uint32_t indx;
2849 	uint64_t chunkid;
2850 	uint64_t fleng;
2851 	uint32_t version;
2852 //	uint32_t ip;
2853 //	uint16_t port;
2854 	uint8_t count;
2855 	uint8_t cs_data[100*10];
2856 	uint32_t msgid;
2857 	if (length!=12) {
2858 		syslog(LOG_NOTICE,"CLTOMA_FUSE_READ_CHUNK - wrong size (%"PRIu32"/12)",length);
2859 		eptr->mode = KILL;
2860 		return;
2861 	}
2862 	msgid = get32bit(&data);
2863 	inode = get32bit(&data);
2864 	indx = get32bit(&data);
2865 //	if (matoclserv_open_check(eptr,inode)<0) {
2866 //		status = ERROR_NOTOPENED;
2867 //	} else {
2868 		status = fs_readchunk(inode,indx,&chunkid,&fleng);
2869 //	}
2870 	if (status==STATUS_OK) {
2871 		if (chunkid>0) {
2872 			if (eptr->version>=VERSION2INT(1,7,32)) {
2873 				status = chunk_get_version_and_csdata(1,chunkid,eptr->peerip,&version,&count,cs_data);
2874 			} else {
2875 				status = chunk_get_version_and_csdata(0,chunkid,eptr->peerip,&version,&count,cs_data);
2876 			}
2877 		} else {
2878 			version = 0;
2879 			count = 0;
2880 		}
2881 	}
2882 	if (status!=STATUS_OK) {
2883 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READ_CHUNK,5);
2884 		put32bit(&ptr,msgid);
2885 		put8bit(&ptr,status);
2886 		return;
2887 	}
2888 	dcm_access(inode,sessions_get_id(eptr->sesdata));
2889 	if (eptr->version>=VERSION2INT(1,7,32)) {
2890 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READ_CHUNK,25+count*10);
2891 	} else {
2892 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READ_CHUNK,24+count*6);
2893 	}
2894 	put32bit(&ptr,msgid);
2895 	if (eptr->version>=VERSION2INT(1,7,32)) {
2896 		put8bit(&ptr,1);
2897 	}
2898 	put64bit(&ptr,fleng);
2899 	put64bit(&ptr,chunkid);
2900 	put32bit(&ptr,version);
2901 	if (count>0) {
2902 		if (eptr->version>=VERSION2INT(1,7,32)) {
2903 			memcpy(ptr,cs_data,count*10);
2904 		} else {
2905 			memcpy(ptr,cs_data,count*6);
2906 		}
2907 	}
2908 	sessions_inc_stats(eptr->sesdata,14);
2909 }
2910 
matoclserv_fuse_write_chunk(matoclserventry * eptr,const uint8_t * data,uint32_t length)2911 void matoclserv_fuse_write_chunk(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2912 	uint8_t *ptr;
2913 	uint8_t status;
2914 	uint32_t inode;
2915 	uint32_t indx;
2916 	uint64_t fleng;
2917 	uint64_t chunkid;
2918 	uint32_t msgid;
2919 	uint8_t opflag;
2920 	chunklist *cl;
2921 	uint32_t version;
2922 	uint8_t count;
2923 	uint8_t cs_data[100*10];
2924 
2925 	if (length!=12) {
2926 		syslog(LOG_NOTICE,"CLTOMA_FUSE_WRITE_CHUNK - wrong size (%"PRIu32"/12)",length);
2927 		eptr->mode = KILL;
2928 		return;
2929 	}
2930 	msgid = get32bit(&data);
2931 	inode = get32bit(&data);
2932 	indx = get32bit(&data);
2933 	if (sessions_get_sesflags(eptr->sesdata)&SESFLAG_READONLY) {
2934 		status = ERROR_EROFS;
2935 	} else {
2936 		status = fs_writechunk(inode,indx,&chunkid,&fleng,&opflag);
2937 	}
2938 	if (status!=STATUS_OK) {
2939 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,5);
2940 		put32bit(&ptr,msgid);
2941 		put8bit(&ptr,status);
2942 		return;
2943 	}
2944 	if (opflag) {	// wait for operation end
2945 		cl = (chunklist*)malloc(sizeof(chunklist));
2946 		passert(cl);
2947 		cl->inode = inode;
2948 		cl->chunkid = chunkid;
2949 		cl->qid = msgid;
2950 		cl->fleng = fleng;
2951 		cl->type = FUSE_WRITE;
2952 		cl->next = eptr->chunkdelayedops;
2953 		eptr->chunkdelayedops = cl;
2954 	} else {	// return status immediately
2955 		dcm_modify(inode,sessions_get_id(eptr->sesdata));
2956 		if (eptr->version>=VERSION2INT(1,7,32)) {
2957 			status = chunk_get_version_and_csdata(1,chunkid,eptr->peerip,&version,&count,cs_data);
2958 		} else {
2959 			status = chunk_get_version_and_csdata(0,chunkid,eptr->peerip,&version,&count,cs_data);
2960 		}
2961 		if (status!=STATUS_OK) {
2962 			ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,5);
2963 			put32bit(&ptr,msgid);
2964 			put8bit(&ptr,status);
2965 			fs_writeend(0,0,chunkid);	// ignore status - just do it.
2966 			return;
2967 		}
2968 		if (eptr->version>=VERSION2INT(1,7,32)) {
2969 			ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,25+count*10);
2970 		} else {
2971 			ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,24+count*6);
2972 		}
2973 		put32bit(&ptr,msgid);
2974 		if (eptr->version>=VERSION2INT(1,7,32)) {
2975 			put8bit(&ptr,1);
2976 		}
2977 		put64bit(&ptr,fleng);
2978 		put64bit(&ptr,chunkid);
2979 		put32bit(&ptr,version);
2980 		if (count>0) {
2981 			if (eptr->version>=VERSION2INT(1,7,32)) {
2982 				memcpy(ptr,cs_data,count*10);
2983 			} else {
2984 				memcpy(ptr,cs_data,count*6);
2985 			}
2986 		}
2987 	}
2988 	sessions_inc_stats(eptr->sesdata,15);
2989 }
2990 
matoclserv_fuse_write_chunk_end(matoclserventry * eptr,const uint8_t * data,uint32_t length)2991 void matoclserv_fuse_write_chunk_end(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2992 	uint8_t *ptr;
2993 	uint32_t msgid;
2994 	uint32_t inode;
2995 	uint64_t fleng;
2996 	uint64_t chunkid;
2997 	uint8_t status;
2998 //	chunklist *cl,**acl;
2999 	if (length!=24) {
3000 		syslog(LOG_NOTICE,"CLTOMA_FUSE_WRITE_CHUNK_END - wrong size (%"PRIu32"/24)",length);
3001 		eptr->mode = KILL;
3002 		return;
3003 	}
3004 	msgid = get32bit(&data);
3005 	chunkid = get64bit(&data);
3006 	inode = get32bit(&data);
3007 	fleng = get64bit(&data);
3008 	if (sessions_get_sesflags(eptr->sesdata)&SESFLAG_READONLY) {
3009 		status = ERROR_EROFS;
3010 	} else {
3011 		status = fs_writeend(inode,fleng,chunkid);
3012 	}
3013 	dcm_modify(inode,sessions_get_id(eptr->sesdata));
3014 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK_END,5);
3015 	put32bit(&ptr,msgid);
3016 	put8bit(&ptr,status);
3017 }
3018 
matoclserv_fuse_repair(matoclserventry * eptr,const uint8_t * data,uint32_t length)3019 void matoclserv_fuse_repair(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3020 	uint32_t inode,uid,gids;
3021 	uint32_t *gid;
3022 	uint32_t i;
3023 	uint32_t msgid;
3024 	uint32_t chunksnotchanged,chunkserased,chunksrepaired;
3025 	uint8_t *ptr;
3026 	uint8_t status;
3027 	if (length<16) {
3028 		syslog(LOG_NOTICE,"CLTOMA_FUSE_REPAIR - wrong size (%"PRIu32"/16+N*4)",length);
3029 		eptr->mode = KILL;
3030 		return;
3031 	}
3032 	msgid = get32bit(&data);
3033 	inode = get32bit(&data);
3034 	uid = get32bit(&data);
3035 	if (length==16) {
3036 		gids = 1;
3037 		gid = matoclserv_gid_storage(gids);
3038 		gid[0] = get32bit(&data);
3039 	} else {
3040 		gids = get32bit(&data);
3041 		if (length!=16+4*gids) {
3042 			syslog(LOG_NOTICE,"CLTOMA_FUSE_REPAIR - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
3043 			eptr->mode = KILL;
3044 			return;
3045 		}
3046 		gid = matoclserv_gid_storage(gids);
3047 		for (i=0 ; i<gids ; i++) {
3048 			gid[i] = get32bit(&data);
3049 		}
3050 	}
3051 	sessions_ugid_remap(eptr->sesdata,&uid,gid);
3052 	status = fs_repair(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,gids,gid,&chunksnotchanged,&chunkserased,&chunksrepaired);
3053 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REPAIR,(status!=STATUS_OK)?5:16);
3054 	put32bit(&ptr,msgid);
3055 	if (status!=0) {
3056 		put8bit(&ptr,status);
3057 	} else {
3058 		put32bit(&ptr,chunksnotchanged);
3059 		put32bit(&ptr,chunkserased);
3060 		put32bit(&ptr,chunksrepaired);
3061 	}
3062 }
3063 
matoclserv_fuse_check(matoclserventry * eptr,const uint8_t * data,uint32_t length)3064 void matoclserv_fuse_check(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3065 	uint32_t inode;
3066 	uint32_t i,chunkcount[11];
3067 	uint32_t msgid;
3068 	uint8_t *ptr;
3069 	uint8_t status;
3070 	if (length!=8) {
3071 		syslog(LOG_NOTICE,"CLTOMA_FUSE_CHECK - wrong size (%"PRIu32"/8)",length);
3072 		eptr->mode = KILL;
3073 		return;
3074 	}
3075 	msgid = get32bit(&data);
3076 	inode = get32bit(&data);
3077 	status = fs_checkfile(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,chunkcount);
3078 	if (status!=STATUS_OK) {
3079 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CHECK,5);
3080 		put32bit(&ptr,msgid);
3081 		put8bit(&ptr,status);
3082 	} else {
3083 		if (eptr->version>=VERSION2INT(1,6,23)) {
3084 			ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CHECK,48);
3085 			put32bit(&ptr,msgid);
3086 			for (i=0 ; i<11 ; i++) {
3087 				put32bit(&ptr,chunkcount[i]);
3088 			}
3089 		} else {
3090 			uint8_t j;
3091 			j=0;
3092 			for (i=0 ; i<11 ; i++) {
3093 				if (chunkcount[i]>0) {
3094 					j++;
3095 				}
3096 			}
3097 			ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CHECK,4+3*j);
3098 			put32bit(&ptr,msgid);
3099 			for (i=0 ; i<11 ; i++) {
3100 				if (chunkcount[i]>0) {
3101 					put8bit(&ptr,i);
3102 					if (chunkcount[i]<=65535) {
3103 						put16bit(&ptr,chunkcount[i]);
3104 					} else {
3105 						put16bit(&ptr,65535);
3106 					}
3107 				}
3108 			}
3109 		}
3110 	}
3111 }
3112 
3113 
matoclserv_fuse_gettrashtime(matoclserventry * eptr,const uint8_t * data,uint32_t length)3114 void matoclserv_fuse_gettrashtime(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3115 	uint32_t inode;
3116 	uint8_t gmode;
3117 	void *fptr,*dptr;
3118 	uint32_t fnodes,dnodes;
3119 	uint32_t msgid;
3120 	uint8_t *ptr;
3121 	uint8_t status;
3122 	if (length!=9) {
3123 		syslog(LOG_NOTICE,"CLTOMA_FUSE_GETTRASHTIME - wrong size (%"PRIu32"/9)",length);
3124 		eptr->mode = KILL;
3125 		return;
3126 	}
3127 	msgid = get32bit(&data);
3128 	inode = get32bit(&data);
3129 	gmode = get8bit(&data);
3130 	status = fs_gettrashtime_prepare(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,gmode,&fptr,&dptr,&fnodes,&dnodes);
3131 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETTRASHTIME,(status!=STATUS_OK)?5:12+8*(fnodes+dnodes));
3132 	put32bit(&ptr,msgid);
3133 	if (status!=STATUS_OK) {
3134 		put8bit(&ptr,status);
3135 	} else {
3136 		put32bit(&ptr,fnodes);
3137 		put32bit(&ptr,dnodes);
3138 		fs_gettrashtime_store(fptr,dptr,ptr);
3139 	}
3140 }
3141 
matoclserv_fuse_settrashtime(matoclserventry * eptr,const uint8_t * data,uint32_t length)3142 void matoclserv_fuse_settrashtime(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3143 	uint32_t inode,uid,trashtime;
3144 	uint32_t msgid;
3145 	uint8_t smode;
3146 	uint32_t changed,notchanged,notpermitted;
3147 	uint8_t *ptr;
3148 	uint8_t status;
3149 	if (length!=17) {
3150 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SETTRASHTIME - wrong size (%"PRIu32"/17)",length);
3151 		eptr->mode = KILL;
3152 		return;
3153 	}
3154 	msgid = get32bit(&data);
3155 	inode = get32bit(&data);
3156 	uid = get32bit(&data);
3157 	sessions_ugid_remap(eptr->sesdata,&uid,NULL);
3158 	trashtime = get32bit(&data);
3159 	smode = get8bit(&data);
3160 	status = sessions_check_trashtime(eptr->sesdata,smode&SMODE_TMASK,trashtime);
3161 	if (status==STATUS_OK) {
3162 		status = fs_settrashtime(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,trashtime,smode,&changed,&notchanged,&notpermitted);
3163 	}
3164 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETTRASHTIME,(status!=STATUS_OK)?5:16);
3165 	put32bit(&ptr,msgid);
3166 	if (status!=STATUS_OK) {
3167 		put8bit(&ptr,status);
3168 	} else {
3169 		put32bit(&ptr,changed);
3170 		put32bit(&ptr,notchanged);
3171 		put32bit(&ptr,notpermitted);
3172 	}
3173 }
3174 
matoclserv_fuse_getgoal(matoclserventry * eptr,const uint8_t * data,uint32_t length)3175 void matoclserv_fuse_getgoal(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3176 	uint32_t inode;
3177 	uint32_t msgid;
3178 	uint32_t fgtab[10],dgtab[10];
3179 	uint8_t i,fn,dn,gmode;
3180 	uint8_t *ptr;
3181 	uint8_t status;
3182 	if (length!=9) {
3183 		syslog(LOG_NOTICE,"CLTOMA_FUSE_GETGOAL - wrong size (%"PRIu32"/9)",length);
3184 		eptr->mode = KILL;
3185 		return;
3186 	}
3187 	msgid = get32bit(&data);
3188 	inode = get32bit(&data);
3189 	gmode = get8bit(&data);
3190 	status = fs_getgoal(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,gmode,fgtab,dgtab);
3191 	fn=0;
3192 	dn=0;
3193 	if (status==STATUS_OK) {
3194 		for (i=1 ; i<10 ; i++) {
3195 			if (fgtab[i]) {
3196 				fn++;
3197 			}
3198 			if (dgtab[i]) {
3199 				dn++;
3200 			}
3201 		}
3202 	}
3203 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETGOAL,(status!=STATUS_OK)?5:6+5*(fn+dn));
3204 	put32bit(&ptr,msgid);
3205 	if (status!=STATUS_OK) {
3206 		put8bit(&ptr,status);
3207 	} else {
3208 		put8bit(&ptr,fn);
3209 		put8bit(&ptr,dn);
3210 		for (i=1 ; i<10 ; i++) {
3211 			if (fgtab[i]) {
3212 				put8bit(&ptr,i);
3213 				put32bit(&ptr,fgtab[i]);
3214 			}
3215 		}
3216 		for (i=1 ; i<10 ; i++) {
3217 			if (dgtab[i]) {
3218 				put8bit(&ptr,i);
3219 				put32bit(&ptr,dgtab[i]);
3220 			}
3221 		}
3222 	}
3223 }
3224 
matoclserv_fuse_setgoal(matoclserventry * eptr,const uint8_t * data,uint32_t length)3225 void matoclserv_fuse_setgoal(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3226 	uint32_t inode,uid;
3227 	uint32_t msgid;
3228 	uint8_t goal,smode;
3229 	uint32_t changed,notchanged,notpermitted;
3230 	uint8_t *ptr;
3231 	uint8_t status;
3232 	if (length!=14) {
3233 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SETGOAL - wrong size (%"PRIu32"/14)",length);
3234 		eptr->mode = KILL;
3235 		return;
3236 	}
3237 	msgid = get32bit(&data);
3238 	inode = get32bit(&data);
3239 	uid = get32bit(&data);
3240 	sessions_ugid_remap(eptr->sesdata,&uid,NULL);
3241 	goal = get8bit(&data);
3242 	smode = get8bit(&data);
3243 	status = sessions_check_goal(eptr->sesdata,smode&SMODE_TMASK,goal);
3244 	if (goal<1 || goal>9) {
3245 		status = ERROR_EINVAL;
3246 	}
3247 	if (status==STATUS_OK) {
3248 		status = fs_setgoal(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,goal,smode,&changed,&notchanged,&notpermitted);
3249 	}
3250 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETGOAL,(status!=STATUS_OK)?5:16);
3251 	put32bit(&ptr,msgid);
3252 	if (status!=STATUS_OK) {
3253 		put8bit(&ptr,status);
3254 	} else {
3255 		put32bit(&ptr,changed);
3256 		put32bit(&ptr,notchanged);
3257 		put32bit(&ptr,notpermitted);
3258 	}
3259 }
3260 
matoclserv_fuse_geteattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)3261 void matoclserv_fuse_geteattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3262 	uint32_t inode;
3263 	uint32_t msgid;
3264 	uint32_t feattrtab[16],deattrtab[16];
3265 	uint8_t i,fn,dn,gmode;
3266 	uint8_t *ptr;
3267 	uint8_t status;
3268 	if (length!=9) {
3269 		syslog(LOG_NOTICE,"CLTOMA_FUSE_GETEATTR - wrong size (%"PRIu32"/9)",length);
3270 		eptr->mode = KILL;
3271 		return;
3272 	}
3273 	msgid = get32bit(&data);
3274 	inode = get32bit(&data);
3275 	gmode = get8bit(&data);
3276 	status = fs_geteattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,gmode,feattrtab,deattrtab);
3277 	fn=0;
3278 	dn=0;
3279 	if (status==STATUS_OK) {
3280 		for (i=0 ; i<16 ; i++) {
3281 			if (feattrtab[i]) {
3282 				fn++;
3283 			}
3284 			if (deattrtab[i]) {
3285 				dn++;
3286 			}
3287 		}
3288 	}
3289 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETEATTR,(status!=STATUS_OK)?5:6+5*(fn+dn));
3290 	put32bit(&ptr,msgid);
3291 	if (status!=STATUS_OK) {
3292 		put8bit(&ptr,status);
3293 	} else {
3294 		put8bit(&ptr,fn);
3295 		put8bit(&ptr,dn);
3296 		for (i=0 ; i<16 ; i++) {
3297 			if (feattrtab[i]) {
3298 				put8bit(&ptr,i);
3299 				put32bit(&ptr,feattrtab[i]);
3300 			}
3301 		}
3302 		for (i=0 ; i<16 ; i++) {
3303 			if (deattrtab[i]) {
3304 				put8bit(&ptr,i);
3305 				put32bit(&ptr,deattrtab[i]);
3306 			}
3307 		}
3308 	}
3309 }
3310 
matoclserv_fuse_seteattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)3311 void matoclserv_fuse_seteattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3312 	uint32_t inode,uid;
3313 	uint32_t msgid;
3314 	uint8_t eattr,smode;
3315 	uint32_t changed,notchanged,notpermitted;
3316 	uint8_t *ptr;
3317 	uint8_t status;
3318 	if (length!=14) {
3319 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SETEATTR - wrong size (%"PRIu32"/14)",length);
3320 		eptr->mode = KILL;
3321 		return;
3322 	}
3323 	msgid = get32bit(&data);
3324 	inode = get32bit(&data);
3325 	uid = get32bit(&data);
3326 	sessions_ugid_remap(eptr->sesdata,&uid,NULL);
3327 	eattr = get8bit(&data);
3328 	smode = get8bit(&data);
3329 	status = fs_seteattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,eattr,smode,&changed,&notchanged,&notpermitted);
3330 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETEATTR,(status!=STATUS_OK)?5:16);
3331 	put32bit(&ptr,msgid);
3332 	if (status!=STATUS_OK) {
3333 		put8bit(&ptr,status);
3334 	} else {
3335 		put32bit(&ptr,changed);
3336 		put32bit(&ptr,notchanged);
3337 		put32bit(&ptr,notpermitted);
3338 	}
3339 }
3340 
matoclserv_fuse_parents(matoclserventry * eptr,const uint8_t * data,uint32_t length)3341 void matoclserv_fuse_parents(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3342 	uint32_t inode;
3343 	uint32_t msgid;
3344 	uint32_t pcount;
3345 	uint8_t *ptr;
3346 	uint8_t status;
3347 	if (length!=8) {
3348 		syslog(LOG_NOTICE,"CLTOMA_FUSE_PARENTS - wrong size (%"PRIu32"/8)",length);
3349 		eptr->mode = KILL;
3350 		return;
3351 	}
3352 	msgid = get32bit(&data);
3353 	inode = get32bit(&data);
3354 	status = fs_get_parents_count(sessions_get_rootinode(eptr->sesdata),inode,&pcount);
3355 	if (status!=STATUS_OK) {
3356 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_PARENTS,5);
3357 		put32bit(&ptr,msgid);
3358 		put8bit(&ptr,status);
3359 	} else {
3360 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_PARENTS,4+4*pcount);
3361 		put32bit(&ptr,msgid);
3362 		fs_get_parents_data(sessions_get_rootinode(eptr->sesdata),inode,ptr);
3363 	}
3364 }
3365 
matoclserv_fuse_paths(matoclserventry * eptr,const uint8_t * data,uint32_t length)3366 void matoclserv_fuse_paths(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3367 	uint32_t inode;
3368 	uint32_t msgid;
3369 	uint32_t psize;
3370 	uint8_t *ptr;
3371 	uint8_t status;
3372 	if (length!=8) {
3373 		syslog(LOG_NOTICE,"CLTOMA_FUSE_PATHS - wrong size (%"PRIu32"/8)",length);
3374 		eptr->mode = KILL;
3375 		return;
3376 	}
3377 	msgid = get32bit(&data);
3378 	inode = get32bit(&data);
3379 	status = fs_get_paths_size(sessions_get_rootinode(eptr->sesdata),inode,&psize);
3380 	if (status!=STATUS_OK) {
3381 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_PATHS,5);
3382 		put32bit(&ptr,msgid);
3383 		put8bit(&ptr,status);
3384 	} else {
3385 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_PATHS,4+psize);
3386 		put32bit(&ptr,msgid);
3387 		fs_get_paths_data(sessions_get_rootinode(eptr->sesdata),inode,ptr);
3388 	}
3389 }
3390 
matoclserv_fuse_getxattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)3391 void matoclserv_fuse_getxattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3392 	uint32_t inode,uid,gids;
3393 	uint32_t *gid;
3394 	uint32_t i;
3395 	uint32_t msgid;
3396 	uint8_t opened;
3397 	uint8_t mode;
3398 	uint8_t *ptr;
3399 	uint8_t status;
3400 	uint8_t anleng;
3401 	const uint8_t *attrname;
3402 	if (length<19) {
3403 		syslog(LOG_NOTICE,"CLTOMA_FUSE_GETXATTR - wrong size (%"PRIu32")",length);
3404 		eptr->mode = KILL;
3405 		return;
3406 	}
3407 	opened = 0; // makes gcc happy
3408 	gid = NULL; // makes gcc happy
3409 	msgid = get32bit(&data);
3410 	inode = get32bit(&data);
3411 	if (eptr->version<VERSION2INT(2,0,0)) {
3412 		opened = get8bit(&data);
3413 		uid = get32bit(&data);
3414 		gids = 1;
3415 		gid = matoclserv_gid_storage(gids);
3416 		gid[0] = get32bit(&data);
3417 	}
3418 	anleng = get8bit(&data);
3419 	attrname = data;
3420 	data+=anleng;
3421 	if (length<19U+anleng) {
3422 		syslog(LOG_NOTICE,"CLTOMA_FUSE_GETXATTR - wrong size (%"PRIu32":anleng=%"PRIu8")",length,anleng);
3423 		eptr->mode = KILL;
3424 		return;
3425 	}
3426 	mode = get8bit(&data);
3427 	if (eptr->version>=VERSION2INT(2,0,0)) {
3428 		opened = get8bit(&data);
3429 		uid = get32bit(&data);
3430 		if (length==19U+anleng) {
3431 			gids = 1;
3432 			gid = matoclserv_gid_storage(gids);
3433 			gid[0] = get32bit(&data);
3434 		} else {
3435 			gids = get32bit(&data);
3436 			if (length!=19U+anleng+4*gids) {
3437 				syslog(LOG_NOTICE,"CLTOMA_FUSE_GETXATTR - wrong size (%"PRIu32":anleng=%"PRIu8":gids=%"PRIu32")",length,anleng,gids);
3438 				eptr->mode = KILL;
3439 				return;
3440 			}
3441 			gid = matoclserv_gid_storage(gids);
3442 			for (i=0 ; i<gids ; i++) {
3443 				gid[i] = get32bit(&data);
3444 			}
3445 		}
3446 	}
3447 	sessions_ugid_remap(eptr->sesdata,&uid,gid);
3448 	if (mode!=MFS_XATTR_GETA_DATA && mode!=MFS_XATTR_LENGTH_ONLY) {
3449 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETXATTR,5);
3450 		put32bit(&ptr,msgid);
3451 		put8bit(&ptr,ERROR_EINVAL);
3452 	} else if (anleng==0) {
3453 		void *xanode;
3454 		uint32_t xasize;
3455 		status = fs_listxattr_leng(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,opened,uid,gids,gid,&xanode,&xasize);
3456 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETXATTR,(status!=STATUS_OK)?5:8+((mode==MFS_XATTR_GETA_DATA)?xasize:0));
3457 		put32bit(&ptr,msgid);
3458 		if (status!=STATUS_OK) {
3459 			put8bit(&ptr,status);
3460 		} else {
3461 			put32bit(&ptr,xasize);
3462 			if (mode==MFS_XATTR_GETA_DATA && xasize>0) {
3463 				fs_listxattr_data(xanode,ptr);
3464 			}
3465 		}
3466 	} else {
3467 		uint8_t *attrvalue;
3468 		uint32_t avleng;
3469 		status = fs_getxattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,opened,uid,gids,gid,anleng,attrname,&avleng,&attrvalue);
3470 		ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETXATTR,(status!=STATUS_OK)?5:8+((mode==MFS_XATTR_GETA_DATA)?avleng:0));
3471 		put32bit(&ptr,msgid);
3472 		if (status!=STATUS_OK) {
3473 			put8bit(&ptr,status);
3474 		} else {
3475 			put32bit(&ptr,avleng);
3476 			if (mode==MFS_XATTR_GETA_DATA && avleng>0) {
3477 				memcpy(ptr,attrvalue,avleng);
3478 			}
3479 		}
3480 	}
3481 }
3482 
matoclserv_fuse_setxattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)3483 void matoclserv_fuse_setxattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3484 	uint32_t inode,uid,gids;
3485 	uint32_t *gid;
3486 	uint32_t i;
3487 	uint32_t msgid;
3488 	const uint8_t *attrname,*attrvalue;
3489 	uint8_t opened;
3490 	uint8_t anleng;
3491 	uint32_t avleng;
3492 	uint8_t mode;
3493 	uint8_t *ptr;
3494 	uint8_t status;
3495 	if (length<23) {
3496 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SETXATTR - wrong size (%"PRIu32")",length);
3497 		eptr->mode = KILL;
3498 		return;
3499 	}
3500 	opened = 0; // makes gcc happy
3501 	gid = NULL; // makes gcc happy
3502 	msgid = get32bit(&data);
3503 	inode = get32bit(&data);
3504 	if (eptr->version<VERSION2INT(2,0,0)) {
3505 		opened = get8bit(&data);
3506 		uid = get32bit(&data);
3507 		gids = 1;
3508 		gid = matoclserv_gid_storage(gids);
3509 		gid[0] = get32bit(&data);
3510 	}
3511 	anleng = get8bit(&data);
3512 	if (length<23U+anleng) {
3513 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SETXATTR - wrong size (%"PRIu32":anleng=%"PRIu8")",length,anleng);
3514 		eptr->mode = KILL;
3515 		return;
3516 	}
3517 	attrname = data;
3518 	data += anleng;
3519 	avleng = get32bit(&data);
3520 	if (length<23U+anleng+avleng) {
3521 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SETXATTR - wrong size (%"PRIu32":anleng=%"PRIu8":avleng=%"PRIu32")",length,anleng,avleng);
3522 		eptr->mode = KILL;
3523 		return;
3524 	}
3525 	attrvalue = data;
3526 	data += avleng;
3527 	mode = get8bit(&data);
3528 	if (eptr->version>=VERSION2INT(2,0,0)) {
3529 		opened = get8bit(&data);
3530 		uid = get32bit(&data);
3531 		if (length==23U+anleng+avleng) {
3532 			gids = 1;
3533 			gid = matoclserv_gid_storage(gids);
3534 			gid[0] = get32bit(&data);
3535 		} else {
3536 			gids = get32bit(&data);
3537 			if (length!=23U+anleng+avleng+4*gids) {
3538 				syslog(LOG_NOTICE,"CLTOMA_FUSE_SETXATTR - wrong size (%"PRIu32":anleng=%"PRIu8":avleng=%"PRIu32":gids=%"PRIu32")",length,anleng,avleng,gids);
3539 				eptr->mode = KILL;
3540 				return;
3541 			}
3542 			gid = matoclserv_gid_storage(gids);
3543 			for (i=0 ; i<gids ; i++) {
3544 				gid[i] = get32bit(&data);
3545 			}
3546 		}
3547 	}
3548 	sessions_ugid_remap(eptr->sesdata,&uid,gid);
3549 	status = fs_setxattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,opened,uid,gids,gid,anleng,attrname,avleng,attrvalue,mode);
3550 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETXATTR,5);
3551 	put32bit(&ptr,msgid);
3552 	put8bit(&ptr,status);
3553 }
3554 
matoclserv_fuse_getacl(matoclserventry * eptr,const uint8_t * data,uint32_t length)3555 void matoclserv_fuse_getacl(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3556 	uint32_t inode,uid,gids;
3557 	uint32_t *gid;
3558 	uint32_t i;
3559 	uint8_t opened;
3560 	uint32_t msgid;
3561 	uint8_t acltype;
3562 	uint8_t *ptr;
3563 	uint8_t status;
3564 	void *c;
3565 	uint16_t userperm;
3566 	uint16_t groupperm;
3567 	uint16_t otherperm;
3568 	uint16_t mask;
3569 	uint16_t namedusers;
3570 	uint16_t namedgroups;
3571 	uint32_t aclleng;
3572 	if (length<18) {
3573 		syslog(LOG_NOTICE,"CLTOMA_FUSE_GETACL - wrong size (%"PRIu32")",length);
3574 		eptr->mode = KILL;
3575 		return;
3576 	}
3577 	msgid = get32bit(&data);
3578 	inode = get32bit(&data);
3579 	acltype = get8bit(&data);
3580 	opened = get8bit(&data);
3581 	uid = get32bit(&data);
3582 	if (length==18) {
3583 		gids = 1;
3584 		gid = matoclserv_gid_storage(gids);
3585 		gid[0] = get32bit(&data);
3586 	} else {
3587 		gids = get32bit(&data);
3588 		if (length!=18+4*gids) {
3589 			syslog(LOG_NOTICE,"CLTOMA_FUSE_GETACL - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
3590 			eptr->mode = KILL;
3591 			return;
3592 		}
3593 		gid = matoclserv_gid_storage(gids);
3594 		for (i=0 ; i<gids ; i++) {
3595 			gid[i] = get32bit(&data);
3596 		}
3597 	}
3598 	sessions_ugid_remap(eptr->sesdata,&uid,gid);
3599 	status = fs_getacl_size(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,opened,uid,gids,gid,acltype,&c,&aclleng);
3600 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETACL,(status!=STATUS_OK)?5:16+aclleng);
3601 	if (status!=STATUS_OK) {
3602 		put32bit(&ptr,msgid);
3603 		put8bit(&ptr,status);
3604 	} else {
3605 		fs_getacl_data(c,&userperm,&groupperm,&otherperm,&mask,&namedusers,&namedgroups,ptr+16);
3606 		put32bit(&ptr,msgid);
3607 		put16bit(&ptr,userperm);
3608 		put16bit(&ptr,groupperm);
3609 		put16bit(&ptr,otherperm);
3610 		put16bit(&ptr,mask);
3611 		put16bit(&ptr,namedusers);
3612 		put16bit(&ptr,namedgroups);
3613 	}
3614 }
3615 
matoclserv_fuse_setacl(matoclserventry * eptr,const uint8_t * data,uint32_t length)3616 void matoclserv_fuse_setacl(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3617 	uint32_t inode;
3618 	uint32_t uid;
3619 	uint32_t msgid;
3620 	uint8_t acltype;
3621 	uint16_t userperm;
3622 	uint16_t groupperm;
3623 	uint16_t otherperm;
3624 	uint16_t mask;
3625 	uint16_t namedusers;
3626 	uint16_t namedgroups;
3627 	uint8_t *ptr;
3628 	uint8_t status;
3629 	if (length<25) {
3630 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SETACL - wrong size (%"PRIu32")",length);
3631 		eptr->mode = KILL;
3632 		return;
3633 	}
3634 	msgid = get32bit(&data);
3635 	inode = get32bit(&data);
3636 	uid = get32bit(&data);
3637 	acltype = get8bit(&data);
3638 	userperm = get16bit(&data);
3639 	groupperm = get16bit(&data);
3640 	otherperm = get16bit(&data);
3641 	mask = get16bit(&data);
3642 	namedusers = get16bit(&data);
3643 	namedgroups = get16bit(&data);
3644 	if (length!=(namedusers+namedgroups)*6U+25U) {
3645 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SETACL - wrong size (%"PRIu32":namedusers=%"PRIu16":namedgroups=%"PRIu16")",length,namedusers,namedgroups);
3646 		eptr->mode = KILL;
3647 		return;
3648 	}
3649 //	uid = get32bit(&data);
3650 //	gid = get32bit(&data);
3651 //	sessions_ugid_remap(eptr->sesdata,&uid,&gid);
3652 	status = fs_setacl(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,acltype,userperm,groupperm,otherperm,mask,namedusers,namedgroups,data);
3653 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETACL,5);
3654 	put32bit(&ptr,msgid);
3655 	put8bit(&ptr,status);
3656 }
3657 
3658 /*
3659 void matoclserv_fuse_setfilechunks(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3660 	uint32_t inode,uid,gid,indx;
3661 	uint32_t msgid;
3662 	uint64_t leng;
3663 	uint8_t *ptr;
3664 	uint8_t status;
3665 	if (length<28U || ((length-28)%8)!=0) {
3666 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SETFILECHUNKS - wrong size (%"PRIu32"/28+N*8)",length);
3667 		eptr->mode = KILL;
3668 		return;
3669 	}
3670 	msgid = get32bit(&data);
3671 	inode = get32bit(&data);
3672 	uid = get32bit(&data);
3673 	gid = get32bit(&data);
3674 	leng = get64bit(&data);
3675 	indx = get32bit(&data);
3676 	sessions_ugid_remap(eptr->sesdata,&uid,&gid);
3677 	status = fs_setfilechunks(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,gid,leng,indx,(length-28)/8,data);
3678 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETFILECHUNKS,5);
3679 	put32bit(&ptr,msgid);
3680 	put8bit(&ptr,status);
3681 }
3682 */
3683 
matoclserv_fuse_append(matoclserventry * eptr,const uint8_t * data,uint32_t length)3684 void matoclserv_fuse_append(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3685 	uint32_t inode,inode_src,uid,gids;
3686 	uint32_t *gid;
3687 	uint32_t i;
3688 	uint32_t msgid;
3689 	uint8_t *ptr;
3690 	uint8_t status;
3691 	if (length<20) {
3692 		syslog(LOG_NOTICE,"CLTOMA_FUSE_APPEND - wrong size (%"PRIu32"/20)",length);
3693 		eptr->mode = KILL;
3694 		return;
3695 	}
3696 	msgid = get32bit(&data);
3697 	inode = get32bit(&data);
3698 	inode_src = get32bit(&data);
3699 	uid = get32bit(&data);
3700 	if (length==20) {
3701 		gids = 1;
3702 		gid = matoclserv_gid_storage(gids);
3703 		gid[0] = get32bit(&data);
3704 	} else {
3705 		gids = get32bit(&data);
3706 		if (length!=20+4*gids) {
3707 			syslog(LOG_NOTICE,"CLTOMA_FUSE_APPEND - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
3708 			eptr->mode = KILL;
3709 			return;
3710 		}
3711 		gid = matoclserv_gid_storage(gids);
3712 		for (i=0 ; i<gids ; i++) {
3713 			gid[i] = get32bit(&data);
3714 		}
3715 	}
3716 	sessions_ugid_remap(eptr->sesdata,&uid,gid);
3717 	status = fs_append(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,inode_src,uid,gids,gid);
3718 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_APPEND,5);
3719 	put32bit(&ptr,msgid);
3720 	put8bit(&ptr,status);
3721 }
3722 
matoclserv_fuse_snapshot(matoclserventry * eptr,const uint8_t * data,uint32_t length)3723 void matoclserv_fuse_snapshot(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3724 	uint32_t inode,inode_dst;
3725 	uint8_t nleng_dst;
3726 	const uint8_t *name_dst;
3727 	uint32_t uid,gids;
3728 	uint32_t *gid;
3729 	uint32_t i;
3730 	uint8_t smode;
3731 	uint16_t requmask;
3732 	uint32_t msgid;
3733 	uint8_t *ptr;
3734 	uint8_t status;
3735 	if (length<22) {
3736 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SNAPSHOT - wrong size (%"PRIu32")",length);
3737 		eptr->mode = KILL;
3738 		return;
3739 	}
3740 	msgid = get32bit(&data);
3741 	inode = get32bit(&data);
3742 	inode_dst = get32bit(&data);
3743 	nleng_dst = get8bit(&data);
3744 	if (length!=22U+nleng_dst && length<24U+nleng_dst) {
3745 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SNAPSHOT - wrong size (%"PRIu32":nleng_dst=%"PRIu8")",length,nleng_dst);
3746 		eptr->mode = KILL;
3747 		return;
3748 	}
3749 	name_dst = data;
3750 	data += nleng_dst;
3751 	uid = get32bit(&data);
3752 	if (length<=24U+nleng_dst) {
3753 		gids = 1;
3754 		gid = matoclserv_gid_storage(gids);
3755 		gid[0] = get32bit(&data);
3756 	} else {
3757 		gids = get32bit(&data);
3758 		if (length!=24U+nleng_dst+4*gids) {
3759 			syslog(LOG_NOTICE,"CLTOMA_FUSE_SNAPSHOT - wrong size (%"PRIu32":nleng_dst=%"PRIu8":gids=%"PRIu32")",length,nleng_dst,gids);
3760 			eptr->mode = KILL;
3761 			return;
3762 		}
3763 		gid = matoclserv_gid_storage(gids);
3764 		for (i=0 ; i<gids ; i++) {
3765 			gid[i] = get32bit(&data);
3766 		}
3767 	}
3768 	sessions_ugid_remap(eptr->sesdata,&uid,gid);
3769 	smode = get8bit(&data);
3770 	if (length>=24U+nleng_dst) {
3771 		requmask = get16bit(&data);
3772 	} else {
3773 		smode &= ~SNAPSHOT_MODE_CPLIKE_ATTR;
3774 		requmask = 0;
3775 	}
3776 	status = fs_snapshot(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,inode_dst,nleng_dst,name_dst,uid,gids,gid,smode,requmask);
3777 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SNAPSHOT,5);
3778 	put32bit(&ptr,msgid);
3779 	put8bit(&ptr,status);
3780 }
3781 
matoclserv_fuse_quotacontrol(matoclserventry * eptr,const uint8_t * data,uint32_t length)3782 void matoclserv_fuse_quotacontrol(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3783 	uint8_t flags,del;
3784 	uint32_t sinodes,hinodes,curinodes;
3785 	uint64_t slength,ssize,srealsize,hlength,hsize,hrealsize,curlength,cursize,currealsize;
3786 	uint32_t msgid,inode;
3787 	uint8_t *ptr;
3788 	uint8_t status;
3789 	if (length!=65 && length!=9) {
3790 		syslog(LOG_NOTICE,"CLTOMA_FUSE_QUOTACONTROL - wrong size (%"PRIu32")",length);
3791 		eptr->mode = KILL;
3792 		return;
3793 	}
3794 	msgid = get32bit(&data);
3795 	inode = get32bit(&data);
3796 	flags = get8bit(&data);
3797 	if (length==65) {
3798 		sinodes = get32bit(&data);
3799 		slength = get64bit(&data);
3800 		ssize = get64bit(&data);
3801 		srealsize = get64bit(&data);
3802 		hinodes = get32bit(&data);
3803 		hlength = get64bit(&data);
3804 		hsize = get64bit(&data);
3805 		hrealsize = get64bit(&data);
3806 		del=0;
3807 	} else {
3808 		del=1;
3809 	}
3810 	if (flags && sessions_is_root_remapped(eptr->sesdata)) {
3811 		status = ERROR_EACCES;
3812 	} else {
3813 		status = fs_quotacontrol(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,del,&flags,&sinodes,&slength,&ssize,&srealsize,&hinodes,&hlength,&hsize,&hrealsize,&curinodes,&curlength,&cursize,&currealsize);
3814 	}
3815 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_QUOTACONTROL,(status!=STATUS_OK)?5:89);
3816 	put32bit(&ptr,msgid);
3817 	if (status!=STATUS_OK) {
3818 		put8bit(&ptr,status);
3819 	} else {
3820 		put8bit(&ptr,flags);
3821 		put32bit(&ptr,sinodes);
3822 		put64bit(&ptr,slength);
3823 		put64bit(&ptr,ssize);
3824 		put64bit(&ptr,srealsize);
3825 		put32bit(&ptr,hinodes);
3826 		put64bit(&ptr,hlength);
3827 		put64bit(&ptr,hsize);
3828 		put64bit(&ptr,hrealsize);
3829 		put32bit(&ptr,curinodes);
3830 		put64bit(&ptr,curlength);
3831 		put64bit(&ptr,cursize);
3832 		put64bit(&ptr,currealsize);
3833 	}
3834 }
3835 
3836 /*
3837 void matoclserv_fuse_eattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3838 	uint8_t mode,eattr,fneattr;
3839 	uint32_t msgid,inode,uid;
3840 	uint8_t *ptr;
3841 	uint8_t status;
3842 	if (length!=14) {
3843 		syslog(LOG_NOTICE,"CLTOMA_FUSE_EATTR - wrong size (%"PRIu32")",length);
3844 		eptr->mode = KILL;
3845 		return;
3846 	}
3847 	msgid = get32bit(&data);
3848 	inode = get32bit(&data);
3849 	uid = get32bit(&data);
3850 	mode = get8bit(&data);
3851 	eattr = get8bit(&data);
3852 	status = fs_eattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,mode,&eattr,&fneattr);
3853 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_EATTR,(status!=STATUS_OK)?5:6);
3854 	put32bit(&ptr,msgid);
3855 	if (status!=STATUS_OK) {
3856 		put8bit(&ptr,status);
3857 	} else {
3858 		put8bit(&ptr,eattr);
3859 		put8bit(&ptr,fneattr);
3860 	}
3861 }
3862 */
3863 
matoclserv_fuse_getdirstats_old(matoclserventry * eptr,const uint8_t * data,uint32_t length)3864 void matoclserv_fuse_getdirstats_old(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3865 	uint32_t inode,inodes,files,dirs,chunks;
3866 	uint64_t leng,size,rsize;
3867 	uint32_t msgid;
3868 	uint8_t *ptr;
3869 	uint8_t status;
3870 	if (length!=8) {
3871 		syslog(LOG_NOTICE,"CLTOMA_FUSE_GETDIRSTATS - wrong size (%"PRIu32"/8)",length);
3872 		eptr->mode = KILL;
3873 		return;
3874 	}
3875 	msgid = get32bit(&data);
3876 	inode = get32bit(&data);
3877 	status = fs_get_dir_stats(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,&inodes,&dirs,&files,&chunks,&leng,&size,&rsize);
3878 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETDIRSTATS,(status!=STATUS_OK)?5:60);
3879 	put32bit(&ptr,msgid);
3880 	if (status!=STATUS_OK) {
3881 		put8bit(&ptr,status);
3882 	} else {
3883 		put32bit(&ptr,inodes);
3884 		put32bit(&ptr,dirs);
3885 		put32bit(&ptr,files);
3886 		put32bit(&ptr,0);
3887 		put32bit(&ptr,0);
3888 		put32bit(&ptr,chunks);
3889 		put32bit(&ptr,0);
3890 		put32bit(&ptr,0);
3891 		put64bit(&ptr,leng);
3892 		put64bit(&ptr,size);
3893 		put64bit(&ptr,rsize);
3894 	}
3895 }
3896 
matoclserv_fuse_getdirstats(matoclserventry * eptr,const uint8_t * data,uint32_t length)3897 void matoclserv_fuse_getdirstats(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3898 	uint32_t inode,inodes,files,dirs,chunks;
3899 	uint64_t leng,size,rsize;
3900 	uint32_t msgid;
3901 	uint8_t *ptr;
3902 	uint8_t status;
3903 	if (length!=8) {
3904 		syslog(LOG_NOTICE,"CLTOMA_FUSE_GETDIRSTATS - wrong size (%"PRIu32"/8)",length);
3905 		eptr->mode = KILL;
3906 		return;
3907 	}
3908 	msgid = get32bit(&data);
3909 	inode = get32bit(&data);
3910 	status = fs_get_dir_stats(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,&inodes,&dirs,&files,&chunks,&leng,&size,&rsize);
3911 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETDIRSTATS,(status!=STATUS_OK)?5:44);
3912 	put32bit(&ptr,msgid);
3913 	if (status!=STATUS_OK) {
3914 		put8bit(&ptr,status);
3915 	} else {
3916 		put32bit(&ptr,inodes);
3917 		put32bit(&ptr,dirs);
3918 		put32bit(&ptr,files);
3919 		put32bit(&ptr,chunks);
3920 		put64bit(&ptr,leng);
3921 		put64bit(&ptr,size);
3922 		put64bit(&ptr,rsize);
3923 	}
3924 }
3925 
matoclserv_fuse_gettrash(matoclserventry * eptr,const uint8_t * data,uint32_t length)3926 void matoclserv_fuse_gettrash(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3927 	uint32_t msgid;
3928 	uint8_t *ptr;
3929 	uint8_t status;
3930 	uint32_t dleng;
3931 	if (length!=4) {
3932 		syslog(LOG_NOTICE,"CLTOMA_FUSE_GETTRASH - wrong size (%"PRIu32"/4)",length);
3933 		eptr->mode = KILL;
3934 		return;
3935 	}
3936 	msgid = get32bit(&data);
3937 	status = fs_readtrash_size(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),&dleng);
3938 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETTRASH,(status!=STATUS_OK)?5:(4+dleng));
3939 	put32bit(&ptr,msgid);
3940 	if (status!=STATUS_OK) {
3941 		put8bit(&ptr,status);
3942 	} else {
3943 		fs_readtrash_data(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),ptr);
3944 	}
3945 }
3946 
matoclserv_fuse_getdetachedattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)3947 void matoclserv_fuse_getdetachedattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3948 	uint32_t inode;
3949 	uint8_t attr[35];
3950 	uint32_t msgid;
3951 	uint8_t dtype;
3952 	uint8_t *ptr;
3953 	uint8_t status;
3954 	if (length<8 || length>9) {
3955 		syslog(LOG_NOTICE,"CLTOMA_FUSE_GETDETACHEDATTR - wrong size (%"PRIu32"/8,9)",length);
3956 		eptr->mode = KILL;
3957 		return;
3958 	}
3959 	msgid = get32bit(&data);
3960 	inode = get32bit(&data);
3961 	if (length==9) {
3962 		dtype = get8bit(&data);
3963 	} else {
3964 		dtype = DTYPE_UNKNOWN;
3965 	}
3966 	status = fs_getdetachedattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,attr,dtype);
3967 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETDETACHEDATTR,(status!=STATUS_OK)?5:39);
3968 	put32bit(&ptr,msgid);
3969 	if (status!=STATUS_OK) {
3970 		put8bit(&ptr,status);
3971 	} else {
3972 		memcpy(ptr,attr,35);
3973 	}
3974 }
3975 
matoclserv_fuse_gettrashpath(matoclserventry * eptr,const uint8_t * data,uint32_t length)3976 void matoclserv_fuse_gettrashpath(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3977 	uint32_t inode;
3978 	uint32_t pleng;
3979 	const uint8_t *path;
3980 	uint32_t msgid;
3981 	uint8_t *ptr;
3982 	uint8_t status;
3983 	if (length!=8) {
3984 		syslog(LOG_NOTICE,"CLTOMA_FUSE_GETTRASHPATH - wrong size (%"PRIu32"/8)",length);
3985 		eptr->mode = KILL;
3986 		return;
3987 	}
3988 	msgid = get32bit(&data);
3989 	inode = get32bit(&data);
3990 	status = fs_gettrashpath(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,&pleng,&path);
3991 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETTRASHPATH,(status!=STATUS_OK)?5:8+pleng+1);
3992 	put32bit(&ptr,msgid);
3993 	if (status!=STATUS_OK) {
3994 		put8bit(&ptr,status);
3995 	} else {
3996 		put32bit(&ptr,pleng+1);
3997 		if (pleng>0) {
3998 			memcpy(ptr,path,pleng);
3999 		}
4000 		ptr[pleng]=0;
4001 	}
4002 }
4003 
matoclserv_fuse_settrashpath(matoclserventry * eptr,const uint8_t * data,uint32_t length)4004 void matoclserv_fuse_settrashpath(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4005 	uint32_t inode;
4006 	const uint8_t *path;
4007 	uint32_t pleng;
4008 	uint32_t msgid;
4009 	uint8_t status;
4010 	uint8_t *ptr;
4011 	if (length<12) {
4012 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SETTRASHPATH - wrong size (%"PRIu32"/>=12)",length);
4013 		eptr->mode = KILL;
4014 		return;
4015 	}
4016 	msgid = get32bit(&data);
4017 	inode = get32bit(&data);
4018 	pleng = get32bit(&data);
4019 	if (length!=12+pleng) {
4020 		syslog(LOG_NOTICE,"CLTOMA_FUSE_SETTRASHPATH - wrong size (%"PRIu32"/%"PRIu32")",length,12+pleng);
4021 		eptr->mode = KILL;
4022 		return;
4023 	}
4024 	path = data;
4025 	data += pleng;
4026 	while (pleng>0 && path[pleng-1]==0) {
4027 		pleng--;
4028 	}
4029 	status = fs_settrashpath(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,pleng,path);
4030 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETTRASHPATH,5);
4031 	put32bit(&ptr,msgid);
4032 	put8bit(&ptr,status);
4033 }
4034 
matoclserv_fuse_undel(matoclserventry * eptr,const uint8_t * data,uint32_t length)4035 void matoclserv_fuse_undel(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4036 	uint32_t inode;
4037 	uint32_t msgid;
4038 	uint8_t status;
4039 	uint8_t *ptr;
4040 	if (length!=8) {
4041 		syslog(LOG_NOTICE,"CLTOMA_FUSE_UNDEL - wrong size (%"PRIu32"/8)",length);
4042 		eptr->mode = KILL;
4043 		return;
4044 	}
4045 	msgid = get32bit(&data);
4046 	inode = get32bit(&data);
4047 	status = fs_undel(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode);
4048 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_UNDEL,5);
4049 	put32bit(&ptr,msgid);
4050 	put8bit(&ptr,status);
4051 }
4052 
matoclserv_fuse_purge(matoclserventry * eptr,const uint8_t * data,uint32_t length)4053 void matoclserv_fuse_purge(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4054 	uint32_t inode;
4055 	uint32_t msgid;
4056 	uint8_t *ptr;
4057 	uint8_t status;
4058 	if (length!=8) {
4059 		syslog(LOG_NOTICE,"CLTOMA_FUSE_PURGE - wrong size (%"PRIu32"/8)",length);
4060 		eptr->mode = KILL;
4061 		return;
4062 	}
4063 	msgid = get32bit(&data);
4064 	inode = get32bit(&data);
4065 	status = fs_purge(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode);
4066 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_PURGE,5);
4067 	put32bit(&ptr,msgid);
4068 	put8bit(&ptr,status);
4069 }
4070 
4071 
matoclserv_fuse_getsustained(matoclserventry * eptr,const uint8_t * data,uint32_t length)4072 void matoclserv_fuse_getsustained(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4073 	uint32_t msgid;
4074 	uint8_t *ptr;
4075 	uint8_t status;
4076 	uint32_t dleng;
4077 	if (length!=4) {
4078 		syslog(LOG_NOTICE,"CLTOMA_FUSE_GETSUSTAINED - wrong size (%"PRIu32"/4)",length);
4079 		eptr->mode = KILL;
4080 		return;
4081 	}
4082 	msgid = get32bit(&data);
4083 	status = fs_readsustained_size(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),&dleng);
4084 	ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETSUSTAINED,(status!=STATUS_OK)?5:(4+dleng));
4085 	put32bit(&ptr,msgid);
4086 	if (status!=STATUS_OK) {
4087 		put8bit(&ptr,status);
4088 	} else {
4089 		fs_readsustained_data(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),ptr);
4090 	}
4091 }
4092 
4093 
4094 /*
4095 void matocl_session_timedout(session *sesdata) {
4096 	filelist *fl,*afl;
4097 	fl=sesdata->openedfiles;
4098 	while (fl) {
4099 		afl = fl;
4100 		fl=fl->next;
4101 		fs_release(afl->inode,sesdata->sessionid);
4102 		free(afl);
4103 	}
4104 	sesdata->openedfiles=NULL;
4105 	if (sesdata->info) {
4106 		free(sesdata->info);
4107 	}
4108 }
4109 
4110 void matocl_session_check(void) {
4111 	session **sesdata,*asesdata;
4112 	uint32_t now;
4113 
4114 	now = main_time();
4115 	sesdata = &(sessionshead);
4116 	while ((asesdata=*sesdata)) {
4117 		// syslog(LOG_NOTICE,"session: %u ; nsocks: %u ; state: %u ; disconnected: %u",asesdata->sessionid,asesdata->nsocks,asesdata->newsession,asesdata->disconnected);
4118 		if (asesdata->nsocks==0 && ((asesdata->newsession>1 && asesdata->disconnected<now) || (asesdata->newsession==1 && asesdata->disconnected+SessionSustainTime<now) || (asesdata->newsession==0 && asesdata->disconnected+120<now))) {
4119 			syslog(LOG_NOTICE,"remove session: %u",asesdata->sessionid);
4120 			matocl_session_timedout(asesdata);
4121 			*sesdata = asesdata->next;
4122 			free(asesdata);
4123 		} else {
4124 			sesdata = &(asesdata->next);
4125 		}
4126 	}
4127 //	matoclserv_show_notification_dirs();
4128 }
4129 
4130 void matocl_session_statsmove(void) {
4131 	session *sesdata;
4132 	for (sesdata = sessionshead ; sesdata ; sesdata=sesdata->next) {
4133 		memcpy(sesdata->lasthouropstats,sesdata->currentopstats,4*SESSION_STATS);
4134 		memset(sesdata->currentopstats,0,4*SESSION_STATS);
4135 	}
4136 	matoclserv_store_sessions();
4137 }
4138 */
matocl_beforedisconnect(matoclserventry * eptr)4139 void matocl_beforedisconnect(matoclserventry *eptr) {
4140 	chunklist *cl,*acl;
4141 // unlock locked chunks
4142 	cl=eptr->chunkdelayedops;
4143 	while (cl) {
4144 		acl = cl;
4145 		cl=cl->next;
4146 		if (acl->type == FUSE_TRUNCATE) {
4147 			fs_end_setlength(acl->chunkid);
4148 		}
4149 		free(acl);
4150 	}
4151 	eptr->chunkdelayedops=NULL;
4152 	sessions_disconnection(eptr->sesdata);
4153 /*
4154 	if (eptr->sesdata) {
4155 
4156 		if (eptr->sesdata->nsocks>0) {
4157 			eptr->sesdata->nsocks--;
4158 		}
4159 		if (eptr->sesdata->nsocks==0) {
4160 			eptr->sesdata->disconnected = main_time();
4161 		}
4162 	}
4163 */
4164 /* CACHENOTIFY
4165 	matoclserv_notify_disconnected(eptr);
4166 */
4167 }
4168 
matoclserv_gotpacket(matoclserventry * eptr,uint32_t type,const uint8_t * data,uint32_t length)4169 void matoclserv_gotpacket(matoclserventry *eptr,uint32_t type,const uint8_t *data,uint32_t length) {
4170 	if (type==ANTOAN_NOP) {
4171 		return;
4172 	}
4173 	if (type==ANTOAN_UNKNOWN_COMMAND) { // for future use
4174 		return;
4175 	}
4176 	if (type==ANTOAN_BAD_COMMAND_SIZE) { // for future use
4177 		return;
4178 	}
4179 //	printf("AQQ\n");
4180 	if (eptr->registered==0) {	// unregistered clients - beware that in this context sesdata is NULL
4181 		switch (type) {
4182 			case ANTOAN_GET_VERSION:
4183 				matoclserv_get_version(eptr,data,length);
4184 				break;
4185 			case CLTOMA_FUSE_REGISTER:
4186 //				printf("REGISTER\n");
4187 				matoclserv_fuse_register(eptr,data,length);
4188 				break;
4189 			case CLTOMA_CSERV_LIST:
4190 				matoclserv_cserv_list(eptr,data,length);
4191 				break;
4192 			case CLTOMA_SESSION_LIST:
4193 				matoclserv_session_list(eptr,data,length);
4194 				break;
4195 			case CLTOAN_CHART:
4196 				matoclserv_chart(eptr,data,length);
4197 				break;
4198 			case CLTOAN_CHART_DATA:
4199 				matoclserv_chart_data(eptr,data,length);
4200 				break;
4201 			case CLTOMA_INFO:
4202 				matoclserv_info(eptr,data,length);
4203 				break;
4204 			case CLTOMA_FSTEST_INFO:
4205 				matoclserv_fstest_info(eptr,data,length);
4206 				break;
4207 			case CLTOMA_CHUNKSTEST_INFO:
4208 				matoclserv_chunkstest_info(eptr,data,length);
4209 				break;
4210 			case CLTOMA_CHUNKS_MATRIX:
4211 				matoclserv_chunks_matrix(eptr,data,length);
4212 				break;
4213 			case CLTOMA_QUOTA_INFO:
4214 				matoclserv_quota_info(eptr,data,length);
4215 				break;
4216 			case CLTOMA_EXPORTS_INFO:
4217 				matoclserv_exports_info(eptr,data,length);
4218 				break;
4219 			case CLTOMA_MLOG_LIST:
4220 				matoclserv_mlog_list(eptr,data,length);
4221 				break;
4222 			case CLTOMA_CSSERV_COMMAND:
4223 				matoclserv_cserv_command(eptr,data,length);
4224 				break;
4225 			case CLTOMA_SESSION_COMMAND:
4226 				matoclserv_session_command(eptr,data,length);
4227 				break;
4228 			case CLTOMA_MEMORY_INFO:
4229 				matoclserv_memory_info(eptr,data,length);
4230 				break;
4231 			case CLTOAN_MODULE_INFO:
4232 				matoclserv_module_info(eptr,data,length);
4233 				break;
4234 			case CLTOMA_MASS_RESOLVE_PATHS:
4235 				matoclserv_mass_resolve_paths(eptr,data,length);
4236 				break;
4237 			case CLTOMA_MISSING_CHUNKS:
4238 				matoclserv_missing_chunks(eptr,data,length);
4239 				break;
4240 			default:
4241 				syslog(LOG_NOTICE,"main master server module: got unknown message from unregistered (type:%"PRIu32")",type);
4242 				eptr->mode=KILL;
4243 		}
4244 	} else if (eptr->registered<100) {	// mounts and new tools
4245 		if (eptr->sesdata==NULL) {
4246 			syslog(LOG_ERR,"registered connection without sesdata !!!");
4247 			eptr->mode=KILL;
4248 			return;
4249 		}
4250 		switch (type) {
4251 			case ANTOAN_GET_VERSION:
4252 				matoclserv_get_version(eptr,data,length);
4253 				break;
4254 			case CLTOMA_FUSE_REGISTER:
4255 				matoclserv_fuse_register(eptr,data,length);
4256 				break;
4257 			case CLTOMA_FUSE_SUSTAINED_INODES:
4258 				matoclserv_fuse_sustained_inodes(eptr,data,length);
4259 				break;
4260 			case CLTOMA_FUSE_STATFS:
4261 				matoclserv_fuse_statfs(eptr,data,length);
4262 				break;
4263 			case CLTOMA_FUSE_ACCESS:
4264 				matoclserv_fuse_access(eptr,data,length);
4265 				break;
4266 			case CLTOMA_FUSE_LOOKUP:
4267 				matoclserv_fuse_lookup(eptr,data,length);
4268 				break;
4269 			case CLTOMA_FUSE_GETATTR:
4270 				matoclserv_fuse_getattr(eptr,data,length);
4271 				break;
4272 			case CLTOMA_FUSE_SETATTR:
4273 				matoclserv_fuse_setattr(eptr,data,length);
4274 				break;
4275 			case CLTOMA_FUSE_READLINK:
4276 				matoclserv_fuse_readlink(eptr,data,length);
4277 				break;
4278 			case CLTOMA_FUSE_SYMLINK:
4279 				matoclserv_fuse_symlink(eptr,data,length);
4280 				break;
4281 			case CLTOMA_FUSE_MKNOD:
4282 				matoclserv_fuse_mknod(eptr,data,length);
4283 				break;
4284 			case CLTOMA_FUSE_MKDIR:
4285 				matoclserv_fuse_mkdir(eptr,data,length);
4286 				break;
4287 			case CLTOMA_FUSE_UNLINK:
4288 				matoclserv_fuse_unlink(eptr,data,length);
4289 				break;
4290 			case CLTOMA_FUSE_RMDIR:
4291 				matoclserv_fuse_rmdir(eptr,data,length);
4292 				break;
4293 			case CLTOMA_FUSE_RENAME:
4294 				matoclserv_fuse_rename(eptr,data,length);
4295 				break;
4296 			case CLTOMA_FUSE_LINK:
4297 				matoclserv_fuse_link(eptr,data,length);
4298 				break;
4299 			case CLTOMA_FUSE_READDIR:
4300 				matoclserv_fuse_readdir(eptr,data,length);
4301 				break;
4302 /* CACHENOTIFY
4303 			case CLTOMA_FUSE_DIR_REMOVED:
4304 				matoclserv_fuse_dir_removed(eptr,data,length);
4305 				break;
4306 */
4307 			case CLTOMA_FUSE_OPEN:
4308 				matoclserv_fuse_open(eptr,data,length);
4309 				break;
4310 			case CLTOMA_FUSE_CREATE:
4311 				matoclserv_fuse_create(eptr,data,length);
4312 				break;
4313 			case CLTOMA_FUSE_READ_CHUNK:
4314 				matoclserv_fuse_read_chunk(eptr,data,length);
4315 				break;
4316 			case CLTOMA_FUSE_WRITE_CHUNK:
4317 				matoclserv_fuse_write_chunk(eptr,data,length);
4318 				break;
4319 			case CLTOMA_FUSE_WRITE_CHUNK_END:
4320 				matoclserv_fuse_write_chunk_end(eptr,data,length);
4321 				break;
4322 // fuse - meta
4323 			case CLTOMA_FUSE_GETTRASH:
4324 				matoclserv_fuse_gettrash(eptr,data,length);
4325 				break;
4326 			case CLTOMA_FUSE_GETDETACHEDATTR:
4327 				matoclserv_fuse_getdetachedattr(eptr,data,length);
4328 				break;
4329 			case CLTOMA_FUSE_GETTRASHPATH:
4330 				matoclserv_fuse_gettrashpath(eptr,data,length);
4331 				break;
4332 			case CLTOMA_FUSE_SETTRASHPATH:
4333 				matoclserv_fuse_settrashpath(eptr,data,length);
4334 				break;
4335 			case CLTOMA_FUSE_UNDEL:
4336 				matoclserv_fuse_undel(eptr,data,length);
4337 				break;
4338 			case CLTOMA_FUSE_PURGE:
4339 				matoclserv_fuse_purge(eptr,data,length);
4340 				break;
4341 			case CLTOMA_FUSE_GETSUSTAINED:
4342 				matoclserv_fuse_getsustained(eptr,data,length);
4343 				break;
4344 			case CLTOMA_FUSE_CHECK:
4345 				matoclserv_fuse_check(eptr,data,length);
4346 				break;
4347 			case CLTOMA_FUSE_GETTRASHTIME:
4348 				matoclserv_fuse_gettrashtime(eptr,data,length);
4349 				break;
4350 			case CLTOMA_FUSE_SETTRASHTIME:
4351 				matoclserv_fuse_settrashtime(eptr,data,length);
4352 				break;
4353 			case CLTOMA_FUSE_GETGOAL:
4354 				matoclserv_fuse_getgoal(eptr,data,length);
4355 				break;
4356 			case CLTOMA_FUSE_SETGOAL:
4357 				matoclserv_fuse_setgoal(eptr,data,length);
4358 				break;
4359 			case CLTOMA_FUSE_APPEND:
4360 				matoclserv_fuse_append(eptr,data,length);
4361 				break;
4362 //			case CLTOMA_FUSE_SETFILECHUNKS:
4363 //				matoclserv_fuse_setfilechunks(eptr,data,length);
4364 //				break;
4365 			case CLTOMA_FUSE_GETDIRSTATS:
4366 				matoclserv_fuse_getdirstats_old(eptr,data,length);
4367 				break;
4368 			case CLTOMA_FUSE_TRUNCATE:
4369 				matoclserv_fuse_truncate(eptr,data,length);
4370 				break;
4371 			case CLTOMA_FUSE_REPAIR:
4372 				matoclserv_fuse_repair(eptr,data,length);
4373 				break;
4374 			case CLTOMA_FUSE_SNAPSHOT:
4375 				matoclserv_fuse_snapshot(eptr,data,length);
4376 				break;
4377 			case CLTOMA_FUSE_GETEATTR:
4378 				matoclserv_fuse_geteattr(eptr,data,length);
4379 				break;
4380 			case CLTOMA_FUSE_SETEATTR:
4381 				matoclserv_fuse_seteattr(eptr,data,length);
4382 				break;
4383 			case CLTOMA_FUSE_PARENTS:
4384 				matoclserv_fuse_parents(eptr,data,length);
4385 				break;
4386 			case CLTOMA_FUSE_PATHS:
4387 				matoclserv_fuse_paths(eptr,data,length);
4388 				break;
4389 			case CLTOMA_FUSE_GETXATTR:
4390 				matoclserv_fuse_getxattr(eptr,data,length);
4391 				break;
4392 			case CLTOMA_FUSE_SETXATTR:
4393 				matoclserv_fuse_setxattr(eptr,data,length);
4394 				break;
4395 			case CLTOMA_FUSE_GETACL:
4396 				matoclserv_fuse_getacl(eptr,data,length);
4397 				break;
4398 			case CLTOMA_FUSE_SETACL:
4399 				matoclserv_fuse_setacl(eptr,data,length);
4400 				break;
4401 			case CLTOMA_FUSE_QUOTACONTROL:
4402 				matoclserv_fuse_quotacontrol(eptr,data,length);
4403 				break;
4404 
4405 /* for tools - also should be available for registered clients */
4406 			case CLTOMA_CSERV_LIST:
4407 				matoclserv_cserv_list(eptr,data,length);
4408 				break;
4409 			case CLTOMA_SESSION_LIST:
4410 				matoclserv_session_list(eptr,data,length);
4411 				break;
4412 			case CLTOAN_CHART:
4413 				matoclserv_chart(eptr,data,length);
4414 				break;
4415 			case CLTOAN_CHART_DATA:
4416 				matoclserv_chart_data(eptr,data,length);
4417 				break;
4418 			case CLTOMA_INFO:
4419 				matoclserv_info(eptr,data,length);
4420 				break;
4421 			case CLTOMA_FSTEST_INFO:
4422 				matoclserv_fstest_info(eptr,data,length);
4423 				break;
4424 			case CLTOMA_CHUNKSTEST_INFO:
4425 				matoclserv_chunkstest_info(eptr,data,length);
4426 				break;
4427 			case CLTOMA_CHUNKS_MATRIX:
4428 				matoclserv_chunks_matrix(eptr,data,length);
4429 				break;
4430 			case CLTOMA_QUOTA_INFO:
4431 				matoclserv_quota_info(eptr,data,length);
4432 				break;
4433 			case CLTOMA_EXPORTS_INFO:
4434 				matoclserv_exports_info(eptr,data,length);
4435 				break;
4436 			case CLTOMA_MLOG_LIST:
4437 				matoclserv_mlog_list(eptr,data,length);
4438 				break;
4439 			case CLTOMA_CSSERV_COMMAND:
4440 				matoclserv_cserv_command(eptr,data,length);
4441 				break;
4442 			case CLTOMA_SESSION_COMMAND:
4443 				matoclserv_session_command(eptr,data,length);
4444 				break;
4445 			case CLTOMA_MEMORY_INFO:
4446 				matoclserv_memory_info(eptr,data,length);
4447 				break;
4448 			case CLTOAN_MODULE_INFO:
4449 				matoclserv_module_info(eptr,data,length);
4450 				break;
4451 			case CLTOMA_MASS_RESOLVE_PATHS:
4452 				matoclserv_mass_resolve_paths(eptr,data,length);
4453 				break;
4454 			case CLTOMA_MISSING_CHUNKS:
4455 				matoclserv_missing_chunks(eptr,data,length);
4456 				break;
4457 			default:
4458 				syslog(LOG_NOTICE,"main master server module: got unknown message from mfsmount (type:%"PRIu32")",type);
4459 				eptr->mode=KILL;
4460 		}
4461 	} else {	// old mfstools
4462 		if (eptr->sesdata==NULL) {
4463 			syslog(LOG_ERR,"registered connection (tools) without sesdata !!!");
4464 			eptr->mode=KILL;
4465 			return;
4466 		}
4467 		switch (type) {
4468 // extra (external tools)
4469 			case ANTOAN_GET_VERSION:
4470 				matoclserv_get_version(eptr,data,length);
4471 				break;
4472 			case CLTOMA_FUSE_REGISTER:
4473 				matoclserv_fuse_register(eptr,data,length);
4474 				break;
4475 			case CLTOMA_FUSE_READ_CHUNK:	// used in mfsfileinfo
4476 				matoclserv_fuse_read_chunk(eptr,data,length);
4477 				break;
4478 			case CLTOMA_FUSE_CHECK:
4479 				matoclserv_fuse_check(eptr,data,length);
4480 				break;
4481 			case CLTOMA_FUSE_GETTRASHTIME:
4482 				matoclserv_fuse_gettrashtime(eptr,data,length);
4483 				break;
4484 			case CLTOMA_FUSE_SETTRASHTIME:
4485 				matoclserv_fuse_settrashtime(eptr,data,length);
4486 				break;
4487 			case CLTOMA_FUSE_GETGOAL:
4488 				matoclserv_fuse_getgoal(eptr,data,length);
4489 				break;
4490 			case CLTOMA_FUSE_SETGOAL:
4491 				matoclserv_fuse_setgoal(eptr,data,length);
4492 				break;
4493 			case CLTOMA_FUSE_APPEND:
4494 				matoclserv_fuse_append(eptr,data,length);
4495 				break;
4496 //			case CLTOMA_FUSE_SETFILECHUNKS:
4497 //				matoclserv_fuse_setfilechunks(eptr,data,length);
4498 //				break;
4499 			case CLTOMA_FUSE_GETDIRSTATS:
4500 				matoclserv_fuse_getdirstats(eptr,data,length);
4501 				break;
4502 			case CLTOMA_FUSE_TRUNCATE:
4503 				matoclserv_fuse_truncate(eptr,data,length);
4504 				break;
4505 			case CLTOMA_FUSE_REPAIR:
4506 				matoclserv_fuse_repair(eptr,data,length);
4507 				break;
4508 			case CLTOMA_FUSE_SNAPSHOT:
4509 				matoclserv_fuse_snapshot(eptr,data,length);
4510 				break;
4511 			case CLTOMA_FUSE_GETEATTR:
4512 				matoclserv_fuse_geteattr(eptr,data,length);
4513 				break;
4514 			case CLTOMA_FUSE_SETEATTR:
4515 				matoclserv_fuse_seteattr(eptr,data,length);
4516 				break;
4517 /* do not use in version before 1.7.x */
4518 			case CLTOMA_FUSE_QUOTACONTROL:
4519 				matoclserv_fuse_quotacontrol(eptr,data,length);
4520 				break;
4521 /* ------ */
4522 			default:
4523 				syslog(LOG_NOTICE,"main master server module: got unknown message from mfstools (type:%"PRIu32")",type);
4524 				eptr->mode=KILL;
4525 		}
4526 	}
4527 }
4528 
matoclserv_read(matoclserventry * eptr,double now)4529 void matoclserv_read(matoclserventry *eptr,double now) {
4530 	int32_t i;
4531 	uint32_t type,leng;
4532 	const uint8_t *ptr;
4533 	uint32_t rbleng,rbpos;
4534 	uint8_t err,hup,errmsg;
4535 	static uint8_t *readbuff = NULL;
4536 	static uint32_t readbuffsize = 0;
4537 
4538 	if (eptr == NULL) {
4539 		if (readbuff != NULL) {
4540 			free(readbuff);
4541 		}
4542 		readbuff = NULL;
4543 		readbuffsize = 0;
4544 		return;
4545 	}
4546 
4547 	if (readbuffsize==0) {
4548 		readbuffsize = 65536;
4549 		readbuff = malloc(readbuffsize);
4550 		passert(readbuff);
4551 	}
4552 
4553 	rbleng = 0;
4554 	err = 0;
4555 	hup = 0;
4556 	errmsg = 0;
4557 	for (;;) {
4558 		i = read(eptr->sock,readbuff+rbleng,readbuffsize-rbleng);
4559 		if (i==0) {
4560 			hup = 1;
4561 			break;
4562 		} else if (i<0) {
4563 			if (ERRNO_ERROR) {
4564 				err = 1;
4565 #ifdef ECONNRESET
4566 				if (errno!=ECONNRESET || eptr->registered<100) {
4567 #endif
4568 					errmsg = 1;
4569 #ifdef ECONNRESET
4570 				}
4571 #endif
4572 			}
4573 			break;
4574 		} else {
4575 			stats_brcvd += i;
4576 			rbleng += i;
4577 			if (rbleng==readbuffsize) {
4578 				readbuffsize*=2;
4579 				readbuff = realloc(readbuff,readbuffsize);
4580 				passert(readbuff);
4581 			} else {
4582 				break;
4583 			}
4584 		}
4585 	}
4586 
4587 	if (rbleng>0) {
4588 		eptr->lastread = now;
4589 	}
4590 
4591 	rbpos = 0;
4592 	while (rbpos<rbleng) {
4593 		if ((rbleng-rbpos)>=eptr->input_bytesleft) {
4594 			memcpy(eptr->input_startptr,readbuff+rbpos,eptr->input_bytesleft);
4595 			i = eptr->input_bytesleft;
4596 		} else {
4597 			memcpy(eptr->input_startptr,readbuff+rbpos,rbleng-rbpos);
4598 			i = rbleng-rbpos;
4599 		}
4600 		rbpos += i;
4601 		eptr->input_startptr+=i;
4602 		eptr->input_bytesleft-=i;
4603 
4604 		if (eptr->input_bytesleft>0) {
4605 			break;
4606 		}
4607 
4608 		if (eptr->input_packet == NULL) {
4609 			ptr = eptr->input_hdr;
4610 			type = get32bit(&ptr);
4611 			leng = get32bit(&ptr);
4612 
4613 			if (leng>MaxPacketSize) {
4614 				syslog(LOG_WARNING,"main master server module: packet too long (%"PRIu32"/%u)",leng,MaxPacketSize);
4615 				eptr->input_end = 1;
4616 				return;
4617 			}
4618 
4619 			stats_prcvd++;
4620 			eptr->input_packet = malloc(offsetof(in_packetstruct,data)+leng);
4621 			passert(eptr->input_packet);
4622 			eptr->input_packet->next = NULL;
4623 			eptr->input_packet->type = type;
4624 			eptr->input_packet->leng = leng;
4625 
4626 			eptr->input_startptr = eptr->input_packet->data;
4627 			eptr->input_bytesleft = leng;
4628 		}
4629 
4630 		if (eptr->input_bytesleft>0) {
4631 			continue;
4632 		}
4633 
4634 		if (eptr->input_packet != NULL) {
4635 			*(eptr->inputtail) = eptr->input_packet;
4636 			eptr->inputtail = &(eptr->input_packet->next);
4637 			eptr->input_packet = NULL;
4638 			eptr->input_bytesleft = 8;
4639 			eptr->input_startptr = eptr->input_hdr;
4640 		}
4641 	}
4642 
4643 	if (hup) {
4644 		if (eptr->registered>0 && eptr->registered<100) {	// show this message only for standard, registered clients
4645 			syslog(LOG_NOTICE,"connection with client(ip:%u.%u.%u.%u) has been closed by peer",(eptr->peerip>>24)&0xFF,(eptr->peerip>>16)&0xFF,(eptr->peerip>>8)&0xFF,eptr->peerip&0xFF);
4646 		}
4647 		eptr->input_end = 1;
4648 	} else if (err) {
4649 		if (errmsg) {
4650 			mfs_arg_errlog_silent(LOG_NOTICE,"main master server module: (ip:%u.%u.%u.%u) read error",(eptr->peerip>>24)&0xFF,(eptr->peerip>>16)&0xFF,(eptr->peerip>>8)&0xFF,eptr->peerip&0xFF);
4651 		}
4652 		eptr->input_end = 1;
4653 	}
4654 }
4655 
matoclserv_parse(matoclserventry * eptr)4656 void matoclserv_parse(matoclserventry *eptr) {
4657 	in_packetstruct *ipack;
4658 	uint64_t starttime;
4659 	uint64_t currtime;
4660 
4661 	starttime = monotonic_useconds();
4662 	currtime = starttime;
4663 	while (eptr->mode==DATA && (ipack = eptr->inputhead)!=NULL && starttime+10000>currtime) {
4664 		matoclserv_gotpacket(eptr,ipack->type,ipack->data,ipack->leng);
4665 		eptr->inputhead = ipack->next;
4666 		free(ipack);
4667 		if (eptr->inputhead==NULL) {
4668 			eptr->inputtail = &(eptr->inputhead);
4669 		} else {
4670 			currtime = monotonic_useconds();
4671 		}
4672 	}
4673 	if (eptr->mode==DATA && eptr->inputhead==NULL && eptr->input_end) {
4674 		eptr->mode = KILL;
4675 	}
4676 }
4677 
matoclserv_write(matoclserventry * eptr,double now)4678 void matoclserv_write(matoclserventry *eptr,double now) {
4679 	out_packetstruct *opack;
4680 	int32_t i;
4681 #ifdef HAVE_WRITEV
4682 	struct iovec iovtab[100];
4683 	uint32_t iovdata;
4684 	uint32_t leng;
4685 	uint32_t left;
4686 
4687 	for (;;) {
4688 		leng = 0;
4689 		for (iovdata=0,opack=eptr->outputhead ; iovdata<100 && opack!=NULL ; iovdata++,opack=opack->next) {
4690 			iovtab[iovdata].iov_base = opack->startptr;
4691 			iovtab[iovdata].iov_len = opack->bytesleft;
4692 			leng += opack->bytesleft;
4693 		}
4694 		if (iovdata==0) {
4695 			return;
4696 		}
4697 		i = writev(eptr->sock,iovtab,iovdata);
4698 		if (i<0) {
4699 			if (ERRNO_ERROR) {
4700 				mfs_arg_errlog_silent(LOG_NOTICE,"main master server module: (ip:%u.%u.%u.%u) write error",(eptr->peerip>>24)&0xFF,(eptr->peerip>>16)&0xFF,(eptr->peerip>>8)&0xFF,eptr->peerip&0xFF);
4701 				eptr->mode = KILL;
4702 			}
4703 			return;
4704 		}
4705 		if (i>0) {
4706 			eptr->lastwrite = now;
4707 		}
4708 		stats_bsent+=i;
4709 		left = i;
4710 		while (left>0 && eptr->outputhead!=NULL) {
4711 			opack = eptr->outputhead;
4712 			if (opack->bytesleft>left) {
4713 				opack->startptr+=left;
4714 				opack->bytesleft-=left;
4715 				left = 0;
4716 			} else {
4717 				left -= opack->bytesleft;
4718 				eptr->outputhead = opack->next;
4719 				if (eptr->outputhead==NULL) {
4720 					eptr->outputtail = &(eptr->outputhead);
4721 				}
4722 				free(opack);
4723 				stats_psent++;
4724 			}
4725 		}
4726 		if ((uint32_t)i < leng) {
4727 			return;
4728 		}
4729 	}
4730 #else
4731 	for (;;) {
4732 		opack = eptr->outputhead;
4733 		if (opack==NULL) {
4734 			return;
4735 		}
4736 		i=write(eptr->sock,opack->startptr,opack->bytesleft);
4737 		if (i<0) {
4738 			if (ERRNO_ERROR) {
4739 				mfs_arg_errlog_silent(LOG_NOTICE,"main master server module: (ip:%u.%u.%u.%u) write error",(eptr->peerip>>24)&0xFF,(eptr->peerip>>16)&0xFF,(eptr->peerip>>8)&0xFF,eptr->peerip&0xFF);
4740 				eptr->mode = KILL;
4741 			}
4742 			return;
4743 		}
4744 		if (i>0) {
4745 			eptr->lastwrite = now;
4746 		}
4747 		opack->startptr+=i;
4748 		opack->bytesleft-=i;
4749 		stats_bsent+=i;
4750 		if (opack->bytesleft>0) {
4751 			return;
4752 		}
4753 		stats_psent++;
4754 		eptr->outputhead = opack->next;
4755 		if (eptr->outputhead==NULL) {
4756 			eptr->outputtail = &(eptr->outputhead);
4757 		}
4758 		free(opack);
4759 	}
4760 #endif
4761 }
4762 
matoclserv_desc(struct pollfd * pdesc,uint32_t * ndesc)4763 void matoclserv_desc(struct pollfd *pdesc,uint32_t *ndesc) {
4764 	uint32_t pos = *ndesc;
4765 	matoclserventry *eptr;
4766 
4767 	pdesc[pos].fd = lsock;
4768 		pdesc[pos].events = POLLIN;
4769 		lsockpdescpos = pos;
4770 		pos++;
4771 //		FD_SET(lsock,rset);
4772 //		max = lsock;
4773 	for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
4774 		pdesc[pos].fd = eptr->sock;
4775 		pdesc[pos].events = 0;
4776 		eptr->pdescpos = pos;
4777 //		i=eptr->sock;
4778 		pdesc[pos].events |= POLLIN;
4779 //			FD_SET(i,rset);
4780 //			if (i>max) {
4781 //				max=i;
4782 //			}
4783 		if (eptr->outputhead!=NULL) {
4784 			pdesc[pos].events |= POLLOUT;
4785 //			FD_SET(i,wset);
4786 //			if (i>max) {
4787 //				max=i;
4788 //			}
4789 		}
4790 		pos++;
4791 	}
4792 	*ndesc = pos;
4793 //	return max;
4794 }
4795 
matoclserv_disconnection_loop(void)4796 void matoclserv_disconnection_loop(void) {
4797 	matoclserventry *eptr,**kptr;
4798 	in_packetstruct *ipptr,*ipaptr;
4799 	out_packetstruct *opptr,*opaptr;
4800 
4801 	kptr = &matoclservhead;
4802 	while ((eptr=*kptr)) {
4803 		if (eptr->mode == KILL) {
4804 			matocl_beforedisconnect(eptr);
4805 			tcpclose(eptr->sock);
4806 			if (eptr->input_packet) {
4807 				free(eptr->input_packet);
4808 			}
4809 			ipptr = eptr->inputhead;
4810 			while (ipptr) {
4811 				ipaptr = ipptr;
4812 				ipptr = ipptr->next;
4813 				free(ipaptr);
4814 			}
4815 			opptr = eptr->outputhead;
4816 			while (opptr) {
4817 				opaptr = opptr;
4818 				opptr = opptr->next;
4819 				free(opaptr);
4820 			}
4821 			*kptr = eptr->next;
4822 			free(eptr);
4823 		} else {
4824 			kptr = &(eptr->next);
4825 		}
4826 	}
4827 }
4828 
matoclserv_serve(struct pollfd * pdesc)4829 void matoclserv_serve(struct pollfd *pdesc) {
4830 	double now;
4831 	matoclserventry *eptr;
4832 	int ns;
4833 	static double lastaction = 0.0;
4834 	double timeoutadd;
4835 
4836 	now = monotonic_seconds();
4837 // timeout fix
4838 	if (lastaction>0.0) {
4839 		timeoutadd = now-lastaction;
4840 		if (timeoutadd>1.0) {
4841 			for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
4842 				eptr->lastread += timeoutadd;
4843 			}
4844 		}
4845 	}
4846 	lastaction = now;
4847 
4848 	if (lsockpdescpos>=0 && (pdesc[lsockpdescpos].revents & POLLIN)) {
4849 //	if (FD_ISSET(lsock,rset)) {
4850 		ns=tcpaccept(lsock);
4851 		if (ns<0) {
4852 			mfs_errlog_silent(LOG_NOTICE,"main master server module: accept error");
4853 		} else {
4854 			tcpnonblock(ns);
4855 			tcpnodelay(ns);
4856 			eptr = malloc(sizeof(matoclserventry));
4857 			passert(eptr);
4858 			eptr->next = matoclservhead;
4859 			matoclservhead = eptr;
4860 			eptr->sock = ns;
4861 			eptr->pdescpos = -1;
4862 			tcpgetpeer(ns,&(eptr->peerip),NULL);
4863 			eptr->registered = 0;
4864 /* CACHENOTIFY
4865 			eptr->notifications = 0;
4866 */
4867 			eptr->version = 0;
4868 			eptr->mode = DATA;
4869 			eptr->lastread = now;
4870 			eptr->lastwrite = now;
4871 			eptr->input_bytesleft = 8;
4872 			eptr->input_startptr = eptr->input_hdr;
4873 			eptr->input_end = 0;
4874 			eptr->input_packet = NULL;
4875 			eptr->inputhead = NULL;
4876 			eptr->inputtail = &(eptr->inputhead);
4877 			eptr->outputhead = NULL;
4878 			eptr->outputtail = &(eptr->outputhead);
4879 
4880 			eptr->chunkdelayedops = NULL;
4881 			eptr->sesdata = NULL;
4882 /* CACHENOTIFY
4883 			eptr->cacheddirs = NULL;
4884 */
4885 			memset(eptr->passwordrnd,0,32);
4886 //			eptr->openedfiles = NULL;
4887 		}
4888 	}
4889 
4890 // read
4891 	for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
4892 		if (eptr->pdescpos>=0) {
4893 			if ((pdesc[eptr->pdescpos].revents & (POLLERR|POLLIN))==POLLIN && eptr->mode!=KILL) {
4894 				matoclserv_read(eptr,now);
4895 			}
4896 			if (pdesc[eptr->pdescpos].revents & (POLLERR|POLLHUP)) {
4897 				eptr->input_end = 1;
4898 			}
4899 		}
4900 		matoclserv_parse(eptr);
4901 	}
4902 
4903 // write
4904 	for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
4905 		if (eptr->lastwrite+1.0<now && eptr->registered<100 && eptr->outputhead==NULL) {
4906 			uint8_t *ptr = matoclserv_createpacket(eptr,ANTOAN_NOP,4);	// 4 byte length because of 'msgid'
4907 			*((uint32_t*)ptr) = 0;
4908 		}
4909 		if (eptr->pdescpos>=0) {
4910 /* CACHENOTIFY
4911 			if (eptr->notifications) {
4912 				if (eptr->version>=VERSION2INT(1,6,22)) {
4913 					uint8_t *ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_NOTIFY_END,4);	// transaction end
4914 					*((uint32_t*)ptr) = 0;
4915 				}
4916 				eptr->notifications = 0;
4917 			}
4918 */
4919 			if ((((pdesc[eptr->pdescpos].events & POLLOUT)==0 && (eptr->outputhead)) || (pdesc[eptr->pdescpos].revents & POLLOUT)) && eptr->mode!=KILL) {
4920 				matoclserv_write(eptr,now);
4921 			}
4922 		}
4923 		if (eptr->lastread+10.0<now) {
4924 			eptr->mode = KILL;
4925 		}
4926 		if (eptr->mode==FINISH && eptr->outputhead==NULL) {
4927 			eptr->mode = KILL;
4928 		}
4929 	}
4930 
4931 	matoclserv_disconnection_loop();
4932 }
4933 
matoclserv_keep_alive(void)4934 void matoclserv_keep_alive(void) {
4935 	double now;
4936 	matoclserventry *eptr;
4937 
4938 	now = monotonic_seconds();
4939 	for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
4940 		if (eptr->mode == DATA && eptr->input_end==0) {
4941 			matoclserv_read(eptr,now);
4942 		}
4943 	}
4944 	for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
4945 		if (eptr->lastwrite+1.0<now && eptr->registered<100 && eptr->outputhead==NULL) {
4946 			uint8_t *ptr = matoclserv_createpacket(eptr,ANTOAN_NOP,4);	// 4 byte length because of 'msgid'
4947 			*((uint32_t*)ptr) = 0;
4948 		}
4949 		if (eptr->mode == DATA && eptr->outputhead) {
4950 			matoclserv_write(eptr,now);
4951 		}
4952 	}
4953 }
4954 
matoclserv_term(void)4955 void matoclserv_term(void) {
4956 	matoclserventry *eptr,*eaptr;
4957 	in_packetstruct *ipptr,*ipaptr;
4958 	out_packetstruct *opptr,*opaptr;
4959 	chunklist *cl,*cln;
4960 //	session *ss,*ssn;
4961 //	filelist *of,*ofn;
4962 
4963 	syslog(LOG_NOTICE,"main master server module: closing %s:%s",ListenHost,ListenPort);
4964 	tcpclose(lsock);
4965 
4966 	eptr = matoclservhead;
4967 	while (eptr) {
4968 		if (eptr->input_packet) {
4969 			free(eptr->input_packet);
4970 		}
4971 		ipptr = eptr->inputhead;
4972 		while (ipptr) {
4973 			ipaptr = ipptr;
4974 			ipptr = ipptr->next;
4975 			free(ipaptr);
4976 		}
4977 		opptr = eptr->outputhead;
4978 		while (opptr) {
4979 			opaptr = opptr;
4980 			opptr = opptr->next;
4981 			free(opaptr);
4982 		}
4983 		for (cl = eptr->chunkdelayedops ; cl ; cl = cln) {
4984 			cln = cl->next;
4985 			free(cl);
4986 		}
4987 		eaptr = eptr;
4988 		eptr = eptr->next;
4989 		free(eaptr);
4990 	}
4991 	matoclservhead=NULL;
4992 
4993 	matoclserv_read(NULL,0.0); // free internal read buffer
4994 	matoclserv_gid_storage(0); // free supplementary groups buffer
4995 
4996 	free(ListenHost);
4997 	free(ListenPort);
4998 }
4999 
matoclserv_no_more_pending_jobs(void)5000 int matoclserv_no_more_pending_jobs(void) {
5001 	matoclserventry *eptr;
5002 	for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
5003 		if (eptr->outputhead!=NULL) {
5004 			return 0;
5005 		}
5006 		if (eptr->chunkdelayedops!=NULL) {
5007 			return 0;
5008 		}
5009 	}
5010 	return 1;
5011 }
5012 
matoclserv_disconnect_all(void)5013 void matoclserv_disconnect_all(void) {
5014 	matoclserventry *eptr;
5015 	for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
5016 		eptr->mode = KILL;
5017 	}
5018 	matoclserv_disconnection_loop();
5019 }
5020 
matoclserv_start_cond_check(void)5021 void matoclserv_start_cond_check(void) {
5022 	if (starting) {
5023 // very simple condition checking if all chunkservers have been connected
5024 // in the future master will know his chunkservers list and then this condition will be changed
5025 		if (chunk_get_missing_count()<100) {
5026 			starting=0;
5027 		} else {
5028 			starting--;
5029 		}
5030 	}
5031 }
5032 
5033 /*
5034 int matoclserv_sessionsinit(void) {
5035 	fprintf(stderr,"loading sessions ... ");
5036 	fflush(stderr);
5037 	sessionshead = NULL;
5038 	switch (matoclserv_load_sessions()) {
5039 		case 0:	// no file
5040 			fprintf(stderr,"file not found\n");
5041 			fprintf(stderr,"if it is not fresh installation then you have to restart all active mounts !!!\n");
5042 			matoclserv_store_sessions();
5043 			break;
5044 		case 1: // file loaded
5045 			fprintf(stderr,"ok\n");
5046 			fprintf(stderr,"sessions file has been loaded\n");
5047 			break;
5048 		default:
5049 			fprintf(stderr,"error\n");
5050 			fprintf(stderr,"due to missing sessions you have to restart all active mounts !!!\n");
5051 			break;
5052 	}
5053 	SessionSustainTime = cfg_getuint32("SESSION_SUSTAIN_TIME",86400);
5054 	if (SessionSustainTime>7*86400) {
5055 		SessionSustainTime=7*86400;
5056 		mfs_syslog(LOG_WARNING,"SESSION_SUSTAIN_TIME too big (more than week) - setting this value to one week");
5057 	}
5058 	if (SessionSustainTime<60) {
5059 		SessionSustainTime=60;
5060 		mfs_syslog(LOG_WARNING,"SESSION_SUSTAIN_TIME too low (less than minute) - setting this value to one minute");
5061 	}
5062 	return 0;
5063 }
5064 */
5065 
matoclserv_reload(void)5066 void matoclserv_reload(void) {
5067 	char *oldListenHost,*oldListenPort;
5068 	int newlsock;
5069 /*
5070 	SessionSustainTime = cfg_getuint32("SESSION_SUSTAIN_TIME",86400);
5071 	if (SessionSustainTime>7*86400) {
5072 		SessionSustainTime=7*86400;
5073 		mfs_syslog(LOG_WARNING,"SESSION_SUSTAIN_TIME too big (more than week) - setting this value to one week");
5074 	}
5075 	if (SessionSustainTime<60) {
5076 		SessionSustainTime=60;
5077 		mfs_syslog(LOG_WARNING,"SESSION_SUSTAIN_TIME too low (less than minute) - setting this value to one minute");
5078 	}
5079 */
5080 	oldListenHost = ListenHost;
5081 	oldListenPort = ListenPort;
5082 	if (cfg_isdefined("MATOCL_LISTEN_HOST") || cfg_isdefined("MATOCL_LISTEN_PORT") || !(cfg_isdefined("MATOCU_LISTEN_HOST") || cfg_isdefined("MATOCU_LISTEN_HOST"))) {
5083 		ListenHost = cfg_getstr("MATOCL_LISTEN_HOST","*");
5084 		ListenPort = cfg_getstr("MATOCL_LISTEN_PORT",DEFAULT_MASTER_CLIENT_PORT);
5085 	} else {
5086 		ListenHost = cfg_getstr("MATOCU_LISTEN_HOST","*"); // deprecated option
5087 		ListenPort = cfg_getstr("MATOCU_LISTEN_PORT",DEFAULT_MASTER_CLIENT_PORT); // deprecated option
5088 	}
5089 	if (strcmp(oldListenHost,ListenHost)==0 && strcmp(oldListenPort,ListenPort)==0) {
5090 		free(oldListenHost);
5091 		free(oldListenPort);
5092 		mfs_arg_syslog(LOG_NOTICE,"main master server module: socket address hasn't changed (%s:%s)",ListenHost,ListenPort);
5093 		return;
5094 	}
5095 
5096 	newlsock = tcpsocket();
5097 	if (newlsock<0) {
5098 		mfs_errlog(LOG_WARNING,"main master server module: socket address has changed, but can't create new socket");
5099 		free(ListenHost);
5100 		free(ListenPort);
5101 		ListenHost = oldListenHost;
5102 		ListenPort = oldListenPort;
5103 		return;
5104 	}
5105 	tcpnonblock(newlsock);
5106 	tcpnodelay(newlsock);
5107 	tcpreuseaddr(newlsock);
5108 	if (tcpstrlisten(newlsock,ListenHost,ListenPort,100)<0) {
5109 		mfs_arg_errlog(LOG_ERR,"main master server module: socket address has changed, but can't listen on socket (%s:%s)",ListenHost,ListenPort);
5110 		free(ListenHost);
5111 		free(ListenPort);
5112 		ListenHost = oldListenHost;
5113 		ListenPort = oldListenPort;
5114 		tcpclose(newlsock);
5115 		return;
5116 	}
5117 	if (tcpsetacceptfilter(newlsock)<0 && errno!=ENOTSUP) {
5118 		mfs_errlog_silent(LOG_NOTICE,"main master server module: can't set accept filter");
5119 	}
5120 	mfs_arg_syslog(LOG_NOTICE,"main master server module: socket address has changed, now listen on %s:%s",ListenHost,ListenPort);
5121 	free(oldListenHost);
5122 	free(oldListenPort);
5123 	tcpclose(lsock);
5124 	lsock = newlsock;
5125 }
5126 
matoclserv_init(void)5127 int matoclserv_init(void) {
5128 	if (cfg_isdefined("MATOCL_LISTEN_HOST") || cfg_isdefined("MATOCL_LISTEN_PORT") || !(cfg_isdefined("MATOCU_LISTEN_HOST") || cfg_isdefined("MATOCU_LISTEN_HOST"))) {
5129 		ListenHost = cfg_getstr("MATOCL_LISTEN_HOST","*");
5130 		ListenPort = cfg_getstr("MATOCL_LISTEN_PORT",DEFAULT_MASTER_CLIENT_PORT);
5131 	} else {
5132 		fprintf(stderr,"change MATOCU_LISTEN_* option names to MATOCL_LISTEN_* !!!\n");
5133 		ListenHost = cfg_getstr("MATOCU_LISTEN_HOST","*"); // deprecated option
5134 		ListenPort = cfg_getstr("MATOCU_LISTEN_PORT",DEFAULT_MASTER_CLIENT_PORT); // deprecated option
5135 	}
5136 
5137 	starting = 12;
5138 	lsock = tcpsocket();
5139 	if (lsock<0) {
5140 		mfs_errlog(LOG_ERR,"main master server module: can't create socket");
5141 		return -1;
5142 	}
5143 	tcpnonblock(lsock);
5144 	tcpnodelay(lsock);
5145 	tcpreuseaddr(lsock);
5146 	if (tcpstrlisten(lsock,ListenHost,ListenPort,100)<0) {
5147 		mfs_arg_errlog(LOG_ERR,"main master server module: can't listen on %s:%s",ListenHost,ListenPort);
5148 		return -1;
5149 	}
5150 	if (tcpsetacceptfilter(lsock)<0 && errno!=ENOTSUP) {
5151 		mfs_errlog_silent(LOG_NOTICE,"main master server module: can't set accept filter");
5152 	}
5153 	mfs_arg_syslog(LOG_NOTICE,"main master server module: listen on %s:%s",ListenHost,ListenPort);
5154 
5155 	matoclservhead = NULL;
5156 /* CACHENOTIFY
5157 	matoclserv_dircache_init();
5158 */
5159 
5160 	main_time_register(10,0,matoclserv_start_cond_check);
5161 //	main_time_register(10,0,matocl_session_check);
5162 //	main_time_register(3600,0,matocl_session_statsmove);
5163 	main_reload_register(matoclserv_reload);
5164 	main_destruct_register(matoclserv_term);
5165 	main_poll_register(matoclserv_desc,matoclserv_serve);
5166 	main_keepalive_register(matoclserv_keep_alive);
5167 //	main_wantexit_register(matoclserv_wantexit);
5168 //	main_canexit_register(matoclserv_canexit);
5169 	return 0;
5170 }
5171