1 /*
2  * Copyright (C) 2021 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 <stdlib.h>
27 #include <string.h>
28 #include <inttypes.h>
29 
30 #include "MFSCommunication.h"
31 #include "sharedpointer.h"
32 #include "filesystem.h"
33 #include "sessions.h"
34 #include "openfiles.h"
35 #include "flocklocks.h"
36 #include "posixlocks.h"
37 #include "csdb.h"
38 #include "chunks.h"
39 #include "storageclass.h"
40 #include "metadata.h"
41 #include "slogger.h"
42 #include "massert.h"
43 #include "mfsstrerr.h"
44 
45 #define EAT(clptr,fn,vno,c) { \
46 	if (*(clptr)!=(c)) { \
47 		mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": '%c' expected",(fn),(vno),(c)); \
48 		return -1; \
49 	} \
50 	(clptr)++; \
51 }
52 
53 #define GETNAME(name,clptr,fn,vno,c) { \
54 	uint32_t _tmp_i; \
55 	char _tmp_c,_tmp_h1,_tmp_h2; \
56 	memset((void*)(name),0,256); \
57 	_tmp_i = 0; \
58 	while ((_tmp_c=*((clptr)++))!=c && _tmp_i<255) { \
59 		if (_tmp_c=='\0' || _tmp_c=='\r' || _tmp_c=='\n') { \
60 			mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": '%c' expected",(fn),(vno),(c)); \
61 			return -1; \
62 		} \
63 		if (_tmp_c=='%') { \
64 			_tmp_h1 = *((clptr)++); \
65 			_tmp_h2 = *((clptr)++); \
66 			if (_tmp_h1>='0' && _tmp_h1<='9') { \
67 				_tmp_h1-='0'; \
68 			} else if (_tmp_h1>='A' && _tmp_h1<='F') { \
69 				_tmp_h1-=('A'-10); \
70 			} else { \
71 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": hex expected",(fn),(vno)); \
72 				return -1; \
73 			} \
74 			if (_tmp_h2>='0' && _tmp_h2<='9') { \
75 				_tmp_h2-='0'; \
76 			} else if (_tmp_h2>='A' && _tmp_h2<='F') { \
77 				_tmp_h2-=('A'-10); \
78 			} else { \
79 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": hex expected",(fn),(vno)); \
80 				return -1; \
81 			} \
82 			_tmp_c = _tmp_h1*16+_tmp_h2; \
83 		} \
84 		name[_tmp_i++] = _tmp_c; \
85 	} \
86 	(clptr)--; \
87 	name[_tmp_i]=0; \
88 }
89 
90 #define GETPATH(path,size,clptr,fn,vno,c) { \
91 	uint32_t _tmp_i; \
92 	char _tmp_c,_tmp_h1,_tmp_h2; \
93 	_tmp_i = 0; \
94 	while ((_tmp_c=*((clptr)++))!=c) { \
95 		if (_tmp_c=='\0' || _tmp_c=='\r' || _tmp_c=='\n') { \
96 			mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": '%c' expected",(fn),(vno),(c)); \
97 			return -1; \
98 		} \
99 		if (_tmp_c=='%') { \
100 			_tmp_h1 = *((clptr)++); \
101 			_tmp_h2 = *((clptr)++); \
102 			if (_tmp_h1>='0' && _tmp_h1<='9') { \
103 				_tmp_h1-='0'; \
104 			} else if (_tmp_h1>='A' && _tmp_h1<='F') { \
105 				_tmp_h1-=('A'-10); \
106 			} else { \
107 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": hex expected",(fn),(vno)); \
108 				return -1; \
109 			} \
110 			if (_tmp_h2>='0' && _tmp_h2<='9') { \
111 				_tmp_h2-='0'; \
112 			} else if (_tmp_h2>='A' && _tmp_h2<='F') { \
113 				_tmp_h2-=('A'-10); \
114 			} else { \
115 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": hex expected",(fn),(vno)); \
116 				return -1; \
117 			} \
118 			_tmp_c = _tmp_h1*16+_tmp_h2; \
119 		} \
120 		if ((_tmp_i)>=(size)) { \
121 			(size) = _tmp_i+1000; \
122 			if ((path)==NULL) { \
123 				(path) = malloc(size); \
124 			} else { \
125 				uint8_t *_tmp_path = (path); \
126 				(path) = realloc((path),(size)); \
127 				if ((path)==NULL) { \
128 					free(_tmp_path); \
129 				} \
130 			} \
131 			passert(path); \
132 		} \
133 		(path)[_tmp_i++]=_tmp_c; \
134 	} \
135 	if ((_tmp_i)>=(size)) { \
136 		(size) = _tmp_i+1000; \
137 		if ((path)==NULL) { \
138 			(path) = malloc(size); \
139 		} else { \
140 			uint8_t *_tmp_path = (path); \
141 			(path) = realloc((path),(size)); \
142 			if ((path)==NULL) { \
143 				free(_tmp_path); \
144 			} \
145 		} \
146 		passert(path); \
147 	} \
148 	(clptr)--; \
149 	(path)[_tmp_i]=0; \
150 }
151 
152 #define GETDATA(buff,leng,size,clptr,fn,vno,c) { \
153 	char _tmp_c,_tmp_h1,_tmp_h2; \
154 	(leng) = 0; \
155 	while ((_tmp_c=*((clptr)++))!=c) { \
156 		if (_tmp_c=='\0' || _tmp_c=='\r' || _tmp_c=='\n') { \
157 			mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": '%c' expected",(fn),(vno),(c)); \
158 			return -1; \
159 		} \
160 		if (_tmp_c=='%') { \
161 			_tmp_h1 = *((clptr)++); \
162 			_tmp_h2 = *((clptr)++); \
163 			if (_tmp_h1>='0' && _tmp_h1<='9') { \
164 				_tmp_h1-='0'; \
165 			} else if (_tmp_h1>='A' && _tmp_h1<='F') { \
166 				_tmp_h1-=('A'-10); \
167 			} else { \
168 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": hex expected",(fn),(vno)); \
169 				return -1; \
170 			} \
171 			if (_tmp_h2>='0' && _tmp_h2<='9') { \
172 				_tmp_h2-='0'; \
173 			} else if (_tmp_h2>='A' && _tmp_h2<='F') { \
174 				_tmp_h2-=('A'-10); \
175 			} else { \
176 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": hex expected",(fn),(vno)); \
177 				return -1; \
178 			} \
179 			_tmp_c = _tmp_h1*16+_tmp_h2; \
180 		} \
181 		if ((leng)>=(size)) { \
182 			(size) = (leng)+1000; \
183 			if ((buff)==NULL) { \
184 				(buff) = malloc(size); \
185 			} else { \
186 				uint8_t *_tmp_buff = (buff); \
187 				(buff) = realloc((buff),(size)); \
188 				if ((buff)==NULL) { \
189 					free(_tmp_buff); \
190 				} \
191 			} \
192 			passert(buff); \
193 		} \
194 		(buff)[(leng)++]=_tmp_c; \
195 	} \
196 	(clptr)--; \
197 }
198 
199 #define GETARRAYU32(buff,leng,size,clptr,fn,vno) { \
200 	char _tmp_c; \
201 	char *eptr; \
202 	(leng) = 0; \
203 	_tmp_c = *((clptr)++); \
204 	if (_tmp_c!='[') { \
205 		mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": '[' expected",(fn),(vno)); \
206 		return -1; \
207 	} \
208 	while ((_tmp_c=*((clptr)++))!=']') { \
209 		if (_tmp_c=='\0' || _tmp_c=='\r' || _tmp_c=='\n') { \
210 			mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": ']' expected",(fn),(vno)); \
211 			return -1; \
212 		} \
213 		if (_tmp_c>='0' && _tmp_c<='9') { \
214 			if ((leng)>=(size)) { \
215 				(size) = (leng)+32; \
216 				if ((buff)==NULL) { \
217 					(buff) = malloc((size)*sizeof(uint32_t)); \
218 				} else { \
219 					uint32_t *_tmp_buff = (buff); \
220 					(buff) = realloc((buff),(size)*sizeof(uint32_t)); \
221 					if ((buff)==NULL) { \
222 						free(_tmp_buff); \
223 					} \
224 				} \
225 				passert(buff); \
226 			} \
227 			(buff)[(leng)++] = strtoul(clptr,&eptr,10); \
228 			clptr = (const char*)eptr; \
229 		} else if (_tmp_c!=',') { \
230 			mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": number or ',' expected",(fn),(vno)); \
231 			return -1; \
232 		} \
233 	} \
234 }
235 
236 #define GETU8(data,clptr) { \
237 	uint32_t tmp; \
238 	char *eptr; \
239 	tmp=strtoul(clptr,&eptr,10); \
240 	clptr = (const char*)eptr; \
241 	if (tmp>255) { \
242 		mfs_arg_syslog(LOG_WARNING,"value too big (%"PRIu32" - 0-255 expected)",tmp); \
243 		return -1; \
244 	} \
245 	(data)=tmp; \
246 }
247 
248 #define GETU16(data,clptr) { \
249 	uint32_t tmp; \
250 	char *eptr; \
251 	tmp=strtoul(clptr,&eptr,10); \
252 	clptr = (const char*)eptr; \
253 	if (tmp>65535) { \
254 		mfs_arg_syslog(LOG_WARNING,"value too big (%"PRIu32" - 0-65535 expected)",tmp); \
255 		return -1; \
256 	} \
257 	(data)=tmp; \
258 }
259 
260 #define GETU32(data,clptr) { \
261 	char *eptr; \
262 	(data)=strtoul(clptr,&eptr,10); \
263 	clptr = (const char*)eptr; \
264 }
265 
266 #define GETX32(data,clptr) { \
267 	char *eptr; \
268 	(data)=strtoul(clptr,&eptr,16); \
269 	clptr = (const char*)eptr; \
270 }
271 
272 #define GETU64(data,clptr) { \
273 	char *eptr; \
274 	(data)=strtoull(clptr,&eptr,10); \
275 	clptr = (const char*)eptr; \
276 }
277 
do_idle(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)278 int do_idle(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
279 	(void)ts;
280 	EAT(ptr,filename,lv,'(');
281 	EAT(ptr,filename,lv,')');
282 	(void)ptr; // silence cppcheck warnings
283 	meta_version_inc(); // no-operation - just increase meta version and return OK.
284 	return MFS_STATUS_OK;
285 }
286 
do_access(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)287 int do_access(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
288 	uint32_t inode;
289 	EAT(ptr,filename,lv,'(');
290 	GETU32(inode,ptr);
291 	EAT(ptr,filename,lv,')');
292 	(void)ptr; // silence cppcheck warnings
293 	return fs_mr_access(ts,inode);
294 }
295 
do_append(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)296 int do_append(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
297 	uint32_t inode,inode_src;
298 	uint32_t slice_from,slice_to;
299 	EAT(ptr,filename,lv,'(');
300 	GETU32(inode,ptr);
301 	EAT(ptr,filename,lv,',');
302 	GETU32(inode_src,ptr);
303 	if (*ptr==')') {
304 		slice_from = 0xFFFFFFFF;
305 		slice_to = 0;
306 	} else {
307 		EAT(ptr,filename,lv,',');
308 		GETU32(slice_from,ptr);
309 		EAT(ptr,filename,lv,',');
310 		GETU32(slice_to,ptr);
311 	}
312 	EAT(ptr,filename,lv,')');
313 	(void)ptr; // silence cppcheck warnings
314 	return fs_mr_append_slice(ts,inode,inode_src,slice_from,slice_to);
315 }
316 
do_acquire(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)317 int do_acquire(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
318 	uint32_t inode,cuid;
319 	(void)ts;
320 	EAT(ptr,filename,lv,'(');
321 	GETU32(inode,ptr);
322 	EAT(ptr,filename,lv,',');
323 	GETU32(cuid,ptr);
324 	EAT(ptr,filename,lv,')');
325 	(void)ptr; // silence cppcheck warnings
326 	return of_mr_acquire(inode,cuid);
327 }
328 
do_archchg(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)329 int do_archchg(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
330 	uint32_t inode,uid,nsinodes;
331 	uint8_t flags;
332 	uint64_t chgchunks,notchgchunks;
333 	EAT(ptr,filename,lv,'(');
334 	GETU32(inode,ptr);
335 	EAT(ptr,filename,lv,',');
336 	GETU32(uid,ptr);
337 	EAT(ptr,filename,lv,',');
338 	GETU8(flags,ptr);
339 	EAT(ptr,filename,lv,')');
340 	EAT(ptr,filename,lv,':');
341 	GETU64(chgchunks,ptr);
342 	EAT(ptr,filename,lv,',');
343 	GETU64(notchgchunks,ptr);
344 	EAT(ptr,filename,lv,',');
345 	GETU32(nsinodes,ptr);
346 	(void)ptr; // silence cppcheck warnings
347 	return fs_mr_archchg(ts,inode,uid,flags,chgchunks,notchgchunks,nsinodes);
348 }
349 
do_amtime(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)350 int do_amtime(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
351 	uint32_t inode,atime,mtime,ctime;
352 	(void)ts;
353 	EAT(ptr,filename,lv,'(');
354 	GETU32(inode,ptr);
355 	EAT(ptr,filename,lv,',');
356 	GETU32(atime,ptr);
357 	EAT(ptr,filename,lv,',');
358 	GETU32(mtime,ptr);
359 	EAT(ptr,filename,lv,',');
360 	GETU32(ctime,ptr);
361 	EAT(ptr,filename,lv,')');
362 	(void)ptr; // silence cppcheck warnings
363 	return fs_mr_amtime(inode,atime,mtime,ctime);
364 }
365 
do_attr(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)366 int do_attr(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
367 	uint32_t inode,mode,uid,gid,atime,mtime,winattr,aclmode;
368 	EAT(ptr,filename,lv,'(');
369 	GETU32(inode,ptr);
370 	EAT(ptr,filename,lv,',');
371 	GETU32(mode,ptr);
372 	EAT(ptr,filename,lv,',');
373 	GETU32(uid,ptr);
374 	EAT(ptr,filename,lv,',');
375 	GETU32(gid,ptr);
376 	EAT(ptr,filename,lv,',');
377 	GETU32(atime,ptr);
378 	EAT(ptr,filename,lv,',');
379 	GETU32(mtime,ptr);
380 	if (*ptr==',') {
381 		EAT(ptr,filename,lv,',');
382 		GETU32(aclmode,ptr);
383 		if (*ptr==',') {
384 			EAT(ptr,filename,lv,',');
385 			winattr = aclmode;
386 			GETU32(aclmode,ptr);
387 		} else {
388 			winattr = 0;
389 		}
390 	} else {
391 		aclmode = mode;
392 		winattr = 0;
393 	}
394 	EAT(ptr,filename,lv,')');
395 	(void)ptr; // silence cppcheck warnings
396 	return fs_mr_attr(ts,inode,mode,uid,gid,atime,mtime,winattr,aclmode);
397 }
398 
399 /*
400 int do_copy(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
401 	uint32_t inode,parent;
402 	uint8_t name[256];
403 	EAT(ptr,filename,lv,'(');
404 	GETU32(inode,ptr);
405 	EAT(ptr,filename,lv,',');
406 	GETU32(parent,ptr);
407 	EAT(ptr,filename,lv,',');
408 	GETNAME(name,ptr,filename,lv,')');
409 	EAT(ptr,filename,lv,')');
410 	return fs_mr_copy(ts,inode,parent,strlen(name),name);
411 }
412 */
413 
do_create(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)414 int do_create(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
415 	uint32_t parent,uid,gid,rdev,inode;
416 	uint16_t mode,cumask;
417 	uint8_t type,name[256];
418 	EAT(ptr,filename,lv,'(');
419 	GETU32(parent,ptr);
420 	EAT(ptr,filename,lv,',');
421 	GETNAME(name,ptr,filename,lv,',');
422 	EAT(ptr,filename,lv,',');
423 	if (*ptr>='0' && *ptr<='9') {
424 		GETU8(type,ptr);
425 	} else {
426 		type = *ptr;
427 		ptr++;
428 	}
429 	EAT(ptr,filename,lv,',');
430 	GETU16(mode,ptr);
431 	EAT(ptr,filename,lv,',');
432 	if (type<16) {
433 		GETU16(cumask,ptr);
434 		EAT(ptr,filename,lv,',');
435 	} else {
436 		cumask = 0;
437 	}
438 	GETU32(uid,ptr);
439 	EAT(ptr,filename,lv,',');
440 	GETU32(gid,ptr);
441 	EAT(ptr,filename,lv,',');
442 	GETU32(rdev,ptr);
443 	EAT(ptr,filename,lv,')');
444 	EAT(ptr,filename,lv,':');
445 	GETU32(inode,ptr);
446 	(void)ptr; // silence cppcheck warnings
447 	return fs_mr_create(ts,parent,strlen((char*)name),name,type,mode,cumask,uid,gid,rdev,inode);
448 }
449 
do_csdbop(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)450 int do_csdbop(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
451 	uint32_t op,ip,port,arg;
452 	(void)ts;
453 	EAT(ptr,filename,lv,'(');
454 	GETU8(op,ptr);
455 	EAT(ptr,filename,lv,',');
456 	GETU32(ip,ptr);
457 	EAT(ptr,filename,lv,',');
458 	GETU16(port,ptr);
459 	EAT(ptr,filename,lv,',');
460 	GETU32(arg,ptr);
461 	EAT(ptr,filename,lv,')');
462 	(void)ptr; // silence cppcheck warnings
463 	return csdb_mr_op(op,ip,port,arg);
464 }
465 
466 /* deprecated since version 1.7.25 */
do_csadd(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)467 int do_csadd(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
468 	uint32_t ip,port;
469 	(void)ts;
470 	EAT(ptr,filename,lv,'(');
471 	GETU32(ip,ptr);
472 	EAT(ptr,filename,lv,',');
473 	GETU32(port,ptr);
474 	EAT(ptr,filename,lv,')');
475 	(void)ptr; // silence cppcheck warnings
476 	return csdb_mr_csadd(ip,port);
477 }
478 
479 /* deprecated since version 1.7.25 */
do_csdel(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)480 int do_csdel(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
481 	uint32_t ip,port;
482 	(void)ts;
483 	EAT(ptr,filename,lv,'(');
484 	GETU32(ip,ptr);
485 	EAT(ptr,filename,lv,',');
486 	GETU32(port,ptr);
487 	EAT(ptr,filename,lv,')');
488 	(void)ptr; // silence cppcheck warnings
489 	return csdb_mr_csdel(ip,port);
490 }
491 
do_chunkadd(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)492 int do_chunkadd(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
493 	uint64_t chunkid;
494 	uint32_t version,lockedto;
495 	EAT(ptr,filename,lv,'(');
496 	GETU64(chunkid,ptr);
497 	EAT(ptr,filename,lv,',');
498 	GETU32(version,ptr);
499 	EAT(ptr,filename,lv,',');
500 	GETU32(lockedto,ptr);
501 	EAT(ptr,filename,lv,')');
502 	(void)ptr; // silence cppcheck warnings
503 	return chunk_mr_chunkadd(ts,chunkid,version,lockedto);
504 }
505 
do_chunkdel(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)506 int do_chunkdel(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
507 	uint64_t chunkid;
508 	uint32_t version;
509 	(void)ts;
510 	EAT(ptr,filename,lv,'(');
511 	GETU64(chunkid,ptr);
512 	EAT(ptr,filename,lv,',');
513 	GETU32(version,ptr);
514 	EAT(ptr,filename,lv,')');
515 	(void)ptr; // silence cppcheck warnings
516 	return chunk_mr_chunkdel(ts,chunkid,version);
517 }
518 
do_emptytrash(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)519 int do_emptytrash(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
520 	uint32_t sustainedinodes,freeinodes,inode_chksum,bid;
521 	EAT(ptr,filename,lv,'(');
522 	if (*ptr!=')') {
523 		GETU32(bid,ptr);
524 	} else {
525 		bid = 0xFFFFFFFF;
526 	}
527 	EAT(ptr,filename,lv,')');
528 	EAT(ptr,filename,lv,':');
529 	GETU32(freeinodes,ptr);
530 	EAT(ptr,filename,lv,',');
531 	GETU32(sustainedinodes,ptr);
532 	if (*ptr==',') {
533 		EAT(ptr,filename,lv,',');
534 		GETU32(inode_chksum,ptr);
535 	} else {
536 		inode_chksum = 0;
537 	}
538 	(void)ptr; // silence cppcheck warnings
539 	return fs_mr_emptytrash(ts,bid,freeinodes,sustainedinodes,inode_chksum);
540 }
541 
do_emptysustained(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)542 int do_emptysustained(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
543 	uint32_t freeinodes,inode_chksum,bid;
544 	EAT(ptr,filename,lv,'(');
545 	if (*ptr!=')') {
546 		GETU32(bid,ptr);
547 	} else {
548 		bid = 0xFFFFFFFF;
549 	}
550 	EAT(ptr,filename,lv,')');
551 	EAT(ptr,filename,lv,':');
552 	GETU32(freeinodes,ptr);
553 	if (*ptr==',') {
554 		EAT(ptr,filename,lv,',');
555 		GETU32(inode_chksum,ptr);
556 	} else {
557 		inode_chksum = 0;
558 	}
559 	(void)ptr; // silence cppcheck warnings
560 	return fs_mr_emptysustained(ts,bid,freeinodes,inode_chksum);
561 }
562 
do_flock(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)563 int do_flock(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
564 	uint32_t inode,sessionid;
565 	uint64_t owner;
566 	char cmd;
567 	(void)ts;
568 	EAT(ptr,filename,lv,'(');
569 	GETU32(inode,ptr);
570 	EAT(ptr,filename,lv,',');
571 	GETU32(sessionid,ptr);
572 	EAT(ptr,filename,lv,',');
573 	GETU64(owner,ptr);
574 	EAT(ptr,filename,lv,',');
575 	cmd = *ptr;
576 	ptr++;
577 	EAT(ptr,filename,lv,')');
578 	(void)ptr; // silence cppcheck warnings
579 	return flock_mr_change(inode,sessionid,owner,cmd);
580 }
581 
do_freeinodes(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)582 int do_freeinodes(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
583 	uint32_t sustainedinodes,freeinodes,inode_chksum;
584 	uint32_t inodereusedelay;
585 	EAT(ptr,filename,lv,'(');
586 	if (*ptr==')') {
587 		inodereusedelay = 86400;
588 	} else {
589 		GETU32(inodereusedelay,ptr);
590 	}
591 	EAT(ptr,filename,lv,')');
592 	EAT(ptr,filename,lv,':');
593 	GETU32(freeinodes,ptr);
594 	if (*ptr==',') {
595 		EAT(ptr,filename,lv,',');
596 		GETU32(sustainedinodes,ptr);
597 	} else {
598 		sustainedinodes = 0;
599 	}
600 	if (*ptr==',') {
601 		EAT(ptr,filename,lv,',');
602 		GETU32(inode_chksum,ptr);
603 	} else {
604 		inode_chksum = 0;
605 	}
606 	(void)ptr; // silence cppcheck warnings
607 	return fs_mr_freeinodes(ts,inodereusedelay,freeinodes,sustainedinodes,inode_chksum);
608 }
609 
do_incversion(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)610 int do_incversion(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) { // depreciated - replaced by 'setversion'
611 	uint64_t chunkid;
612 	(void)ts;
613 	EAT(ptr,filename,lv,'(');
614 	GETU64(chunkid,ptr);
615 	EAT(ptr,filename,lv,')');
616 	(void)ptr; // silence cppcheck warnings
617 	return chunk_mr_increase_version(chunkid);
618 }
619 
do_setversion(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)620 int do_setversion(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
621 	uint64_t chunkid;
622 	uint32_t version;
623 	(void)ts;
624 	EAT(ptr,filename,lv,'(');
625 	GETU64(chunkid,ptr);
626 	EAT(ptr,filename,lv,',');
627 	GETU32(version,ptr);
628 	EAT(ptr,filename,lv,')');
629 	(void)ptr; // silence cppcheck warnings
630 	return chunk_mr_set_version(chunkid,version);
631 }
632 
633 
do_link(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)634 int do_link(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
635 	uint32_t inode,parent;
636 	uint8_t name[256];
637 	EAT(ptr,filename,lv,'(');
638 	GETU32(inode,ptr);
639 	EAT(ptr,filename,lv,',');
640 	GETU32(parent,ptr);
641 	EAT(ptr,filename,lv,',');
642 	GETNAME(name,ptr,filename,lv,')');
643 	EAT(ptr,filename,lv,')');
644 	(void)ptr; // silence cppcheck warnings
645 	return fs_mr_link(ts,inode,parent,strlen((char*)name),name);
646 }
647 
do_length(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)648 int do_length(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
649 	uint32_t inode;
650 	uint64_t length;
651 	uint8_t canmodmtime;
652 	EAT(ptr,filename,lv,'(');
653 	GETU32(inode,ptr);
654 	EAT(ptr,filename,lv,',');
655 	GETU64(length,ptr);
656 	if (*ptr==',') {
657 		EAT(ptr,filename,lv,',');
658 		GETU8(canmodmtime,ptr);
659 	} else {
660 		canmodmtime = 1;
661 	}
662 	EAT(ptr,filename,lv,')');
663 	(void)ptr; // silence cppcheck warnings
664 	return fs_mr_length(ts,inode,length,canmodmtime);
665 }
666 
do_move(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)667 int do_move(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
668 	uint32_t inode,parent_src,parent_dst;
669 	uint8_t name_src[256],name_dst[256];
670 	EAT(ptr,filename,lv,'(');
671 	GETU32(parent_src,ptr);
672 	EAT(ptr,filename,lv,',');
673 	GETNAME(name_src,ptr,filename,lv,',');
674 	EAT(ptr,filename,lv,',');
675 	GETU32(parent_dst,ptr);
676 	EAT(ptr,filename,lv,',');
677 	GETNAME(name_dst,ptr,filename,lv,')');
678 	EAT(ptr,filename,lv,')');
679 	EAT(ptr,filename,lv,':');
680 	GETU32(inode,ptr);
681 	(void)ptr; // silence cppcheck warnings
682 	return fs_mr_move(ts,parent_src,strlen((char*)name_src),name_src,parent_dst,strlen((char*)name_dst),name_dst,inode);
683 }
684 
do_nextchunkid(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)685 int do_nextchunkid(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
686 	uint64_t chunkid;
687 	(void)ts;
688 	EAT(ptr,filename,lv,'(');
689 	GETU64(chunkid,ptr);
690 	EAT(ptr,filename,lv,')');
691 	(void)ptr; // silence cppcheck warnings
692 	return chunk_mr_nextchunkid(chunkid);
693 }
694 
do_posixlock(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)695 int do_posixlock(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
696 	uint32_t inode,sessionid,pid;
697 	uint64_t owner,start,end;
698 	char cmd;
699 	(void)ts;
700 	EAT(ptr,filename,lv,'(');
701 	GETU32(inode,ptr);
702 	EAT(ptr,filename,lv,',');
703 	GETU32(sessionid,ptr);
704 	EAT(ptr,filename,lv,',');
705 	GETU64(owner,ptr);
706 	EAT(ptr,filename,lv,',');
707 	cmd = *ptr;
708 	ptr++;
709 	EAT(ptr,filename,lv,',');
710 	GETU64(start,ptr);
711 	EAT(ptr,filename,lv,',');
712 	GETU64(end,ptr);
713 	EAT(ptr,filename,lv,',');
714 	GETU32(pid,ptr);
715 	EAT(ptr,filename,lv,')');
716 	(void)ptr; // silence cppcheck warnings
717 	return posix_lock_mr_change(inode,sessionid,owner,cmd,start,end,pid);
718 }
719 
do_purge(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)720 int do_purge(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
721 	uint32_t inode;
722 	EAT(ptr,filename,lv,'(');
723 	GETU32(inode,ptr);
724 	EAT(ptr,filename,lv,')');
725 	(void)ptr; // silence cppcheck warnings
726 	return fs_mr_purge(ts,inode);
727 }
728 
do_quota(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)729 int do_quota(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
730 	uint32_t inode,stimestamp,sinodes,hinodes;
731 	uint64_t slength,ssize,srealsize;
732 	uint64_t hlength,hsize,hrealsize;
733 	uint32_t flags,exceeded,timelimit;
734 	EAT(ptr,filename,lv,'(');
735 	GETU32(inode,ptr);
736 	EAT(ptr,filename,lv,',');
737 	GETU32(exceeded,ptr);
738 	EAT(ptr,filename,lv,',');
739 	GETU32(flags,ptr);
740 	EAT(ptr,filename,lv,',');
741 	GETU32(stimestamp,ptr);
742 	EAT(ptr,filename,lv,',');
743 	GETU32(sinodes,ptr);
744 	EAT(ptr,filename,lv,',');
745 	GETU32(hinodes,ptr);
746 	EAT(ptr,filename,lv,',');
747 	GETU64(slength,ptr);
748 	EAT(ptr,filename,lv,',');
749 	GETU64(hlength,ptr);
750 	EAT(ptr,filename,lv,',');
751 	GETU64(ssize,ptr);
752 	EAT(ptr,filename,lv,',');
753 	GETU64(hsize,ptr);
754 	EAT(ptr,filename,lv,',');
755 	GETU64(srealsize,ptr);
756 	EAT(ptr,filename,lv,',');
757 	GETU64(hrealsize,ptr);
758 	if (*ptr==',') {
759 		EAT(ptr,filename,lv,',');
760 		GETU32(timelimit,ptr);
761 	} else {
762 		timelimit = 0;
763 	}
764 	EAT(ptr,filename,lv,')');
765 	(void)ptr; // silence cppcheck warnings
766 	return fs_mr_quota(ts,inode,exceeded,flags,stimestamp,sinodes,hinodes,slength,hlength,ssize,hsize,srealsize,hrealsize,timelimit);
767 }
768 
769 /*
770 int do_reinit(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
771 	uint32_t inode,indx;
772 	uint64_t chunkid;
773 	EAT(ptr,filename,lv,'(');
774 	GETU32(inode,ptr);
775 	EAT(ptr,filename,lv,',');
776 	GETU32(indx,ptr);
777 	EAT(ptr,filename,lv,')');
778 	EAT(ptr,filename,lv,':');
779 	GETU64(chunkid,ptr);
780 	return fs_mr_reinit(ts,inode,indx,chunkid);
781 }
782 */
do_release(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)783 int do_release(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
784 	uint32_t inode,cuid;
785 	(void)ts;
786 	EAT(ptr,filename,lv,'(');
787 	GETU32(inode,ptr);
788 	EAT(ptr,filename,lv,',');
789 	GETU32(cuid,ptr);
790 	EAT(ptr,filename,lv,')');
791 	(void)ptr; // silence cppcheck warnings
792 	return of_mr_release(inode,cuid);
793 }
794 
do_repair(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)795 int do_repair(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
796 	uint32_t inode,indx;
797 	uint32_t version;
798 	EAT(ptr,filename,lv,'(');
799 	GETU32(inode,ptr);
800 	EAT(ptr,filename,lv,',');
801 	GETU32(indx,ptr);
802 	EAT(ptr,filename,lv,')');
803 	EAT(ptr,filename,lv,':');
804 	GETU32(version,ptr);
805 	(void)ptr; // silence cppcheck warnings
806 	return fs_mr_repair(ts,inode,indx,version);
807 }
808 
do_renumedges(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)809 int do_renumedges(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
810 	uint64_t enextedgeid;
811 	(void)ts;
812 	EAT(ptr,filename,lv,'(');
813 	EAT(ptr,filename,lv,')');
814 	EAT(ptr,filename,lv,':');
815 	GETU64(enextedgeid,ptr);
816 	(void)ptr; // silence cppcheck warnings
817 	return fs_mr_renumerate_edges(enextedgeid);
818 }
819 /*
820 int do_remove(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
821 	uint32_t inode;
822 	EAT(ptr,filename,lv,'(');
823 	GETU32(inode,ptr);
824 	EAT(ptr,filename,lv,')');
825 	return fs_mr_remove(ts,inode);
826 }
827 */
do_session(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)828 int do_session(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
829 	uint32_t sessionid;
830 	(void)ts;
831 	EAT(ptr,filename,lv,'(');
832 	EAT(ptr,filename,lv,')');
833 	EAT(ptr,filename,lv,':');
834 	GETU32(sessionid,ptr);
835 	(void)ptr; // silence cppcheck warnings
836 	return sessions_mr_session(sessionid);
837 }
838 
do_sesadd(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)839 int do_sesadd(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
840 	uint32_t rootinode,sesflags,peerip,sessionid;
841 	uint32_t rootuid,rootgid,mapalluid,mapallgid;
842 	uint32_t mingoal,maxgoal,mintrashtime,maxtrashtime;
843 	uint32_t disables;
844 	uint16_t umaskval;
845 	uint64_t exportscsum;
846 	uint32_t ileng;
847 	static uint8_t *info = NULL;
848 	static uint32_t infosize = 0;
849 
850 	(void)ts;
851 	EAT(ptr,filename,lv,'(');
852 	if (*ptr=='#') {
853 		EAT(ptr,filename,lv,'#');
854 		GETU64(exportscsum,ptr);
855 		EAT(ptr,filename,lv,',');
856 	} else {
857 		exportscsum = 0;
858 	}
859 	GETU32(rootinode,ptr);
860 	EAT(ptr,filename,lv,',');
861 	GETU32(sesflags,ptr);
862 	EAT(ptr,filename,lv,',');
863 	if (*ptr=='0') {
864 		if (ptr[1]<'0' || ptr[1]>'7' || ptr[2]<'0' || ptr[2]>'7' || ptr[3]<'0' || ptr[3]>'7') {
865 			mfs_arg_syslog(LOG_WARNING,"wrong session umask ('%c%c%c' - octal number expected)",ptr[1],ptr[2],ptr[3]);
866 			return -1;
867 		}
868 		umaskval = (ptr[1]-'0') * 64 + (ptr[2]-'0') * 8 + (ptr[3]-'0');
869 		ptr+=4;
870 		EAT(ptr,filename,lv,',');
871 	} else {
872 		umaskval=0;
873 	}
874 	GETU32(rootuid,ptr);
875 	EAT(ptr,filename,lv,',');
876 	GETU32(rootgid,ptr);
877 	EAT(ptr,filename,lv,',');
878 	GETU32(mapalluid,ptr);
879 	EAT(ptr,filename,lv,',');
880 	GETU32(mapallgid,ptr);
881 	EAT(ptr,filename,lv,',');
882 	GETU32(mingoal,ptr);
883 	EAT(ptr,filename,lv,',');
884 	GETU32(maxgoal,ptr);
885 	EAT(ptr,filename,lv,',');
886 	GETU32(mintrashtime,ptr);
887 	EAT(ptr,filename,lv,',');
888 	GETU32(maxtrashtime,ptr);
889 	EAT(ptr,filename,lv,',');
890 	if (ptr[0]=='0' && ptr[1]=='x') {
891 		ptr+=2;
892 		GETX32(disables,ptr);
893 		EAT(ptr,filename,lv,',');
894 	} else {
895 		disables = 0;
896 	}
897 	GETU32(peerip,ptr);
898 	EAT(ptr,filename,lv,',');
899 	GETDATA(info,ileng,infosize,ptr,filename,lv,')');
900 	EAT(ptr,filename,lv,')');
901 	EAT(ptr,filename,lv,':');
902 	GETU32(sessionid,ptr);
903 	(void)ptr; // silence cppcheck warnings
904 	return sessions_mr_sesadd(exportscsum,rootinode,sesflags,umaskval,rootuid,rootgid,mapalluid,mapallgid,mingoal,maxgoal,mintrashtime,maxtrashtime,disables,peerip,info,ileng,sessionid);
905 }
906 
do_seschanged(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)907 int do_seschanged(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
908 	uint32_t rootinode,sesflags,peerip,sessionid;
909 	uint32_t rootuid,rootgid,mapalluid,mapallgid;
910 	uint32_t mingoal,maxgoal,mintrashtime,maxtrashtime;
911 	uint32_t disables;
912 	uint16_t umaskval;
913 	uint64_t exportscsum;
914 	uint32_t ileng;
915 	static uint8_t *info = NULL;
916 	static uint32_t infosize = 0;
917 
918 	(void)ts;
919 	EAT(ptr,filename,lv,'(');
920 	GETU32(sessionid,ptr);
921 	EAT(ptr,filename,lv,',');
922 	if (*ptr=='#') {
923 		EAT(ptr,filename,lv,'#');
924 		GETU64(exportscsum,ptr);
925 		EAT(ptr,filename,lv,',');
926 	} else {
927 		exportscsum = 0;
928 	}
929 	GETU32(rootinode,ptr);
930 	EAT(ptr,filename,lv,',');
931 	GETU32(sesflags,ptr);
932 	EAT(ptr,filename,lv,',');
933 	if (*ptr=='0') {
934 		if (ptr[1]<'0' || ptr[1]>'7' || ptr[2]<'0' || ptr[2]>'7' || ptr[3]<'0' || ptr[3]>'7') {
935 			mfs_arg_syslog(LOG_WARNING,"wrong session umask ('%c%c%c' - octal number expected)",ptr[1],ptr[2],ptr[3]);
936 			return -1;
937 		}
938 		umaskval = (ptr[1]-'0') * 64 + (ptr[2]-'0') * 8 + (ptr[3]-'0');
939 		ptr+=4;
940 		EAT(ptr,filename,lv,',');
941 	} else {
942 		umaskval=0;
943 	}
944 	GETU32(rootuid,ptr);
945 	EAT(ptr,filename,lv,',');
946 	GETU32(rootgid,ptr);
947 	EAT(ptr,filename,lv,',');
948 	GETU32(mapalluid,ptr);
949 	EAT(ptr,filename,lv,',');
950 	GETU32(mapallgid,ptr);
951 	EAT(ptr,filename,lv,',');
952 	GETU32(mingoal,ptr);
953 	EAT(ptr,filename,lv,',');
954 	GETU32(maxgoal,ptr);
955 	EAT(ptr,filename,lv,',');
956 	GETU32(mintrashtime,ptr);
957 	EAT(ptr,filename,lv,',');
958 	GETU32(maxtrashtime,ptr);
959 	EAT(ptr,filename,lv,',');
960 	if (ptr[0]=='0' && ptr[1]=='x') {
961 		ptr+=2;
962 		GETX32(disables,ptr);
963 		EAT(ptr,filename,lv,',');
964 	} else {
965 		disables = 0;
966 	}
967 	GETU32(peerip,ptr);
968 	EAT(ptr,filename,lv,',');
969 	GETDATA(info,ileng,infosize,ptr,filename,lv,')');
970 	EAT(ptr,filename,lv,')');
971 	(void)ptr; // silence cppcheck warnings
972 	return sessions_mr_seschanged(sessionid,exportscsum,rootinode,sesflags,umaskval,rootuid,rootgid,mapalluid,mapallgid,mingoal,maxgoal,mintrashtime,maxtrashtime,disables,peerip,info,ileng);
973 }
974 
do_sesdel(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)975 int do_sesdel(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
976 	uint32_t sessionid;
977 
978 	(void)ts;
979 	EAT(ptr,filename,lv,'(');
980 	GETU32(sessionid,ptr);
981 	EAT(ptr,filename,lv,')');
982 	(void)ptr; // silence cppcheck warnings
983 	return sessions_mr_sesdel(sessionid);
984 }
985 
do_sesdisconnected(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)986 int do_sesdisconnected(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
987 	uint32_t sessionid;
988 
989 	EAT(ptr,filename,lv,'(');
990 	GETU32(sessionid,ptr);
991 	EAT(ptr,filename,lv,')');
992 	(void)ptr; // silence cppcheck warnings
993 	return sessions_mr_disconnected(sessionid,ts);
994 }
995 
do_rollback(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)996 int do_rollback(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
997 	uint32_t inode,indx;
998 	uint64_t prevchunkid,chunkid;
999 	(void)ts;
1000 	EAT(ptr,filename,lv,'(');
1001 	GETU32(inode,ptr);
1002 	EAT(ptr,filename,lv,',');
1003 	GETU32(indx,ptr);
1004 	EAT(ptr,filename,lv,',');
1005 	GETU64(prevchunkid,ptr);
1006 	EAT(ptr,filename,lv,',');
1007 	GETU64(chunkid,ptr);
1008 	EAT(ptr,filename,lv,')');
1009 	(void)ptr; // silence cppcheck warnings
1010 	return fs_mr_rollback(inode,indx,prevchunkid,chunkid);
1011 }
1012 
do_seteattr(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1013 int do_seteattr(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1014 	uint32_t inode,uid,ci,nci,npi;
1015 	uint8_t eattr,smode;
1016 	EAT(ptr,filename,lv,'(');
1017 	GETU32(inode,ptr);
1018 	EAT(ptr,filename,lv,',');
1019 	GETU32(uid,ptr);
1020 	EAT(ptr,filename,lv,',');
1021 	GETU32(eattr,ptr);
1022 	EAT(ptr,filename,lv,',');
1023 	GETU32(smode,ptr);
1024 	EAT(ptr,filename,lv,')');
1025 	EAT(ptr,filename,lv,':');
1026 	GETU32(ci,ptr);
1027 	EAT(ptr,filename,lv,',');
1028 	GETU32(nci,ptr);
1029 	EAT(ptr,filename,lv,',');
1030 	GETU32(npi,ptr);
1031 	(void)ptr; // silence cppcheck warnings
1032 	return fs_mr_seteattr(ts,inode,uid,eattr,smode,ci,nci,npi);
1033 }
1034 
do_setfilechunk(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1035 int do_setfilechunk(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1036 	uint32_t inode,indx;
1037 	uint64_t chunkid;
1038 	(void)ts;
1039 	EAT(ptr,filename,lv,'(');
1040 	GETU32(inode,ptr);
1041 	EAT(ptr,filename,lv,',');
1042 	GETU32(indx,ptr);
1043 	EAT(ptr,filename,lv,',');
1044 	GETU64(chunkid,ptr);
1045 	EAT(ptr,filename,lv,')');
1046 	(void)ptr; // silence cppcheck warnings
1047 	return fs_mr_set_file_chunk(inode,indx,chunkid);
1048 }
1049 
1050 // deprecated
do_setgoal(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1051 int do_setgoal(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1052 	uint32_t inode,uid,ci,nci,npi;
1053 	uint8_t sclassid,smode;
1054 	EAT(ptr,filename,lv,'(');
1055 	GETU32(inode,ptr);
1056 	EAT(ptr,filename,lv,',');
1057 	GETU32(uid,ptr);
1058 	EAT(ptr,filename,lv,',');
1059 	GETU32(sclassid,ptr);
1060 	EAT(ptr,filename,lv,',');
1061 	GETU32(smode,ptr);
1062 	EAT(ptr,filename,lv,')');
1063 	EAT(ptr,filename,lv,':');
1064 	GETU32(ci,ptr);
1065 	EAT(ptr,filename,lv,',');
1066 	GETU32(nci,ptr);
1067 	EAT(ptr,filename,lv,',');
1068 	GETU32(npi,ptr);
1069 	(void)ptr; // silence cppcheck warnings
1070 	return fs_mr_setsclass(ts,inode,uid,sclassid,sclassid,smode,ci,nci,npi);
1071 }
1072 
do_setsclass(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1073 int do_setsclass(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1074 	uint32_t inode,uid,ci,nci,npi;
1075 	uint8_t src_sclassid,dst_sclassid,smode;
1076 	EAT(ptr,filename,lv,'(');
1077 	GETU32(inode,ptr);
1078 	EAT(ptr,filename,lv,',');
1079 	GETU32(uid,ptr);
1080 	EAT(ptr,filename,lv,',');
1081 	GETU32(src_sclassid,ptr);
1082 	EAT(ptr,filename,lv,',');
1083 	GETU32(dst_sclassid,ptr);
1084 	EAT(ptr,filename,lv,',');
1085 	GETU32(smode,ptr);
1086 	EAT(ptr,filename,lv,')');
1087 	EAT(ptr,filename,lv,':');
1088 	GETU32(ci,ptr);
1089 	EAT(ptr,filename,lv,',');
1090 	GETU32(nci,ptr);
1091 	EAT(ptr,filename,lv,',');
1092 	GETU32(npi,ptr);
1093 	(void)ptr; // silence cppcheck warnings
1094 	return fs_mr_setsclass(ts,inode,uid,src_sclassid,dst_sclassid,smode,ci,nci,npi);
1095 }
1096 
do_setmetaid(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1097 int do_setmetaid(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1098 	uint64_t metaid;
1099 	(void)ts;
1100 	EAT(ptr,filename,lv,'(');
1101 	GETU64(metaid,ptr);
1102 	EAT(ptr,filename,lv,')');
1103 	(void)ptr; // silence cppcheck warnings
1104 	return meta_mr_setmetaid(metaid);
1105 }
1106 
do_setpath(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1107 int do_setpath(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1108 	uint32_t inode;
1109 	static uint8_t *path = NULL;
1110 	static uint32_t pathsize = 0;
1111 	(void)ts;
1112 	EAT(ptr,filename,lv,'(');
1113 	GETU32(inode,ptr);
1114 	EAT(ptr,filename,lv,',');
1115 	GETPATH(path,pathsize,ptr,filename,lv,')');
1116 	EAT(ptr,filename,lv,')');
1117 	(void)ptr; // silence cppcheck warnings
1118 	return fs_mr_setpath(inode,path);
1119 }
1120 
do_settrashtime(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1121 int do_settrashtime(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1122 	uint32_t inode,uid,ci,nci,npi;
1123 	uint32_t trashtime;
1124 	uint8_t smode;
1125 	EAT(ptr,filename,lv,'(');
1126 	GETU32(inode,ptr);
1127 	EAT(ptr,filename,lv,',');
1128 	GETU32(uid,ptr);
1129 	EAT(ptr,filename,lv,',');
1130 	GETU32(trashtime,ptr);
1131 	EAT(ptr,filename,lv,',');
1132 	GETU32(smode,ptr);
1133 	EAT(ptr,filename,lv,')');
1134 	EAT(ptr,filename,lv,':');
1135 	GETU32(ci,ptr);
1136 	EAT(ptr,filename,lv,',');
1137 	GETU32(nci,ptr);
1138 	EAT(ptr,filename,lv,',');
1139 	GETU32(npi,ptr);
1140 	(void)ptr; // silence cppcheck warnings
1141 	return fs_mr_settrashtime(ts,inode,uid,trashtime,smode,ci,nci,npi);
1142 }
1143 
do_setxattr(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1144 int do_setxattr(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1145 	uint32_t inode,valueleng,mode;
1146 	uint8_t name[256];
1147 	static uint8_t *value = NULL;
1148 	static uint32_t valuesize = 0;
1149 	EAT(ptr,filename,lv,'(');
1150 	GETU32(inode,ptr);
1151 	EAT(ptr,filename,lv,',');
1152 	GETNAME(name,ptr,filename,lv,',');
1153 	EAT(ptr,filename,lv,',');
1154 	GETDATA(value,valueleng,valuesize,ptr,filename,lv,',');
1155 	EAT(ptr,filename,lv,',');
1156 	GETU32(mode,ptr);
1157 	EAT(ptr,filename,lv,')');
1158 	(void)ptr; // silence cppcheck warnings
1159 	return fs_mr_setxattr(ts,inode,strlen((char*)name),name,valueleng,value,mode);
1160 }
1161 
do_setacl(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1162 int do_setacl(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1163 	uint32_t inode,aclblobleng;
1164 	uint8_t acltype,changectime;
1165 	uint16_t mode,userperm,groupperm,otherperm,mask,namedusers,namedgroups;
1166 	static uint8_t *aclblob = NULL;
1167 	static uint32_t aclblobsize = 0;
1168 	EAT(ptr,filename,lv,'(');
1169 	GETU32(inode,ptr);
1170 	EAT(ptr,filename,lv,',');
1171 	GETU16(mode,ptr);
1172 	EAT(ptr,filename,lv,',');
1173 	GETU8(changectime,ptr);
1174 	EAT(ptr,filename,lv,',');
1175 	GETU8(acltype,ptr);
1176 	EAT(ptr,filename,lv,',');
1177 	GETU16(userperm,ptr);
1178 	EAT(ptr,filename,lv,',');
1179 	GETU16(groupperm,ptr);
1180 	EAT(ptr,filename,lv,',');
1181 	GETU16(otherperm,ptr);
1182 	EAT(ptr,filename,lv,',');
1183 	GETU16(mask,ptr);
1184 	EAT(ptr,filename,lv,',');
1185 	GETU16(namedusers,ptr);
1186 	EAT(ptr,filename,lv,',');
1187 	GETU16(namedgroups,ptr);
1188 	EAT(ptr,filename,lv,',');
1189 	GETDATA(aclblob,aclblobleng,aclblobsize,ptr,filename,lv,')');
1190 	EAT(ptr,filename,lv,')');
1191 	(void)ptr; // silence cppcheck warnings
1192 	if (aclblobleng!=6U*(namedusers+namedgroups)) {
1193 		return MFS_ERROR_MISMATCH;
1194 	}
1195 	return fs_mr_setacl(ts,inode,mode,changectime,acltype,userperm,groupperm,otherperm,mask,namedusers,namedgroups,aclblob);
1196 }
1197 
do_snapshot(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1198 int do_snapshot(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1199 	uint32_t inode,parent,smode,sesflags,uid,gids,umask;
1200 	uint32_t inodecheck,removed,same,existing,hardlinks,new;
1201 	static uint8_t *gidstr = NULL;
1202 	static uint32_t gidstrsize = 0;
1203 	static uint32_t *gid = NULL;
1204 	static uint32_t gidsize = 0;
1205 	uint32_t gidleng;
1206 	uint32_t *gidtab;
1207 	uint8_t name[256];
1208 	uint8_t mode;
1209 	uint32_t i;
1210 	EAT(ptr,filename,lv,'(');
1211 	GETU32(inode,ptr);
1212 	EAT(ptr,filename,lv,',');
1213 	GETU32(parent,ptr);
1214 	EAT(ptr,filename,lv,',');
1215 	GETNAME(name,ptr,filename,lv,',');
1216 	EAT(ptr,filename,lv,',');
1217 	GETU32(smode,ptr);
1218 	EAT(ptr,filename,lv,',');
1219 	GETU32(sesflags,ptr);
1220 	EAT(ptr,filename,lv,',');
1221 	GETU32(uid,ptr);
1222 	EAT(ptr,filename,lv,',');
1223 	if (*ptr=='[') {
1224 		mode=2;
1225 	} else {
1226 		GETU32(gids,ptr);
1227 		EAT(ptr,filename,lv,',');
1228 		mode = 0;
1229 		for (i=0 ; ptr[i] && ptr[i]!=')' ; i++) {
1230 			if (ptr[i]<'0' || ptr[i]>'9') {
1231 				mode=1;
1232 				break;
1233 			}
1234 		}
1235 	}
1236 	if (mode>=1) {
1237 		if (mode==2) {
1238 			GETARRAYU32(gid,gids,gidsize,ptr,filename,lv);
1239 			gidtab = gid;
1240 		} else {
1241 			GETDATA(gidstr,gidleng,gidstrsize,ptr,filename,lv,',');
1242 			if (gids*4!=gidleng) {
1243 				return MFS_ERROR_MISMATCH;
1244 			}
1245 			gidtab = (uint32_t*)gidstr;
1246 		}
1247 		EAT(ptr,filename,lv,',');
1248 		GETU32(umask,ptr);
1249 		EAT(ptr,filename,lv,')');
1250 		if (*ptr==':') {
1251 			EAT(ptr,filename,lv,':');
1252 			GETU32(inodecheck,ptr);
1253 			EAT(ptr,filename,lv,',');
1254 			GETU32(removed,ptr);
1255 			EAT(ptr,filename,lv,',');
1256 			GETU32(same,ptr);
1257 			EAT(ptr,filename,lv,',');
1258 			GETU32(existing,ptr);
1259 			EAT(ptr,filename,lv,',');
1260 			GETU32(hardlinks,ptr);
1261 			EAT(ptr,filename,lv,',');
1262 			GETU32(new,ptr);
1263 		} else {
1264 			inodecheck=0;
1265 			removed=0;
1266 			same=0;
1267 			existing=0;
1268 			hardlinks=0;
1269 			new=0;
1270 		}
1271 		(void)ptr; // silence cppcheck warnings
1272 		return fs_mr_snapshot(ts,inode,parent,strlen((char*)name),name,smode,sesflags,uid,gids,gidtab,umask,inodecheck,removed,same,existing,hardlinks,new);
1273 	} else {
1274 		GETU32(umask,ptr);
1275 		EAT(ptr,filename,lv,')');
1276 		(void)ptr; // silence cppcheck warnings
1277 		return fs_mr_snapshot(ts,inode,parent,strlen((char*)name),name,smode,sesflags,uid,1,&gids,umask,0,0,0,0,0,0);
1278 	}
1279 }
1280 
do_symlink(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1281 int do_symlink(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1282 	uint32_t parent,uid,gid,inode;
1283 	uint8_t name[256];
1284 	static uint8_t *path = NULL;
1285 	static uint32_t pathsize = 0;
1286 	EAT(ptr,filename,lv,'(');
1287 	GETU32(parent,ptr);
1288 	EAT(ptr,filename,lv,',');
1289 	GETNAME(name,ptr,filename,lv,',');
1290 	EAT(ptr,filename,lv,',');
1291 	GETPATH(path,pathsize,ptr,filename,lv,',');
1292 	EAT(ptr,filename,lv,',');
1293 	GETU32(uid,ptr);
1294 	EAT(ptr,filename,lv,',');
1295 	GETU32(gid,ptr);
1296 	EAT(ptr,filename,lv,')');
1297 	EAT(ptr,filename,lv,':');
1298 	GETU32(inode,ptr);
1299 	(void)ptr; // silence cppcheck warnings
1300 	return fs_mr_symlink(ts,parent,strlen((char*)name),name,path,uid,gid,inode);
1301 }
1302 
do_scdel(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1303 int do_scdel(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1304 	uint8_t name[256];
1305 	uint16_t spid;
1306 	(void)ts;
1307 	EAT(ptr,filename,lv,'(');
1308 	GETNAME(name,ptr,filename,lv,')');
1309 	EAT(ptr,filename,lv,')');
1310 	EAT(ptr,filename,lv,':');
1311 	GETU16(spid,ptr);
1312 	(void)ptr; // silence cppcheck warnings
1313 	return sclass_mr_delete_entry(strlen((char*)name),name,spid);
1314 }
1315 
do_scdup(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1316 int do_scdup(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1317 	uint8_t sname[256];
1318 	uint8_t dname[256];
1319 	uint16_t sspid,dspid;
1320 	(void)ts;
1321 	EAT(ptr,filename,lv,'(');
1322 	GETNAME(sname,ptr,filename,lv,',');
1323 	EAT(ptr,filename,lv,',');
1324 	GETNAME(dname,ptr,filename,lv,')');
1325 	EAT(ptr,filename,lv,')');
1326 	EAT(ptr,filename,lv,':');
1327 	GETU16(sspid,ptr);
1328 	EAT(ptr,filename,lv,',');
1329 	GETU16(dspid,ptr);
1330 	(void)ptr; // silence cppcheck warnings
1331 	return sclass_mr_duplicate_entry(strlen((char*)sname),sname,strlen((char*)dname),dname,sspid,dspid);
1332 }
1333 
do_scren(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1334 int do_scren(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1335 	uint8_t sname[256];
1336 	uint8_t dname[256];
1337 	uint16_t spid;
1338 	(void)ts;
1339 	EAT(ptr,filename,lv,'(');
1340 	GETNAME(sname,ptr,filename,lv,',');
1341 	EAT(ptr,filename,lv,',');
1342 	GETNAME(dname,ptr,filename,lv,')');
1343 	EAT(ptr,filename,lv,')');
1344 	EAT(ptr,filename,lv,':');
1345 	GETU16(spid,ptr);
1346 	(void)ptr; // silence cppcheck warnings
1347 	return sclass_mr_rename_entry(strlen((char*)sname),sname,strlen((char*)dname),dname,spid);
1348 }
1349 
do_scset(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1350 int do_scset(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1351 	uint8_t name[256];
1352 	uint16_t spid;
1353 	uint16_t arch_delay;
1354 	uint8_t new_flag,adminonly;
1355 	uint8_t create_labelscnt,keep_labelscnt,arch_labelscnt,create_mode,i;
1356 	uint32_t create_labelmasks[MAXLABELSCNT*MASKORGROUP];
1357 	uint32_t keep_labelmasks[MAXLABELSCNT*MASKORGROUP];
1358 	uint32_t arch_labelmasks[MAXLABELSCNT*MASKORGROUP];
1359 	(void)ts;
1360 	EAT(ptr,filename,lv,'(');
1361 	GETNAME(name,ptr,filename,lv,',');
1362 	EAT(ptr,filename,lv,',');
1363 	GETU8(new_flag,ptr);
1364 	EAT(ptr,filename,lv,',');
1365 	EAT(ptr,filename,lv,'W');
1366 	GETU8(create_labelscnt,ptr);
1367 	EAT(ptr,filename,lv,',');
1368 	EAT(ptr,filename,lv,'K');
1369 	GETU8(keep_labelscnt,ptr);
1370 	EAT(ptr,filename,lv,',');
1371 	EAT(ptr,filename,lv,'A');
1372 	GETU8(arch_labelscnt,ptr);
1373 	EAT(ptr,filename,lv,',');
1374 	GETU8(create_mode,ptr);
1375 	EAT(ptr,filename,lv,',');
1376 	GETU16(arch_delay,ptr);
1377 	EAT(ptr,filename,lv,',');
1378 	GETU8(adminonly,ptr);
1379 	if (create_labelscnt>MAXLABELSCNT || keep_labelscnt>MAXLABELSCNT || arch_labelscnt>MAXLABELSCNT) {
1380 		return MFS_ERROR_EINVAL;
1381 	}
1382 	if (create_labelscnt+keep_labelscnt+arch_labelscnt==0) {
1383 		EAT(ptr,filename,lv,',');
1384 		EAT(ptr,filename,lv,'-');
1385 	} else {
1386 		for (i=0 ; i<create_labelscnt*MASKORGROUP ; i++) {
1387 			EAT(ptr,filename,lv,',');
1388 			GETU32(create_labelmasks[i],ptr);
1389 		}
1390 		for (i=0 ; i<keep_labelscnt*MASKORGROUP ; i++) {
1391 			EAT(ptr,filename,lv,',');
1392 			GETU32(keep_labelmasks[i],ptr);
1393 		}
1394 		for (i=0 ; i<arch_labelscnt*MASKORGROUP ; i++) {
1395 			EAT(ptr,filename,lv,',');
1396 			GETU32(arch_labelmasks[i],ptr);
1397 		}
1398 	}
1399 	EAT(ptr,filename,lv,')');
1400 	EAT(ptr,filename,lv,':');
1401 	GETU16(spid,ptr);
1402 	(void)ptr; // silence cppcheck warnings
1403 	return sclass_mr_set_entry(strlen((char*)name),name,spid,new_flag,adminonly,create_mode,create_labelscnt,create_labelmasks,keep_labelscnt,keep_labelmasks,arch_labelscnt,arch_labelmasks,arch_delay);
1404 }
1405 
do_undel(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1406 int do_undel(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1407 	uint32_t inode;
1408 	EAT(ptr,filename,lv,'(');
1409 	GETU32(inode,ptr);
1410 	EAT(ptr,filename,lv,')');
1411 	(void)ptr; // silence cppcheck warnings
1412 	return fs_mr_undel(ts,inode);
1413 }
1414 
do_unlink(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1415 int do_unlink(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1416 	uint32_t inode,parent;
1417 	uint8_t name[256];
1418 	EAT(ptr,filename,lv,'(');
1419 	GETU32(parent,ptr);
1420 	EAT(ptr,filename,lv,',');
1421 	GETNAME(name,ptr,filename,lv,')');
1422 	EAT(ptr,filename,lv,')');
1423 	EAT(ptr,filename,lv,':');
1424 	GETU32(inode,ptr);
1425 	(void)ptr; // silence cppcheck warnings
1426 	return fs_mr_unlink(ts,parent,strlen((char*)name),name,inode);
1427 }
1428 
do_unlock(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1429 int do_unlock(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1430 	uint64_t chunkid;
1431 	(void)ts;
1432 	EAT(ptr,filename,lv,'(');
1433 	GETU64(chunkid,ptr);
1434 	EAT(ptr,filename,lv,')');
1435 	(void)ptr; // silence cppcheck warnings
1436 	return fs_mr_unlock(chunkid);
1437 }
1438 
do_trunc(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1439 int do_trunc(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1440 	uint32_t inode,indx;
1441 	uint64_t chunkid;
1442 	EAT(ptr,filename,lv,'(');
1443 	GETU32(inode,ptr);
1444 	EAT(ptr,filename,lv,',');
1445 	GETU32(indx,ptr);
1446 	EAT(ptr,filename,lv,')');
1447 	EAT(ptr,filename,lv,':');
1448 	GETU64(chunkid,ptr);
1449 	(void)ptr; // silence cppcheck warnings
1450 	return fs_mr_trunc(ts,inode,indx,chunkid);
1451 }
1452 
do_write(const char * filename,uint64_t lv,uint32_t ts,const char * ptr)1453 int do_write(const char *filename,uint64_t lv,uint32_t ts,const char *ptr) {
1454 	uint32_t inode,indx,opflag;
1455 	uint64_t chunkid;
1456 	uint8_t canmodmtime;
1457 	EAT(ptr,filename,lv,'(');
1458 	GETU32(inode,ptr);
1459 	EAT(ptr,filename,lv,',');
1460 	GETU32(indx,ptr);
1461 	if (*ptr==',') {
1462 		EAT(ptr,filename,lv,',');
1463 		GETU32(opflag,ptr);
1464 	} else {
1465 		opflag=1;
1466 	}
1467 	if (*ptr==',') {
1468 		EAT(ptr,filename,lv,',');
1469 		GETU8(canmodmtime,ptr);
1470 	} else {
1471 		canmodmtime=1;
1472 	}
1473 	EAT(ptr,filename,lv,')');
1474 	EAT(ptr,filename,lv,':');
1475 	GETU64(chunkid,ptr);
1476 	(void)ptr; // silence cppcheck warnings
1477 	return fs_mr_write(ts,inode,indx,opflag,canmodmtime,chunkid);
1478 }
1479 
1480 #define HASHCODESTR(str) (((((uint8_t*)(str))[0]*256U+((uint8_t*)(str))[1])*256U+((uint8_t*)(str))[2])*256U+((uint8_t*)(str))[3])
1481 #define HASHCODE(a,b,c,d) (((((uint8_t)a)*256U+(uint8_t)b)*256U+(uint8_t)c)*256U+(uint8_t)d)
1482 
restore_line(const char * filename,uint64_t lv,const char * line,uint32_t * rts)1483 int restore_line(const char *filename,uint64_t lv,const char *line,uint32_t *rts) {
1484 	const char *ptr;
1485 	uint32_t ts;
1486 	uint32_t hc;
1487 	int status;
1488 //	char* errormsgs[]={ MFS_ERROR_STRINGS };
1489 
1490 	status = MFS_ERROR_MISMATCH;
1491 	ptr = line;
1492 
1493 //	EAT(ptr,filename,lv,':');
1494 //	EAT(ptr,filename,lv,' ');
1495 	GETU32(ts,ptr);
1496 	if (rts!=NULL) {
1497 		*rts = ts;
1498 	}
1499 	EAT(ptr,filename,lv,'|');
1500 	hc = HASHCODESTR(ptr);
1501 	switch (hc) {
1502 		case HASHCODE('I','D','L','E'):
1503 			return do_idle(filename,lv,ts,ptr+4);
1504 		case HASHCODE('A','C','C','E'):
1505 			if (strncmp(ptr,"ACCESS",6)==0) {
1506 				return do_access(filename,lv,ts,ptr+6);
1507 			}
1508 			break;
1509 		case HASHCODE('A','T','T','R'):
1510 			return do_attr(filename,lv,ts,ptr+4);
1511 		case HASHCODE('A','P','P','E'):
1512 			if (strncmp(ptr,"APPEND",6)==0) {
1513 				return do_append(filename,lv,ts,ptr+6);
1514 			}
1515 			break;
1516 		case HASHCODE('A','C','Q','U'):
1517 			if (strncmp(ptr,"ACQUIRE",7)==0) {
1518 				return do_acquire(filename,lv,ts,ptr+7);
1519 			}
1520 			break;
1521 		case HASHCODE('A','Q','U','I'):
1522 			if (strncmp(ptr,"AQUIRE",6)==0) {
1523 				return do_acquire(filename,lv,ts,ptr+6);
1524 			}
1525 			break;
1526 		case HASHCODE('A','R','C','H'):
1527 			if (strncmp(ptr,"ARCHCHG",7)==0) {
1528 				return do_archchg(filename,lv,ts,ptr+7);
1529 			}
1530 			break;
1531 		case HASHCODE('A','M','T','I'):
1532 			if (strncmp(ptr,"AMTIME",6)==0) {
1533 				return do_amtime(filename,lv,ts,ptr+6);
1534 			}
1535 			break;
1536 		case HASHCODE('C','R','E','A'):
1537 			if (strncmp(ptr,"CREATE",6)==0) {
1538 				return do_create(filename,lv,ts,ptr+6);
1539 			}
1540 			break;
1541 		case HASHCODE('C','H','U','N'):
1542 			if (strncmp(ptr,"CHUNKADD",8)==0) {
1543 				return do_chunkadd(filename,lv,ts,ptr+8);
1544 			} else if (strncmp(ptr,"CHUNKDEL",8)==0) {
1545 				return do_chunkdel(filename,lv,ts,ptr+8);
1546 			}
1547 			break;
1548 		case HASHCODE('C','S','A','D'):
1549 			if (strncmp(ptr,"CSADD",5)==0) {		// deprecated
1550 				return do_csadd(filename,lv,ts,ptr+5);
1551 			}
1552 			break;
1553 		case HASHCODE('C','S','D','B'):
1554 			if (strncmp(ptr,"CSDBOP",6)==0) {
1555 				return do_csdbop(filename,lv,ts,ptr+6);
1556 			}
1557 			break;
1558 		case HASHCODE('C','S','D','E'):
1559 			if (strncmp(ptr,"CSDEL",5)==0) {		// deprecated
1560 				return do_csdel(filename,lv,ts,ptr+5);
1561 			}
1562 			break;
1563 		case HASHCODE('C','U','S','T'):
1564 			if (strncmp(ptr,"CUSTOMER",8)==0) {	// deprecated
1565 				return do_session(filename,lv,ts,ptr+8);
1566 			}
1567 			break;
1568 		case HASHCODE('E','M','P','T'):
1569 			if (strncmp(ptr,"EMPTYTRASH",10)==0) {
1570 				return do_emptytrash(filename,lv,ts,ptr+10);
1571 			} else if (strncmp(ptr,"EMPTYSUSTAINED",14)==0) {
1572 				return do_emptysustained(filename,lv,ts,ptr+14);
1573 			} else if (strncmp(ptr,"EMPTYRESERVED",13)==0) {
1574 				return do_emptysustained(filename,lv,ts,ptr+13);
1575 			}
1576 			break;
1577 		case HASHCODE('F','L','O','C'):
1578 			if (strncmp(ptr,"FLOCK",5)==0) {
1579 				return do_flock(filename,lv,ts,ptr+5);
1580 			}
1581 			break;
1582 		case HASHCODE('F','R','E','E'):
1583 			if (strncmp(ptr,"FREEINODES",10)==0) {
1584 				return do_freeinodes(filename,lv,ts,ptr+10);
1585 			}
1586 			break;
1587 		case HASHCODE('I','N','C','V'):
1588 			if (strncmp(ptr,"INCVERSION",10)==0) {
1589 				return do_incversion(filename,lv,ts,ptr+10); // deprecated -> SETVERSION
1590 			}
1591 			break;
1592 		case HASHCODE('L','E','N','G'):
1593 			if (strncmp(ptr,"LENGTH",6)==0) {
1594 				return do_length(filename,lv,ts,ptr+6);
1595 			}
1596 			break;
1597 		case HASHCODE('L','I','N','K'):
1598 			return do_link(filename,lv,ts,ptr+4);
1599 		case HASHCODE('M','O','V','E'):
1600 			return do_move(filename,lv,ts,ptr+4);
1601 		case HASHCODE('N','E','X','T'):
1602 			if (strncmp(ptr,"NEXTCHUNKID",11)==0) {
1603 				return do_nextchunkid(filename,lv,ts,ptr+11); // deprecated
1604 			}
1605 			break;
1606 		case HASHCODE('P','O','S','I'):
1607 			if (strncmp(ptr,"POSIXLOCK",9)==0) {
1608 				return do_posixlock(filename,lv,ts,ptr+9);
1609 			}
1610 			break;
1611 		case HASHCODE('P','U','R','G'):
1612 			if (strncmp(ptr,"PURGE",5)==0) {
1613 				return do_purge(filename,lv,ts,ptr+5);
1614 			}
1615 			break;
1616 		case HASHCODE('Q','U','O','T'):
1617 			if (strncmp(ptr,"QUOTA",5)==0) {
1618 				return do_quota(filename,lv,ts,ptr+5);
1619 			}
1620 			break;
1621 		case HASHCODE('R','E','L','E'):
1622 			if (strncmp(ptr,"RELEASE",7)==0) {
1623 				return do_release(filename,lv,ts,ptr+7);
1624 			}
1625 			break;
1626 		case HASHCODE('R','E','N','U'):
1627 			if (strncmp(ptr,"RENUMERATEEDGES",15)==0) {
1628 				return do_renumedges(filename,lv,ts,ptr+15);
1629 			}
1630 			break;
1631 		case HASHCODE('R','E','P','A'):
1632 			if (strncmp(ptr,"REPAIR",6)==0) {
1633 				return do_repair(filename,lv,ts,ptr+6);
1634 			}
1635 			break;
1636 		case HASHCODE('R','O','L','L'):
1637 			if (strncmp(ptr,"ROLLBACK",8)==0) {
1638 				return do_rollback(filename,lv,ts,ptr+8);
1639 			}
1640 			break;
1641 		case HASHCODE('S','C','D','E'):
1642 			if (strncmp(ptr,"SCDEL",5)==0) {
1643 				return do_scdel(filename,lv,ts,ptr+5);
1644 			}
1645 			break;
1646 		case HASHCODE('S','C','D','U'):
1647 			if (strncmp(ptr,"SCDUP",5)==0) {
1648 				return do_scdup(filename,lv,ts,ptr+5);
1649 			}
1650 			break;
1651 		case HASHCODE('S','C','R','E'):
1652 			if (strncmp(ptr,"SCREN",5)==0) {
1653 				return do_scren(filename,lv,ts,ptr+5);
1654 			}
1655 			break;
1656 		case HASHCODE('S','C','S','E'):
1657 			if (strncmp(ptr,"SCSET",5)==0) {
1658 				return do_scset(filename,lv,ts,ptr+5);
1659 			}
1660 			break;
1661 		case HASHCODE('S','E','S','A'):
1662 			if (strncmp(ptr,"SESADD",6)==0) {
1663 				return do_sesadd(filename,lv,ts,ptr+6);
1664 			}
1665 			break;
1666 		case HASHCODE('S','E','S','C'):
1667 			if (strncmp(ptr,"SESCHANGED",10)==0) {
1668 				return do_seschanged(filename,lv,ts,ptr+10);
1669 			}
1670 			break;
1671 		case HASHCODE('S','E','S','D'):
1672 			if (strncmp(ptr,"SESDEL",6)==0) {
1673 				return do_sesdel(filename,lv,ts,ptr+6);
1674 			} else if (strncmp(ptr,"SESDISCONNECTED",15)==0) {
1675 				return do_sesdisconnected(filename,lv,ts,ptr+15);
1676 			}
1677 			break;
1678 		case HASHCODE('S','E','S','S'):
1679 			if (strncmp(ptr,"SESSION",7)==0) { // deprecated
1680 				return do_session(filename,lv,ts,ptr+7);
1681 			}
1682 			break;
1683 		case HASHCODE('S','E','T','A'):
1684 			if (strncmp(ptr,"SETACL",6)==0) {
1685 				return do_setacl(filename,lv,ts,ptr+6);
1686 			}
1687 			break;
1688 		case HASHCODE('S','E','T','E'):
1689 			if (strncmp(ptr,"SETEATTR",8)==0) {
1690 				return do_seteattr(filename,lv,ts,ptr+8);
1691 			}
1692 			break;
1693 		case HASHCODE('S','E','T','F'):
1694 			if (strncmp(ptr,"SETFILECHUNK",12)==0) {
1695 				return do_setfilechunk(filename,lv,ts,ptr+12);
1696 			}
1697 			break;
1698 		case HASHCODE('S','E','T','G'):
1699 			if (strncmp(ptr,"SETGOAL",7)==0) {
1700 				return do_setgoal(filename,lv,ts,ptr+7);
1701 			}
1702 			break;
1703 		case HASHCODE('S','E','T','M'):
1704 			if (strncmp(ptr,"SETMETAID",9)==0) {
1705 				return do_setmetaid(filename,lv,ts,ptr+9);
1706 			}
1707 			break;
1708 		case HASHCODE('S','E','T','P'):
1709 			if (strncmp(ptr,"SETPATH",7)==0) {
1710 				return do_setpath(filename,lv,ts,ptr+7);
1711 			}
1712 			break;
1713 		case HASHCODE('S','E','T','S'):
1714 			if (strncmp(ptr,"SETSCLASS",9)==0) {
1715 				return do_setsclass(filename,lv,ts,ptr+9);
1716 			}
1717 			break;
1718 		case HASHCODE('S','E','T','T'):
1719 			if (strncmp(ptr,"SETTRASHTIME",12)==0) {
1720 				return do_settrashtime(filename,lv,ts,ptr+12);
1721 			}
1722 			break;
1723 		case HASHCODE('S','E','T','V'):
1724 			if (strncmp(ptr,"SETVERSION",10)==0) {
1725 				return do_setversion(filename,lv,ts,ptr+10);
1726 			}
1727 			break;
1728 		case HASHCODE('S','E','T','X'):
1729 			if (strncmp(ptr,"SETXATTR",8)==0) {
1730 				return do_setxattr(filename,lv,ts,ptr+8);
1731 			}
1732 			break;
1733 		case HASHCODE('S','N','A','P'):
1734 			if (strncmp(ptr,"SNAPSHOT",8)==0) {
1735 				return do_snapshot(filename,lv,ts,ptr+8);
1736 			}
1737 			break;
1738 		case HASHCODE('S','Y','M','L'):
1739 			if (strncmp(ptr,"SYMLINK",7)==0) {
1740 				return do_symlink(filename,lv,ts,ptr+7);
1741 			}
1742 			break;
1743 		case HASHCODE('T','R','U','N'):
1744 			if (strncmp(ptr,"TRUNC",5)==0) {
1745 				return do_trunc(filename,lv,ts,ptr+5);
1746 			}
1747 			break;
1748 		case HASHCODE('U','N','D','E'):
1749 			if (strncmp(ptr,"UNDEL",5)==0) {
1750 				return do_undel(filename,lv,ts,ptr+5);
1751 			}
1752 			break;
1753 		case HASHCODE('U','N','L','I'):
1754 			if (strncmp(ptr,"UNLINK",6)==0) {
1755 				return do_unlink(filename,lv,ts,ptr+6);
1756 			}
1757 			break;
1758 		case HASHCODE('U','N','L','O'):
1759 			if (strncmp(ptr,"UNLOCK",6)==0) {
1760 				return do_unlock(filename,lv,ts,ptr+6);
1761 			}
1762 			break;
1763 		case HASHCODE('W','R','I','T'):
1764 			if (strncmp(ptr,"WRITE",5)==0) {
1765 				return do_write(filename,lv,ts,ptr+5);
1766 			}
1767 			break;
1768 	}
1769 	mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
1770 #if 0
1771 	switch (*ptr) {
1772 		case 'A':
1773 			if (strncmp(ptr,"ACCESS",6)==0) {
1774 				status = do_access(filename,lv,ts,ptr+6);
1775 			} else if (strncmp(ptr,"ATTR",4)==0) {
1776 				status = do_attr(filename,lv,ts,ptr+4);
1777 			} else if (strncmp(ptr,"APPEND",6)==0) {
1778 				status = do_append(filename,lv,ts,ptr+6);
1779 			} else if (strncmp(ptr,"ACQUIRE",7)==0) {
1780 				status = do_acquire(filename,lv,ts,ptr+7);
1781 			} else if (strncmp(ptr,"AQUIRE",6)==0) {
1782 				status = do_acquire(filename,lv,ts,ptr+6);
1783 			} else {
1784 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
1785 			}
1786 			break;
1787 		case 'C':
1788 			if (strncmp(ptr,"CREATE",6)==0) {
1789 				status = do_create(filename,lv,ts,ptr+6);
1790 			} else if (strncmp(ptr,"CHUNKADD",8)==0) {
1791 				status = do_chunkadd(filename,lv,ts,ptr+8);
1792 			} else if (strncmp(ptr,"CHUNKDEL",8)==0) {
1793 				status = do_chunkdel(filename,lv,ts,ptr+8);
1794 			} else if (strncmp(ptr,"CSDBOP",6)==0) {
1795 				status = do_csdbop(filename,lv,ts,ptr+6);
1796 			} else if (strncmp(ptr,"CSADD",5)==0) {		// deprecated
1797 				status = do_csadd(filename,lv,ts,ptr+5);
1798 			} else if (strncmp(ptr,"CSDEL",5)==0) {		// deprecated
1799 				status = do_csdel(filename,lv,ts,ptr+5);
1800 			} else if (strncmp(ptr,"CUSTOMER",8)==0) {	// deprecated
1801 				status = do_session(filename,lv,ts,ptr+8);
1802 			} else {
1803 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
1804 			}
1805 			break;
1806 		case 'E':
1807 			if (strncmp(ptr,"EMPTYTRASH",10)==0) {
1808 				status = do_emptytrash(filename,lv,ts,ptr+10);
1809 			} else if (strncmp(ptr,"EMPTYSUSTAINED",14)==0) {
1810 				status = do_emptysustained(filename,lv,ts,ptr+14);
1811 			} else if (strncmp(ptr,"EMPTYRESERVED",13)==0) {
1812 				status = do_emptysustained(filename,lv,ts,ptr+13);
1813 			} else {
1814 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
1815 			}
1816 			break;
1817 		case 'F':
1818 			if (strncmp(ptr,"FREEINODES",10)==0) {
1819 				status = do_freeinodes(filename,lv,ts,ptr+10);
1820 			} else {
1821 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
1822 			}
1823 			break;
1824 		case 'I':
1825 			if (strncmp(ptr,"INCVERSION",10)==0) {
1826 				status = do_incversion(filename,lv,ts,ptr+10);
1827 			} else {
1828 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
1829 			}
1830 			break;
1831 		case 'L':
1832 			if (strncmp(ptr,"LENGTH",6)==0) {
1833 				status = do_length(filename,lv,ts,ptr+6);
1834 			} else if (strncmp(ptr,"LINK",4)==0) {
1835 				status = do_link(filename,lv,ts,ptr+4);
1836 			} else {
1837 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
1838 			}
1839 			break;
1840 		case 'N':
1841 			if (strncmp(ptr,"NEXTCHUNKID",11)==0) {
1842 				status = do_nextchunkid(filename,lv,ts,ptr+11); // deprecated
1843 			} else {
1844 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
1845 			}
1846 		case 'M':
1847 			if (strncmp(ptr,"MOVE",4)==0) {
1848 				status = do_move(filename,lv,ts,ptr+4);
1849 			} else {
1850 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
1851 			}
1852 			break;
1853 		case 'P':
1854 			if (strncmp(ptr,"PURGE",5)==0) {
1855 				status = do_purge(filename,lv,ts,ptr+5);
1856 			} else {
1857 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
1858 			}
1859 			break;
1860 		case 'Q':
1861 			if (strncmp(ptr,"QUOTA",5)==0) {
1862 				status = do_quota(filename,lv,ts,ptr+5);
1863 			} else {
1864 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
1865 			}
1866 			break;
1867 		case 'R':
1868 			if (strncmp(ptr,"RELEASE",7)==0) {
1869 				status = do_release(filename,lv,ts,ptr+7);
1870 			} else if (strncmp(ptr,"REPAIR",6)==0) {
1871 				status = do_repair(filename,lv,ts,ptr+6);
1872 			} else if (strncmp(ptr,"RENUMEDGES",10)==0) {
1873 				status = do_renumedges(filename,lv,ts,ptr+10);
1874 			} else {
1875 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
1876 			}
1877 			break;
1878 		case 'S':
1879 			if (strncmp(ptr,"SETEATTR",8)==0) {
1880 				status = do_seteattr(filename,lv,ts,ptr+8);
1881 			} else if (strncmp(ptr,"SETGOAL",7)==0) {
1882 				status = do_setgoal(filename,lv,ts,ptr+7);
1883 			} else if (strncmp(ptr,"SETPATH",7)==0) {
1884 				status = do_setpath(filename,lv,ts,ptr+7);
1885 			} else if (strncmp(ptr,"SETTRASHTIME",12)==0) {
1886 				status = do_settrashtime(filename,lv,ts,ptr+12);
1887 			} else if (strncmp(ptr,"SETXATTR",8)==0) {
1888 				status = do_setxattr(filename,lv,ts,ptr+8);
1889 			} else if (strncmp(ptr,"SETACL",6)==0) {
1890 				status = do_setacl(filename,lv,ts,ptr+6);
1891 			} else if (strncmp(ptr,"SNAPSHOT",8)==0) {
1892 				status = do_snapshot(filename,lv,ts,ptr+8);
1893 			} else if (strncmp(ptr,"SYMLINK",7)==0) {
1894 				status = do_symlink(filename,lv,ts,ptr+7);
1895 			} else if (strncmp(ptr,"SESSION",7)==0) { // deprecated
1896 				status = do_session(filename,lv,ts,ptr+7);
1897 			} else if (strncmp(ptr,"SESADD",6)==0) {
1898 				status = do_sesadd(filename,lv,ts,ptr+6);
1899 			} else if (strncmp(ptr,"SESDEL",6)==0) {
1900 				status = do_sesdel(filename,lv,ts,ptr+6);
1901 			} else if (strncmp(ptr,"SESDISCONNECTED",15)==0) {
1902 				status = do_sesdisconnected(filename,lv,ts,ptr+15);
1903 			} else {
1904 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
1905 			}
1906 			break;
1907 		case 'T':
1908 			if (strncmp(ptr,"TRUNC",5)==0) {
1909 				status = do_trunc(filename,lv,ts,ptr+5);
1910 			} else {
1911 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
1912 			}
1913 			break;
1914 		case 'U':
1915 			if (strncmp(ptr,"UNLINK",6)==0) {
1916 				status = do_unlink(filename,lv,ts,ptr+6);
1917 			} else if (strncmp(ptr,"UNDEL",5)==0) {
1918 				status = do_undel(filename,lv,ts,ptr+5);
1919 			} else if (strncmp(ptr,"UNLOCK",6)==0) {
1920 				status = do_unlock(filename,lv,ts,ptr+6);
1921 			} else {
1922 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
1923 			}
1924 			break;
1925 		case 'W':
1926 			if (strncmp(ptr,"WRITE",5)==0) {
1927 				status = do_write(filename,lv,ts,ptr+5);
1928 			} else {
1929 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
1930 			}
1931 			break;
1932 		default:
1933 			mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
1934 	}
1935 #endif
1936 //	if (status>MFS_STATUS_OK) {
1937 //		mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": error: %d (%s)\n",filename,lv,status,errormsgs[status]);
1938 //	}
1939 	return status;
1940 }
1941 
restore_net(uint64_t lv,const char * ptr,uint32_t * rts)1942 int restore_net(uint64_t lv,const char *ptr,uint32_t *rts) {
1943 	int status;
1944 	if (lv!=meta_version()) {
1945 		syslog(LOG_WARNING,"desync - invalid meta version (version in packet: %"PRIu64" / expected: %"PRIu64" / packet data: %s)",lv,meta_version(),ptr);
1946 		return -1;
1947 	}
1948 	status = restore_line("NET",lv,ptr,rts);
1949 	if (status<0) {
1950 		syslog(LOG_WARNING,"desync - operation (%s) parse error",ptr);
1951 		return -1;
1952 	}
1953 	if (status!=MFS_STATUS_OK) {
1954 		syslog(LOG_WARNING,"desync - operation (%s) error: %d (%s)",ptr,status,mfsstrerr(status));
1955 		return -1;
1956 	}
1957 	if (lv+1!=meta_version()) {
1958 		syslog(LOG_WARNING,"desync - meta version has not been increased after the operation (%s)",ptr);
1959 		return -1;
1960 	}
1961 	return 0;
1962 }
1963 
1964 static uint64_t v=0,lastv=0;
1965 static void *lastshfn = NULL;
1966 
restore_file(void * shfilename,uint64_t lv,const char * ptr,uint8_t vlevel)1967 int restore_file(void *shfilename,uint64_t lv,const char *ptr,uint8_t vlevel) {
1968 	int status;
1969 	char *lastfn;
1970 	char *filename = (char*)shp_get(shfilename);
1971 	if (lastv==0 || v==0 || lastshfn==NULL) {
1972 		v = meta_version();
1973 		lastv = lv-1;
1974 		lastfn = "(no file)";
1975 	} else {
1976 		lastfn = (char*)shp_get(lastshfn);
1977 	}
1978 	if (vlevel>1) {
1979 		mfs_arg_syslog(LOG_NOTICE,"filename: %s ; current meta version: %"PRIu64" ; previous changeid: %"PRIu64" ; current changeid: %"PRIu64" ; change data%s",filename,v,lastv,lv,ptr);
1980 	}
1981 	if (lv<lastv) {
1982 		mfs_arg_syslog(LOG_WARNING,"merge error - possibly corrupted input file - ignore entry (filename: %s)\n",filename);
1983 		return 0;
1984 	} else if (lv>=v) {
1985 		if (lv==lastv) {
1986 			if (vlevel>1) {
1987 				mfs_arg_syslog(LOG_WARNING,"duplicated entry: %"PRIu64" (previous file: %s, current file: %s)\n",lv,lastfn,filename);
1988 			}
1989 		} else if (lv>lastv+1) {
1990 			mfs_arg_syslog(LOG_WARNING,"hole in change files (entries from %s:%"PRIu64" to %s:%"PRIu64" are missing) - add more files\n",lastfn,lastv+1,filename,lv-1);
1991 			return -2;
1992 		} else {
1993 			if (vlevel>0) {
1994 				mfs_arg_syslog(LOG_WARNING,"%s: change%s",filename,ptr);
1995 			}
1996 			status = restore_line(filename,lv,ptr,NULL);
1997 			if (status<0) { // parse error - just ignore this line
1998 				return 0;
1999 			}
2000 			if (status>0) { // other errors - stop processing data
2001 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": operation (%s) error: %d (%s)",filename,lv,ptr,status,mfsstrerr(status));
2002 				return -1;
2003 			}
2004 			v = meta_version();
2005 			if (lv+1!=v) {
2006 				mfs_arg_syslog(LOG_WARNING,"%s:%"PRIu64": version mismatch\n",filename,lv);
2007 				return -1;
2008 			}
2009 		}
2010 	}
2011 	lastv = lv;
2012 	if (shfilename!=lastshfn) {
2013 		shp_inc(shfilename);
2014 		if (lastshfn!=NULL) {
2015 			shp_dec(lastshfn);
2016 		}
2017 		lastshfn = shfilename;
2018 	}
2019 	return 0;
2020 }
2021