tizen 2.0 merge
[framework/base/libsqlfs.git] / sqlfs.c
1 /******************************************************************************
2 Copyright 2006 Palmsource, Inc (an ACCESS company). 
3  
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8  
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 Lesser General Public License for more details.
13  
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  
18 *****************************************************************************/
19 /*!
20  * @file sqlfs.c
21  *
22  * @brief file system on top of a SQL database library
23  *  API implementation
24  *
25  *****************************************************************************/
26
27 /* the file system is stored in a SQLite table, with the following columns
28  
29  
30 full key path      type     inode      uid      gid        mode   acl      attributes         atime  mtime ctime size  block_size
31 (text)            (text)    (integer) (integer) (integer)   (integer)   (text)    (text)        (integer) ...
32  
33 the key path must start with "/" and is case sensitive
34  
35 the type can be one of these:  "int", "double",  "string", "dir", "sym link" and "blob"
36  
37  
38 for Blobs we will divide them into 8k pieces, each occupying an BLOB object in database indexed by a block number 
39 which starts from 0
40  
41 created by
42  
43  CREATE TABLE meta_data(key text, type text, inode integer, uid integer, gid integer, mode integer,  acl text, attribute text,
44     atime integer, mtime integer, ctime integer, size integer, block_size integer, primary key (key), unique(key)) ;
45     
46  CREATE TABLE value_data (key text, block_no integer, data_block blob, unique(key, block_no));   
47  
48  create index meta_index on meta_data (key);
49  create index value_index on value_data (key, block_no);
50  
51  
52 */
53
54 /* currently permission control due to the current directory not implemented */
55
56 #include <stdio.h>
57 #include <stdbool.h>
58 #include <stdlib.h>
59 #include <stdint.h>
60 #include <assert.h>
61 #include <stdarg.h>
62 #include <string.h>
63 #include <unistd.h>
64 #include <limits.h>
65 #include <sys/types.h>
66 #include <sys/stat.h>
67 #include <sys/time.h>
68 #include <pthread.h>
69 #include <time.h>
70 #include <attr/xattr.h>
71 #include <sys/capability.h>
72 #include "sqlfs.h"
73 #include "sqlite3.h"
74
75 // baik - for sqlfs profiling
76 int g_total_sec=0;
77 int g_total_usec=0;
78
79 #define PROFILE_START\
80         static int g_sec=0;\
81         static int g_usec=0;\
82      struct timeval time1;\
83      struct timeval time2;\
84      struct timeval restime;\
85         gettimeofday(&time1, NULL);
86
87 #define PROFILE_END\
88         gettimeofday(&time2, NULL);\
89         timersub(&time2, &time1, &restime);\
90         g_sec = g_sec+restime.tv_sec;\
91         g_usec = g_usec+restime.tv_usec;\
92         g_total_sec = g_total_sec+ restime.tv_sec;\
93         g_total_usec = g_total_usec + restime.tv_usec;\
94         printf("%s = %d %d %d(%d) \n",__FUNCTION__,g_sec,g_usec,g_total_usec,g_usec*100/g_total_usec);
95
96 #define PROFILE_POINT(ARG)\
97         {\
98         struct timeval profile_point_enter_time;\
99         gettimeofday(&kkk_enter_time,NULL);\
100         printf("%s- %d %d\n",ARG,profile_point_enter_time.tv_sec,kkk_enter_time.tv_usec);\
101         }
102
103 #define INDEX 0
104
105 #define PREPARE_STMT\
106     stmt = get_sqlfs(sqlfs)->stmts[INDEX];\
107     r = SQLITE_OK; \
108     if (stmt)\
109     {\
110         if (sqlite3_expired(stmt))\
111         {\
112             sqlite3_finalize(stmt);\
113             r = ~SQLITE_OK;\
114         }\
115     }\
116     else r = ~SQLITE_OK;\
117     if (r != SQLITE_OK)
118
119 #define DONE_PREPARE  if (r == SQLITE_OK) get_sqlfs(sqlfs)->stmts[INDEX] = stmt; else get_sqlfs(sqlfs)->stmts[INDEX] = 0;
120
121 #define SQLITE3_PREPARE(a, b, c, d, e)\
122     PREPARE_STMT \
123     r = sqlite3_prepare((a), (b), (c), (d), (e));\
124     DONE_PREPARE
125
126
127 // baik
128 #define SQLFS_FAST_TUNNING
129 #define FAST_ATTRIBUTE_SEARCH
130
131 // sangjung woo
132 #define ENABLE_DAC
133
134 #ifdef FAST_ATTRIBUTE_SEARCH 
135 char *g_prev_attribute_path=NULL;
136 key_attr g_prev_attr = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ;
137 #endif
138
139 #ifdef SQLFS_FAST_TUNNING
140 // baik - minimize get / set block size 
141 static const int BLOCK_SIZE = 1 * 1024;
142 #else
143 static const int BLOCK_SIZE = 128 * 1024;
144 #endif
145
146 static pthread_key_t sql_key;
147
148 static char default_db_file[PATH_MAX] = { 0 };
149
150
151 static int max_inode = 0;
152
153 static void * sqlfs_t_init(const char *);
154 static void sqlfs_t_finalize(void *arg);
155
156 static void delay(int ms)
157 {
158     struct timeval timeout;
159     timeout.tv_sec = ms / 1000 ;
160     timeout.tv_usec = 1000 * ( ms % 1000 );
161
162     select(0, 0, 0, 0, &timeout);
163 }
164
165 static __inline__ int sql_step(sqlite3_stmt *stmt)
166 {
167     int r, i;
168     for (i = 0; i < (1 * 1000 / 100); i++)
169     {
170         r = sqlite3_step(stmt);
171         if (r != SQLITE_BUSY)
172             break;
173         delay(100);
174     }
175
176     return r;
177
178 }
179
180 static __inline__ sqlfs_t *get_sqlfs(sqlfs_t *p)
181 {
182     sqlfs_t *sqlfs;
183
184     if (p)
185         return p;
186
187     sqlfs = (sqlfs_t *) (pthread_getspecific(sql_key));
188     if (sqlfs)
189         return sqlfs;
190
191     sqlfs =  (sqlfs_t*) sqlfs_t_init(default_db_file);
192     pthread_setspecific(sql_key, sqlfs);
193     return sqlfs;
194 }
195 static __inline__ int get_new_inode(void)
196 {
197     return ++max_inode;
198 }
199
200 static __inline__ void remove_tail_slash(char *str)
201 {
202     char *s = str + strlen(str) - 1;
203     while (s != str - 1)
204     {
205         if (*s != '/')
206             break;
207         *s = 0;
208         s--;
209     }
210 }
211
212 static __inline__ char *make_str_copy(const char *str, size_t n)
213 {
214     if (str == 0)
215         return 0;
216     return strndup(str,n);
217 }
218
219 static void show_msg(FILE *f, char *fmt, ...)
220 {
221     va_list ap;
222
223     va_start(ap, fmt);
224
225     vfprintf(f, fmt, ap);
226     va_end(ap);
227 }
228
229
230
231 void clean_attr(key_attr *attr)
232 {
233     if (attr->path)
234         free(attr->path);
235     if (attr->type)
236         free(attr->type);
237     memset(attr, 0, sizeof(*attr));
238 }
239
240
241 void clean_value(key_value *value)
242 {
243     if (value->data)
244         free(value->data);
245     memset(value, 0, sizeof(*value));
246 }
247
248 /*static pthread_mutex_t transaction_lock = PTHREAD_MUTEX_INITIALIZER;
249 */
250 #define TRANS_LOCK //pthread_mutex_lock(&transaction_lock);
251 #define TRANS_UNLOCK //pthread_mutex_unlock(&transaction_lock);
252
253
254 #undef INDEX
255 #define INDEX 100
256
257 static int begin_transaction(sqlfs_t *sqlfs)
258 {
259     int i;
260 #ifdef FUSE
261     const char *cmd = "begin exclusive;";
262
263 #else
264     const char *cmd = "begin;";
265 #endif
266
267     sqlite3_stmt *stmt;
268     const char *tail;
269     int r = SQLITE_OK;
270     TRANS_LOCK
271
272
273     if (get_sqlfs(sqlfs)->transaction_level == 0)
274     {
275         /*assert(sqlite3_get_autocommit(get_sqlfs(sqlfs)->db) != 0);*/
276
277         SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1,  &stmt,  &tail);
278         for (i = 0; i < 10; i++)
279         {
280             r = sqlite3_step(stmt);
281             if (r != SQLITE_BUSY)
282                 break;
283             delay(100);
284         }
285         sqlite3_reset(stmt);
286         if (r == SQLITE_DONE)
287             r = SQLITE_OK;
288         if (r == SQLITE_BUSY)
289         {
290             TRANS_UNLOCK;
291             show_msg(stderr, "database is busy!\n");
292             return r;  /* busy, return back */
293         }
294         get_sqlfs(sqlfs)->in_transaction = 1;
295     }
296     get_sqlfs(sqlfs)->transaction_level++;
297     TRANS_UNLOCK
298     return r;
299 }
300
301 #undef INDEX
302 #define INDEX 101
303
304
305 static int commit_transaction(sqlfs_t *sqlfs, int r0)
306 {
307     int i;
308     /* commit if r0 is 1
309        rollback if r0 is 0
310     */
311     static const char *cmd1 = "commit;", *cmd2 = "rollback;";
312
313     int r = SQLITE_OK;
314     sqlite3_stmt *stmt, *stmt1, *stmt2;
315     const char *tail;
316
317 // baik - ??제 transaction ??에???Prepare ??주는 것이 좋다.
318 #ifndef SQLFS_FAST_TUNNING
319     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd1, -1,  &stmt,  &tail);
320
321     stmt1 = stmt;
322
323 #undef INDEX
324 #define INDEX 102
325
326     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd2, -1,  &stmt,  &tail);
327     stmt2 = stmt;
328
329     if (r0 != 0)
330         stmt = stmt1;
331     else
332         stmt = stmt2;
333 #endif
334
335     TRANS_LOCK
336
337
338     /*assert(get_sqlfs(sqlfs)->transaction_level > 0);*/
339
340     /*assert(get_sqlfs(sqlfs)->transaction_level >= 0);*/
341     if ((get_sqlfs(sqlfs)->transaction_level - 1 == 0) && (get_sqlfs(sqlfs)->in_transaction))
342     {
343 #ifdef SQLFS_FAST_TUNNING
344             SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd1, -1,  &stmt,  &tail);
345
346             stmt1 = stmt;
347
348 #undef INDEX
349 #define INDEX 102
350
351             SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd2, -1,  &stmt,  &tail);
352             stmt2 = stmt;
353
354             if (r0 != 0)
355                 stmt = stmt1;
356             else
357                 stmt = stmt2;
358 #endif
359         for (i = 0; i < 10; i++)
360         {
361             r = sqlite3_step(stmt);
362             if (r != SQLITE_BUSY)
363                 break;
364             delay(100);
365         }
366         sqlite3_reset(stmt);
367         if (r == SQLITE_DONE)
368             r = SQLITE_OK;
369         if (r == SQLITE_BUSY)
370         {
371             TRANS_UNLOCK;
372             show_msg(stderr, "database is busy!\n");
373             return r;  /* busy, return back */
374         }
375         //**assert(sqlite3_get_autocommit(get_sqlfs(sqlfs)->db) != 0);*/
376         get_sqlfs(sqlfs)->in_transaction = 0;
377     }
378     get_sqlfs(sqlfs)->transaction_level--;
379
380     /*if (get_sqlfs(sqlfs)->transaction_level == 0)
381         assert(get_sqlfs(sqlfs)->in_transaction == 0);*/
382     TRANS_UNLOCK
383     return r;
384 }
385
386 #undef INDEX
387 #define INDEX 103
388
389 static int break_transaction(sqlfs_t *sqlfs, int r0)
390 {
391     int i;
392     /* commit if r0 is 1
393        rollback if r0 is 0
394     */
395     static const char *cmd1 = "commit;", *cmd2 = "rollback;";
396
397     int r = SQLITE_OK;
398     sqlite3_stmt *stmt, *stmt1, *stmt2;
399     const char *tail;
400
401     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd1, -1,  &stmt,  &tail);
402
403     stmt1 = stmt;
404
405 #undef INDEX
406 #define INDEX 104
407
408     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd2, -1,  &stmt,  &tail);
409     stmt2 = stmt;
410
411
412     if (r0 != 0)
413         stmt = stmt1;
414     else
415         stmt = stmt2;
416
417     TRANS_LOCK
418
419     if (get_sqlfs(sqlfs)->in_transaction)
420     {
421         for (i = 0; i < 10; i++)
422         {
423             r = sqlite3_step(stmt);
424             if (r != SQLITE_BUSY)
425                 break;
426             delay(100);
427         }
428         sqlite3_reset(stmt);
429         if (r == SQLITE_DONE)
430             r = SQLITE_OK;
431         if (r == SQLITE_BUSY)
432         {
433             TRANS_UNLOCK;
434             show_msg(stderr, "database is busy!\n");
435             return r;  /* busy, return back */
436         }
437         //**assert(sqlite3_get_autocommit(get_sqlfs(sqlfs)->db) != 0);*/
438         get_sqlfs(sqlfs)->in_transaction = 0;
439     }
440     TRANS_UNLOCK
441     return r;
442 }
443
444
445
446 /*#ifndef FUSE
447 #define BEGIN
448 #define COMPLETE(r)
449 #else
450 */
451
452 #if 0 // baik - set 1 for profile
453
454 #ifdef SQLFS_FAST_TUNNING
455         #define BEGIN   PROFILE_START
456         #define COMPLETE(r)     PROFILE_END
457 #else
458         #define BEGIN\
459                 PROFILE_START\
460                 begin_transaction(get_sqlfs(sqlfs));
461         #define COMPLETE(r)\
462                 commit_transaction(get_sqlfs(sqlfs), (r));\
463                 PROFILE_END
464 #endif
465
466 #else
467
468 #ifdef SQLFS_FAST_TUNNING
469         // baik - Transaction ??걸기 ??해??는 반드??setxattr ?????용??서 걸어????다.
470         #define BEGIN
471         #define COMPLETE(r)
472 #else
473         #define BEGIN begin_transaction(get_sqlfs(sqlfs));
474         #define COMPLETE(r) commit_transaction(get_sqlfs(sqlfs), (r));
475 #endif
476
477 #endif
478
479 /*#endif*/
480
481
482 #undef INDEX
483 #define INDEX 1
484
485
486 static __inline__ int get_current_max_inode(sqlfs_t *sqlfs)
487 {
488     sqlite3_stmt *stmt;
489     const char *tail;
490     static const char *cmd = "select max(inode) from meta_data;";
491     int r, result = 0;
492
493     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1,  &stmt,  &tail);
494
495
496     if (r != SQLITE_OK)
497     {
498         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
499         return 0;
500     }
501
502
503     r = sql_step(stmt);
504     if (r != SQLITE_ROW)
505     {
506         if (r != SQLITE_DONE)
507             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
508
509     }
510     else
511         result = sqlite3_column_int(stmt, 0);
512     sqlite3_reset(stmt);
513     return result;
514
515 }
516
517
518 #undef INDEX
519 #define INDEX 2
520
521
522 static int key_exists(sqlfs_t *sqlfs, const char *key, size_t *size)
523 {
524     sqlite3_stmt *stmt;
525     const char *tail;
526     static const char *cmd = "select size from meta_data where key = :key;";
527     int r, result = 0;
528     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1,  &stmt,  &tail);
529     if (r != SQLITE_OK)
530     {
531         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
532         return 0;
533     }
534
535
536     sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC);
537     r = sql_step(stmt);
538     if (r != SQLITE_ROW)
539     {
540         if (r != SQLITE_DONE)
541             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
542         if (r == SQLITE_BUSY)
543             result = 2;
544     }
545
546     else
547     {
548         if (size)
549             *size = sqlite3_column_int64(stmt, 0);
550         result = 1;
551     }
552     sqlite3_reset(stmt);
553     return result;
554
555
556 }
557
558 #undef INDEX
559 #define INDEX 3
560
561
562 static int key_is_dir(sqlfs_t *sqlfs, const char *key)
563 {
564     sqlite3_stmt *stmt;
565     const char *tail, *t;
566     static const char *cmd = "select type from meta_data where key = :key;";
567     int r, result = 0;
568     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1,  &stmt,  &tail);
569     if (r != SQLITE_OK)
570     {
571         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
572         return r;
573     }
574
575     sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC);
576     r = sql_step(stmt);
577     if (r != SQLITE_ROW)
578     {
579         if (r != SQLITE_DONE)
580             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
581         if (r == SQLITE_BUSY)
582             result = 2;
583     }
584
585     else
586     {
587         t = sqlite3_column_text(stmt, 0);
588
589         if (t && !strcmp(TYPE_DIR, t))
590             result = 1;
591
592     }
593     sqlite3_reset(stmt);
594     return result;
595
596
597 }
598
599
600 #undef INDEX
601 #define INDEX 4
602
603 static int key_accessed(sqlfs_t *sqlfs, const char *key)
604 {
605 #ifndef SQLFS_FAST_TUNNING
606     sqlite3_stmt *stmt;
607     const char *tail;
608     static const char *cmd = "update meta_data set atime = :atime where key = :key;";
609     int r;
610     time_t now;
611
612     time(&now);
613     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1,  &stmt,  &tail);
614     if (r != SQLITE_OK)
615     {
616         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
617         return r;
618     }
619
620     r = sqlite3_bind_int64(stmt, 1, now);
621     r = sqlite3_bind_text(stmt, 2, key, -1, SQLITE_STATIC);
622     r = sqlite3_step(stmt);
623     if (r != SQLITE_DONE)
624     {
625         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
626
627     }
628     else if (r == SQLITE_BUSY)
629         ;
630     else
631         r = SQLITE_OK;
632     sqlite3_reset(stmt);
633     return r;
634 #else
635         //baik - key_accessed ??에??access ??보?????데??트 ???? ??는??
636         return SQLITE_OK;
637 #endif
638 }
639
640
641 #undef INDEX
642 #define INDEX 5
643
644 static int key_modified(sqlfs_t *sqlfs, const char *key)
645 {
646     sqlite3_stmt *stmt;
647     const char *tail;
648     time_t now ;
649     static const char *cmd = "update meta_data set atime = :atime, mtime = :mtime, ctime = :ctime where key = :key;";
650     int r;
651
652 #ifdef FAST_ATTRIBUTE_SEARCH
653         if(g_prev_attribute_path!=NULL)
654                 if(strcmp(g_prev_attribute_path,key)==0)
655                 {
656                         free(g_prev_attribute_path);
657                         g_prev_attribute_path = NULL;
658                 }
659 #endif
660
661     time(&now);
662     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1,  &stmt,  &tail);
663     if (r != SQLITE_OK)
664     {
665         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
666         return r;
667     }
668
669     sqlite3_bind_int64(stmt, 1, now);
670     sqlite3_bind_int64(stmt, 2, now);
671     sqlite3_bind_int64(stmt, 3, now);
672     sqlite3_bind_text(stmt, 4, key, -1, SQLITE_STATIC);
673     r = sql_step(stmt);
674     if (r != SQLITE_DONE)
675     {
676         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
677
678     }
679     else
680         r = SQLITE_OK;
681     sqlite3_reset(stmt);
682     return r;
683 }
684
685
686 #undef INDEX
687 #define INDEX 6
688
689
690
691 static int remove_key(sqlfs_t *sqlfs, const char *key)
692 {
693     int r;
694     const char *tail;
695     sqlite3_stmt *stmt;
696     static const char *cmd1 = "delete from meta_data where key = :key;";
697     static const char *cmd2 = "delete from value_data where key = :key;" ;
698     static const char *cmd3 = "delete from xattr_data where key = :key;" ;
699
700 #ifdef FAST_ATTRIBUTE_SEARCH
701         if(g_prev_attribute_path!=NULL)
702                 if(strcmp(g_prev_attribute_path,key)==0)
703                 {
704                         free(g_prev_attribute_path);
705                         g_prev_attribute_path = NULL;
706                 }
707 #endif
708
709     BEGIN
710     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd1, -1, &stmt, &tail);
711     if (r != SQLITE_OK)
712     {
713         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
714         COMPLETE(1)
715         return r;
716     }
717     sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC);
718     r = sql_step(stmt);
719     if (r != SQLITE_DONE)
720     {
721         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
722     }
723     else
724     {
725         r = SQLITE_OK;
726     }
727     sqlite3_reset(stmt);
728
729
730 #undef INDEX
731 #define INDEX 7
732
733     if (r == SQLITE_OK)
734     {
735         SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd2, -1, &stmt, &tail);
736         if (r != SQLITE_OK)
737         {
738             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
739             COMPLETE(1)
740             return r;
741         }
742         sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC);
743         r = sql_step(stmt);
744         if (r != SQLITE_DONE)
745         {
746             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
747         }
748         else
749         {
750             r = SQLITE_OK;
751         }
752         sqlite3_reset(stmt);
753     }
754 #undef INDEX
755 #define INDEX 35
756
757     if (r == SQLITE_OK)
758     {
759         SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd3, -1, &stmt, &tail);
760         if (r != SQLITE_OK)
761         {
762             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
763             COMPLETE(1)
764             return r;
765         }
766         sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC);
767         r = sql_step(stmt);
768         if (r != SQLITE_DONE)
769         {
770             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
771         }
772         else
773         {
774             r = SQLITE_OK;
775         }
776         sqlite3_reset(stmt);
777     }
778     COMPLETE(1)
779     return r;
780 }
781
782
783
784 #undef INDEX
785 #define INDEX 8
786
787
788
789 static int remove_key_subtree(sqlfs_t *sqlfs, const char *key)
790 {
791     int r;
792     const char *tail;
793     sqlite3_stmt *stmt;
794     char pattern[PATH_MAX];
795     static const char *cmd1 = "delete from meta_data where key glob :pattern;";
796     static const char *cmd2 = "delete from value_data where key glob :pattern;" ;
797     char *lpath;
798
799 #ifdef FAST_ATTRIBUTE_SEARCH
800      if(g_prev_attribute_path!=NULL)
801         {
802                 free(g_prev_attribute_path);
803              g_prev_attribute_path = NULL;
804      }
805 #endif
806
807     lpath = strndup(key,strlen(key));
808     assert(lpath != NULL);
809     remove_tail_slash(lpath);
810     sprintf(pattern, "%s/*", lpath);
811     free(lpath);
812     BEGIN
813     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd1, -1, &stmt, &tail);
814     if (r != SQLITE_OK)
815     {
816         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
817         COMPLETE(1)
818         return r;
819     }
820     sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_STATIC);
821     r = sql_step(stmt);
822     if (r != SQLITE_DONE)
823     {
824         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
825     }
826     else
827     {
828         r = SQLITE_OK;
829     }
830     sqlite3_reset(stmt);
831
832
833 #undef INDEX
834 #define INDEX 9
835
836     if (r == SQLITE_OK)
837     {
838         SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd2, -1, &stmt, &tail);
839         if (r != SQLITE_OK)
840         {
841             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
842             COMPLETE(1)
843             return r;
844         }
845         sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_STATIC);
846         r = sql_step(stmt);
847         if (r != SQLITE_DONE)
848         {
849             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
850         }
851
852         else
853         {
854             r = SQLITE_OK;
855         }
856         sqlite3_reset(stmt);
857     }
858     if (r == SQLITE_OK)
859     {
860         r = remove_key(sqlfs, key);
861     }
862     COMPLETE(1)
863     return r;
864 }
865
866
867 #undef INDEX
868 #define INDEX 10
869
870
871 static int remove_key_subtree_with_exclusion(sqlfs_t *sqlfs, const char *key, const char *exclusion_pattern)
872 {
873     int r;
874     const char *tail;
875     sqlite3_stmt *stmt;
876     char pattern[PATH_MAX];
877     char n_pattern[PATH_MAX];
878     static const char *cmd1 = "delete from meta_data where (key glob :pattern) and not (key glob :n_pattern) ;";
879     static const char *cmd2 = "delete from value_data where (key glob :pattern) and not (key glob :n_pattern) ;" ;
880     static const char *cmd3 = "select key from meta_data where (key glob :n_pattern) ;" ;
881     char *lpath;
882
883 #ifdef FAST_ATTRIBUTE_SEARCH
884      if(g_prev_attribute_path!=NULL)
885         {
886                 free(g_prev_attribute_path);
887              g_prev_attribute_path = NULL;
888      }
889 #endif
890
891     lpath = strndup(key,strlen(key));
892     assert(lpath != NULL);
893     remove_tail_slash(lpath);
894     snprintf(pattern, sizeof(pattern), "%s/*", lpath);
895
896     snprintf(n_pattern, sizeof(n_pattern), "%s/%s", lpath, exclusion_pattern);
897     free(lpath);
898     BEGIN
899     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd1, -1, &stmt, &tail);
900     if (r != SQLITE_OK)
901     {
902         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
903         COMPLETE(1)
904         return r;
905     }
906     sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_STATIC);
907     sqlite3_bind_text(stmt, 2, n_pattern, -1, SQLITE_STATIC);
908     r = sql_step(stmt);
909     if (r != SQLITE_DONE)
910     {
911         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
912     }
913     else
914     {
915         r = SQLITE_OK;
916     }
917     sqlite3_reset(stmt);
918
919 #undef INDEX
920 #define INDEX 11
921
922     if (r == SQLITE_OK)
923     {
924         SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd2, -1, &stmt, &tail);
925         if (r != SQLITE_OK)
926         {
927             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
928             COMPLETE(1)
929             return r;
930         }
931         sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_STATIC);
932         r = sql_step(stmt);
933         if (r != SQLITE_DONE)
934         {
935             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
936         }
937         else
938         {
939             r = SQLITE_OK;
940         }
941         sqlite3_reset(stmt);
942     }
943
944
945 #undef INDEX
946 #define INDEX 12
947
948     if (r == SQLITE_OK)
949     {
950         SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd3, -1, &stmt, &tail);
951         if (r != SQLITE_OK)
952         {
953             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
954             COMPLETE(1)
955             return r;
956         }
957         sqlite3_bind_text(stmt, 1, n_pattern, -1, SQLITE_STATIC);
958         r = sql_step(stmt);
959         if (r != SQLITE_ROW)
960         {
961             if (r == SQLITE_BUSY)
962                 ;
963             else
964                 if (r != SQLITE_DONE)
965                     show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
966
967                 else
968                     r = SQLITE_NOTFOUND;
969         }
970
971         sqlite3_reset(stmt);
972
973         if (r == SQLITE_NOTFOUND)
974             r = remove_key(sqlfs, key);
975         else if (r == SQLITE_BUSY)
976             ;
977         else
978             r = SQLITE_OK;
979     }
980     COMPLETE(1)
981     return r;
982 }
983
984
985
986 #undef INDEX
987 #define INDEX 13
988
989 static int rename_key(sqlfs_t *sqlfs, const char *old, const char *new)
990 {
991     int r;
992     const char *tail;
993     sqlite3_stmt *stmt;
994     static const char *cmd1 = "update meta_data set key = :new where key = :old; ";
995     static const char *cmd2 = "update value_data set key = :new where key = :old; ";
996     static const char *cmd3 = "update xattr_data set key = :new where key = :old; ";
997
998 #ifdef FAST_ATTRIBUTE_SEARCH
999         if(g_prev_attribute_path!=NULL)
1000                 if(strcmp(g_prev_attribute_path,old)==0)
1001                 {
1002                         free(g_prev_attribute_path);
1003                         g_prev_attribute_path = NULL;
1004                 }
1005 #endif
1006
1007     BEGIN
1008     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd1, -1, &stmt,  &tail);
1009     if (r != SQLITE_OK)
1010     {
1011         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1012         COMPLETE(1)
1013         return r;
1014     }
1015     sqlite3_bind_text(stmt, 1, new, -1, SQLITE_STATIC);
1016     sqlite3_bind_text(stmt, 2, old, -1, SQLITE_STATIC);
1017     r = sql_step(stmt);
1018     if (r != SQLITE_DONE)
1019     {
1020         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1021     }
1022     else
1023     {
1024         r = SQLITE_OK;
1025     }
1026     sqlite3_reset(stmt);
1027
1028
1029
1030 #undef INDEX
1031 #define INDEX 14
1032
1033
1034     if (r == SQLITE_OK)
1035     {
1036         SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd2, -1, &stmt,  &tail);
1037         if (r != SQLITE_OK)
1038         {
1039             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1040             COMPLETE(1)
1041             return r;
1042         }
1043         sqlite3_bind_text(stmt, 1, new, -1, SQLITE_STATIC);
1044         sqlite3_bind_text(stmt, 2, old, -1, SQLITE_STATIC);
1045         r = sql_step(stmt);
1046         if (r != SQLITE_DONE)
1047         {
1048             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1049         }
1050         else
1051         {
1052             r = SQLITE_OK;
1053         }
1054         sqlite3_reset(stmt);
1055     }
1056
1057 #undef INDEX
1058 #define INDEX 38
1059
1060
1061     if (r == SQLITE_OK)
1062     {
1063         SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd3, -1, &stmt,  &tail);
1064         if (r != SQLITE_OK)
1065         {
1066             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1067             COMPLETE(1)
1068             return r;
1069         }
1070         sqlite3_bind_text(stmt, 1, new, -1, SQLITE_STATIC);
1071         sqlite3_bind_text(stmt, 2, old, -1, SQLITE_STATIC);
1072         r = sql_step(stmt);
1073         if (r != SQLITE_DONE)
1074         {
1075             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1076         }
1077         else
1078         {
1079             r = SQLITE_OK;
1080         }
1081         sqlite3_reset(stmt);
1082     }
1083     COMPLETE(1)
1084     return r;
1085
1086 }
1087
1088
1089 #undef INDEX
1090 #define INDEX 15
1091
1092
1093 static int get_dir_children_num(sqlfs_t *sqlfs, const char *path)
1094 {
1095     int i, r, count = 0;
1096     const char *tail;
1097     const char *t, *t2;
1098     char *lpath = 0;
1099     static const char *cmd = "select key from meta_data where key glob :pattern; ";
1100     char tmp[PATH_MAX];
1101     struct stat st;
1102     sqlite3_stmt *stmt;
1103
1104     if ((i = key_is_dir(sqlfs, path)), (i == 0))
1105     {
1106
1107         return 0;
1108     }
1109     else if (i == 2)
1110         return -EBUSY;
1111
1112     lpath = strndup(path,strlen(path));
1113     assert(lpath != NULL);
1114     remove_tail_slash(lpath);
1115     snprintf(tmp, sizeof(tmp), "%s/*", lpath);
1116     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1, &stmt,  &tail);
1117     if (r != SQLITE_OK)
1118     {
1119         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1120     }
1121     else
1122     {
1123         sqlite3_bind_text(stmt, 1, tmp, -1, SQLITE_STATIC);
1124
1125         while (1)
1126         {
1127             r = sql_step(stmt);
1128             if (r == SQLITE_ROW)
1129             {
1130                 t = sqlite3_column_text(stmt, 0);
1131                 t2 = t + strlen(tmp) - 1;
1132                 if (strchr(t2, '/'))
1133                     continue; /* grand child, etc. */
1134                 count++;
1135
1136             }
1137             else if (r == SQLITE_DONE)
1138             {
1139                 break;
1140             }
1141             else
1142             {
1143                 show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1144
1145                 break;
1146             }
1147         }
1148     }
1149     free(lpath);
1150
1151     if (r == SQLITE_BUSY)
1152         count = -1;
1153     return count;
1154 }
1155
1156 static int set_attr(sqlfs_t *sqlfs, const char *key, const key_attr *attr);
1157
1158
1159 static int ensure_existence(sqlfs_t *sqlfs, const char *key, const char *type)
1160 {
1161     int r;
1162     key_attr attr = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1163     if (key_exists(sqlfs, key, 0) == 0)
1164     {
1165         attr.path = strndup(key,strlen(key));
1166         assert(attr.path != NULL);
1167         attr.type = strndup(type,strlen(type));
1168         assert(attr.type != NULL);
1169         attr.mode = get_sqlfs(sqlfs)->default_mode; /* to use default */
1170 #ifdef FUSE
1171 #ifdef ENABLE_DAC
1172                 attr.uid = fuse_get_context()->uid;
1173                 attr.gid = fuse_get_context()->gid;
1174                 /* printf("[%s:%d]attr.uid = %d, attr.gid=%d\n", __FILE__, __LINE__, attr.uid, attr.gid); */
1175 #else
1176         attr.uid = geteuid();
1177         attr.gid = getegid();
1178 #endif
1179 #else
1180         attr.uid = get_sqlfs(sqlfs)->uid;
1181         attr.gid = get_sqlfs(sqlfs)->gid;
1182
1183 #endif
1184         attr.inode = get_new_inode();
1185         r = set_attr(sqlfs, key, &attr);
1186         if (r != SQLITE_OK)
1187         {
1188             clean_attr(&attr);
1189             return 0;
1190
1191         }
1192         clean_attr(&attr);
1193         return 2;
1194     }
1195
1196     return 1;
1197
1198 }
1199 #if 0
1200 static int ensure_parent_existence(sqlfs_t *sqlfs, const char *key)
1201 {
1202     int r;
1203
1204
1205     char *parent = calloc(strlen(key) + 2, sizeof(char));
1206
1207     char *t;
1208     assert(parent);
1209
1210     strcpy(parent, key);
1211     remove_tail_slash(parent);
1212     t = strrchr(parent, '/');
1213     if (t)
1214     {
1215
1216         *t = 0;
1217     }
1218
1219     if (*parent == 0)
1220     {
1221         t = parent;
1222         *t = '/';
1223         *(t + 1) = 0;
1224     }
1225     ensure_existence(sqlfs, parent, TYPE_DIR);
1226     free(parent);
1227     return 1;
1228 }
1229 #endif
1230
1231 static int get_parent_path(const char *path, char buf[PATH_MAX])
1232 {
1233
1234     char *s;
1235     if ((path[0] == '/') && (path[1] == 0))
1236     {
1237         /* the root directory, which has no parent */
1238         return SQLITE_NOTFOUND;
1239     }
1240
1241     strcpy(buf, path);
1242     remove_tail_slash(buf);
1243     s = strrchr(buf, '/');
1244
1245     if (s == 0)
1246         return SQLITE_NOTFOUND; /* no parent? */
1247     if (s == buf)
1248         s[1] = 0;
1249     else
1250         s[0] = 0;
1251     return SQLITE_OK;
1252
1253 }
1254
1255
1256 #undef INDEX
1257 #define INDEX 16
1258
1259
1260 static int get_permission_data(sqlfs_t *sqlfs, const char *key, gid_t *gid, uid_t *uid, mode_t *mode)
1261 {
1262
1263     int i, r;
1264
1265     const char *tail;
1266     sqlite3_stmt *stmt;
1267     static const char *cmd = "select mode, uid, gid from meta_data where key = :key; ";
1268
1269
1270     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1, &stmt,  &tail);
1271     if (r != SQLITE_OK)
1272     {
1273         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1274         return r;
1275     }
1276     r = sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC);
1277     if (r != SQLITE_OK)
1278     {
1279         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1280
1281     }
1282     r = sql_step(stmt);
1283     if (r != SQLITE_ROW)
1284     {
1285         if (r != SQLITE_DONE)
1286             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1287         else if (r == SQLITE_BUSY)
1288             ;
1289         else
1290             r = SQLITE_NOTFOUND;
1291     }
1292     else
1293     {
1294         *mode = (mode_t) (sqlite3_column_int(stmt, 0));
1295         *uid = (uid_t) (sqlite3_column_int(stmt, 1));
1296         *gid = (gid_t) (sqlite3_column_int(stmt, 2));
1297         r = SQLITE_OK;
1298     }
1299
1300     sqlite3_reset(stmt);
1301     key_accessed(sqlfs, key);
1302     return r;
1303
1304 }
1305
1306 static int get_parent_permission_data(sqlfs_t *sqlfs, const char *key, gid_t *gid, uid_t *uid, mode_t *mode)
1307 {
1308     char tmp[PATH_MAX], *s;
1309     int r;
1310     r = get_parent_path(key, tmp);
1311     if (r == SQLITE_OK)
1312         r = get_permission_data(sqlfs, tmp, gid, uid, mode);
1313
1314     return r;
1315 }
1316
1317
1318 #undef INDEX
1319 #define INDEX 17
1320
1321
1322 static int get_attr(sqlfs_t *sqlfs, const char *key, key_attr *attr)
1323 {
1324     int i, r;
1325
1326     const char *tail;
1327     sqlite3_stmt *stmt;
1328     static const char *cmd = "select key, type, mode, uid, gid, atime, mtime, ctime, size, inode from meta_data where key = :key; ";
1329
1330     clean_attr(attr);
1331
1332         // baik - ??반??으???file operation ?? open -> read -> close ????속????서???발생??다.
1333         //      - ??라?? ??나??Attribute ???cache ??여????과????다.
1334 #ifdef FAST_ATTRIBUTE_SEARCH
1335         if(g_prev_attribute_path!=NULL)
1336                 if(strcmp(g_prev_attribute_path,key)== 0)
1337                 {
1338                         attr->path = make_str_copy(g_prev_attr.path,strlen(g_prev_attr.path));
1339                         assert(attr->path != NULL);
1340                         assert(!strcmp(key, attr->path));
1341                         attr->type = make_str_copy(g_prev_attr.type,strlen(g_prev_attr.type));
1342                         assert(attr->type != NULL);
1343                         attr->mode =g_prev_attr.mode; 
1344                         attr->uid = g_prev_attr.uid;
1345                         attr->gid = g_prev_attr.gid;
1346                         attr->atime = g_prev_attr.atime;
1347                         attr->mtime = g_prev_attr.mtime;
1348                         attr->ctime = g_prev_attr.ctime;
1349                         attr->size = g_prev_attr.size;
1350                         attr->inode = g_prev_attr.inode;
1351                         r = SQLITE_OK;
1352  
1353                         return r; 
1354                 }               
1355 #endif
1356
1357     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1, &stmt,  &tail);
1358     if (r != SQLITE_OK)
1359     {
1360         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1361         return r;
1362     }
1363     r = sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC);
1364     if (r != SQLITE_OK)
1365     {
1366         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1367
1368     }
1369     r = sql_step(stmt);
1370     if (r != SQLITE_ROW)
1371     {
1372         if (r != SQLITE_DONE)
1373             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1374         if (r == SQLITE_BUSY)
1375             ;
1376         else
1377             r = SQLITE_NOTFOUND;
1378     }
1379     else
1380     {
1381         attr->path = make_str_copy(sqlite3_column_text(stmt, 0),strlen(sqlite3_column_text(stmt, 0)));
1382         assert(attr->path != NULL);
1383         assert(!strcmp(key, attr->path));
1384         attr->type = make_str_copy(sqlite3_column_text(stmt, 1),strlen(sqlite3_column_text(stmt, 1)));
1385         assert(attr->type != NULL);
1386         attr->mode = (sqlite3_column_int(stmt, 2));
1387         attr->uid = (sqlite3_column_int(stmt, 3));
1388         attr->gid = (sqlite3_column_int(stmt, 4));
1389         attr->atime = (sqlite3_column_int(stmt, 5));
1390         attr->mtime = (sqlite3_column_int(stmt, 6));
1391         attr->ctime = (sqlite3_column_int(stmt, 7));
1392         attr->size = (sqlite3_column_int64(stmt, 8));
1393         attr->inode = (sqlite3_column_int(stmt, 9));
1394         r = SQLITE_OK;
1395
1396         // baik
1397 #ifdef FAST_ATTRIBUTE_SEARCH
1398            clean_attr(&g_prev_attr);
1399         g_prev_attr.path = make_str_copy(attr->path,strlen(attr->path));
1400         assert(g_prev_attr.path != NULL);
1401         assert(!strcmp(key, attr->path));
1402         g_prev_attr.type = make_str_copy(attr->type,strlen(attr->type));
1403         assert(g_prev_attr.type != NULL);
1404         g_prev_attr.mode = attr->mode; 
1405         g_prev_attr.uid = attr->uid;
1406         g_prev_attr.gid = attr->gid;
1407         g_prev_attr.atime = attr->atime;
1408         g_prev_attr.mtime = attr->mtime;
1409         g_prev_attr.ctime = attr->ctime;
1410         g_prev_attr.size = attr->size;
1411         g_prev_attr.inode = attr->inode;
1412
1413            if(g_prev_attribute_path!=NULL)
1414                     free(g_prev_attribute_path);
1415            g_prev_attribute_path = strndup(key,strlen(key));
1416            assert(g_prev_attribute_path != NULL);
1417 #endif
1418     }
1419
1420     sqlite3_reset(stmt);
1421     key_accessed(sqlfs, key);
1422     return r;
1423
1424 }
1425
1426
1427 #undef INDEX
1428 #define INDEX 18
1429
1430 static int set_attr(sqlfs_t *sqlfs, const char *key, const key_attr *attr)
1431 {
1432     int i, r;
1433     const char *tail;
1434     sqlite3_stmt *stmt;
1435     int mode = attr->mode;
1436     static const char *cmd1 = "insert or ignore into meta_data (key) VALUES ( :key ) ; ";
1437     static const char *cmd2 = "update meta_data set type = :type, mode = :mode, uid = :uid, gid = :gid,"
1438                               "atime = :atime, mtime = :mtime, ctime = :ctime,  size = :size, inode = :inode, block_size = :block_size where key = :key; ";
1439     time_t now;
1440
1441 // baik
1442 #ifdef FAST_ATTRIBUTE_SEARCH
1443         if(g_prev_attribute_path!=NULL)
1444                 if(strcmp(g_prev_attribute_path,key)==0)
1445                 {
1446                         free(g_prev_attribute_path);
1447                         g_prev_attribute_path = NULL;
1448                 }
1449 #endif
1450
1451     BEGIN
1452     if (!strcmp(attr->type, TYPE_DIR))
1453         mode |= S_IFDIR;
1454     else if (!strcmp(attr->type, TYPE_SYM_LINK))
1455         mode |= S_IFLNK;
1456     else
1457         mode |= S_IFREG;
1458
1459     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd1, -1, &stmt,  &tail);
1460     if (r != SQLITE_OK)
1461     {
1462         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1463         COMPLETE(1)
1464         return r;
1465     }
1466     sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC);
1467     r = sql_step(stmt);
1468     sqlite3_reset(stmt);
1469
1470
1471 #undef INDEX
1472 #define INDEX 19
1473
1474
1475     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd2, -1, &stmt,  &tail);
1476     if (r != SQLITE_OK)
1477     {
1478         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1479         COMPLETE(1)
1480         return r;
1481     }
1482     sqlite3_bind_text(stmt, 1, attr->type, -1, SQLITE_STATIC);
1483     sqlite3_bind_int(stmt, 2, mode);
1484     sqlite3_bind_int(stmt, 3, attr->uid);
1485     sqlite3_bind_int(stmt, 4, attr->gid);
1486 // baik - modified time ????기????데??트 ??다.
1487 #ifdef SQLFS_FAST_TUNNING
1488     time(&now);
1489     sqlite3_bind_int(stmt, 5, now);
1490     sqlite3_bind_int(stmt, 6, now);
1491     sqlite3_bind_int(stmt, 7, now);
1492 #else
1493     sqlite3_bind_int(stmt, 5, attr->atime);
1494     sqlite3_bind_int(stmt, 6, attr->mtime);
1495     sqlite3_bind_int(stmt, 7, attr->ctime);
1496 #endif
1497     sqlite3_bind_int64(stmt, 8, attr->size);
1498     sqlite3_bind_int(stmt, 9, attr->inode);
1499     sqlite3_bind_int(stmt, 10, BLOCK_SIZE);
1500
1501     sqlite3_bind_text(stmt, 11, attr->path, -1, SQLITE_STATIC);
1502     r = sql_step(stmt);
1503
1504
1505     if (r != SQLITE_DONE)
1506     {
1507         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1508
1509     }
1510     else
1511         r = SQLITE_OK;
1512     sqlite3_reset(stmt);
1513 #ifndef SQLFS_FAST_TUNNING
1514     key_modified(sqlfs, key);
1515 #endif
1516     /*ensure_parent_existence(sqlfs, key);*/
1517     COMPLETE(1)
1518     return r;
1519
1520 }
1521
1522
1523 #undef INDEX
1524 #define INDEX 20
1525
1526
1527 static int key_set_type(sqlfs_t *sqlfs, const char *key, const char *type)
1528 {
1529     int r = SQLITE_OK, i;
1530     const char *tail;
1531     static const char *cmd = "update meta_data set type = :type where key = :key; ";
1532     sqlite3_stmt *stmt;
1533
1534 #ifdef FAST_ATTRIBUTE_SEARCH
1535         if(g_prev_attribute_path!=NULL)
1536                 if(strcmp(g_prev_attribute_path,key)==0)
1537                 {
1538                         free(g_prev_attribute_path);
1539                         g_prev_attribute_path = NULL;
1540                 }
1541 #endif
1542
1543     BEGIN
1544     i = ensure_existence(sqlfs, key, type);
1545     if (i == 1)
1546     {
1547         SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1, &stmt,  &tail);
1548         if (r != SQLITE_OK)
1549         {
1550             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1551             COMPLETE(1)
1552             return r;
1553         }
1554         sqlite3_bind_text(stmt, 1, type, -1, SQLITE_STATIC);
1555         sqlite3_bind_text(stmt, 2, key, -1, SQLITE_STATIC);
1556         r = sql_step(stmt);
1557         if (r != SQLITE_DONE)
1558         {
1559             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1560         }
1561         sqlite3_reset(stmt);
1562     }
1563     else
1564         r = SQLITE_ERROR;
1565     COMPLETE(1)
1566     return r;
1567 }
1568
1569
1570
1571 #undef INDEX
1572 #define INDEX 21
1573
1574 static int get_value_block(sqlfs_t *sqlfs, const char *key, char *data, int block_no, int *size)
1575 {
1576     int i, r;
1577     const char *tail;
1578     sqlite3_stmt *stmt;
1579     static const char *cmd = "select data_block from value_data where key = :key and block_no = :block_no;";
1580     key_attr attr = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ;
1581     clean_attr(&attr);
1582     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1, &stmt,  &tail);
1583     if (r != SQLITE_OK)
1584     {
1585         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1586         return r;
1587     }
1588     sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC);
1589     sqlite3_bind_int(stmt, 2, block_no);
1590     r = sql_step(stmt);
1591     if (r != SQLITE_ROW)
1592     {
1593         if (r != SQLITE_DONE)
1594             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1595
1596     }
1597     else
1598     {
1599         if (size)
1600             *size = sqlite3_column_bytes(stmt, 0);
1601         memcpy(data, sqlite3_column_blob(stmt, 0), sqlite3_column_bytes(stmt, 0));
1602         r = SQLITE_OK;
1603
1604     }
1605
1606     sqlite3_reset(stmt);
1607
1608     return r;
1609
1610 }
1611
1612
1613 #undef INDEX
1614 #define INDEX 22
1615
1616 static int set_value_block(sqlfs_t *sqlfs, const char *key, const char *data, int block_no, int size)
1617 {
1618     int i, r;
1619     const char *tail;
1620     sqlite3_stmt *stmt;
1621
1622     static const char *cmd = "update value_data set data_block = :data_block where key = :key and block_no = :block_no;";
1623     static const char *cmd1 = "insert or ignore into value_data (key, block_no) VALUES ( :key, :block_no ) ; ";
1624     static const char *cmd2 = "delete from value_data  where key = :key and block_no = :block_no;";
1625     char *tmp;
1626     BEGIN
1627
1628     if (size == 0)
1629     {
1630
1631         SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd2, -1, &stmt,  &tail);
1632         if (r != SQLITE_OK)
1633         {
1634             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1635             COMPLETE(1)
1636             return r;
1637         }
1638         sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC);
1639         sqlite3_bind_int(stmt, 2, block_no);
1640         r = sql_step(stmt);
1641         if (r != SQLITE_DONE)
1642         {
1643             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1644         }
1645         else
1646             r = SQLITE_OK;
1647
1648         sqlite3_reset(stmt);
1649         COMPLETE(1)
1650         return r;
1651     }
1652
1653
1654 #undef INDEX
1655 #define INDEX 23
1656
1657
1658     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd1, -1, &stmt,  &tail);
1659     if (r != SQLITE_OK)
1660     {
1661         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1662         COMPLETE(1)
1663         return r;
1664     }
1665     sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC);
1666     sqlite3_bind_int(stmt, 2, block_no);
1667     r = sql_step(stmt);
1668     sqlite3_reset(stmt);
1669
1670     if (r == SQLITE_BUSY)
1671     {
1672         COMPLETE(1)
1673         return r;
1674     }
1675
1676 #undef INDEX
1677 #define INDEX 24
1678
1679
1680     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1, &stmt,  &tail);
1681     if (r != SQLITE_OK)
1682     {
1683         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1684         COMPLETE(1)
1685         return r;
1686     }
1687     sqlite3_bind_blob(stmt, 1, data, size, SQLITE_STATIC);
1688     sqlite3_bind_text(stmt, 2, key, -1, SQLITE_STATIC);
1689     sqlite3_bind_int(stmt, 3, block_no);
1690     r = sql_step(stmt);
1691
1692
1693     if (r != SQLITE_DONE)
1694     {
1695         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1696
1697     }
1698     else
1699         r = SQLITE_OK;
1700     sqlite3_reset(stmt);
1701
1702     COMPLETE(1)
1703     return r;
1704
1705 }
1706
1707
1708
1709 #undef INDEX
1710 #define INDEX 25
1711
1712
1713 static int get_value(sqlfs_t *sqlfs, const char *key, key_value *value, size_t begin, size_t end)
1714 {
1715     int i, r;
1716     const char *tail;
1717     sqlite3_stmt *stmt;
1718     static const char *cmd = "select size from meta_data where key = :key; ";
1719     size_t size;
1720     int block_no;
1721
1722     clean_value(value);
1723     BEGIN
1724
1725     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1, &stmt,  &tail);
1726     if (r != SQLITE_OK)
1727     {
1728         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1729         COMPLETE(1)
1730         return r;
1731     }
1732     sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC);
1733     r = sql_step(stmt);
1734     if (r != SQLITE_ROW)
1735     {
1736         if (r != SQLITE_DONE)
1737             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1738
1739     }
1740     else
1741     {
1742         size = sqlite3_column_int64(stmt, 0);
1743         r = SQLITE_OK;
1744     }
1745     if (r == SQLITE_OK)
1746     {
1747         if ((end == 0) || (end > size))
1748         {
1749             end = size;
1750         }
1751         if (begin < end)
1752         {
1753             value->size = size;
1754             value->data = malloc(value->size);
1755             assert(value->data);
1756             if (end == 0)
1757                 end = value->size;
1758             begin = (block_no = (begin / BLOCK_SIZE)) * BLOCK_SIZE;
1759             for ( ; begin < end; begin += BLOCK_SIZE, block_no++)
1760             {
1761
1762                 r = get_value_block(sqlfs, key, value->data + begin - value->offset, block_no, NULL);
1763                 if (r != SQLITE_OK)
1764                     break;
1765             }
1766         }
1767         else
1768             r = SQLITE_NOTFOUND  ;
1769     }
1770
1771     sqlite3_reset(stmt);
1772     key_accessed(sqlfs, key);
1773     COMPLETE(1)
1774     return r;
1775
1776 }
1777
1778
1779 #undef INDEX
1780 #define INDEX 26
1781
1782 static int set_value(sqlfs_t *sqlfs, const char *key, const key_value *value, size_t begin, size_t end)
1783 {
1784     int i, r;
1785     const char *tail;
1786     sqlite3_stmt *stmt;
1787     size_t begin2, end2, length;
1788     int block_no;
1789     time_t now;
1790
1791     static const char *cmd1 = "insert or ignore into meta_data (key) VALUES ( :key ) ; ";
1792
1793 // baik - time ????기????데??트 ??다.
1794 #ifdef SQLFS_FAST_TUNNING
1795    static const char *cmd2 = "update meta_data set atime = :atime, mtime = :mtime, ctime = :ctime, size = :size where key =  :key  ; ";
1796 #else
1797    static const char *cmd2 = "update meta_data set size = :size where key =  :key  ; ";
1798 #endif
1799     char *tmp;
1800
1801 #ifdef FAST_ATTRIBUTE_SEARCH
1802         if(g_prev_attribute_path!=NULL)
1803                 if(strcmp(g_prev_attribute_path,key)==0)
1804                 {
1805                         free(g_prev_attribute_path);
1806                         g_prev_attribute_path = NULL;
1807                 }
1808 #endif
1809
1810     BEGIN
1811     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd1, -1, &stmt,  &tail);
1812     if (r != SQLITE_OK)
1813     {
1814         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1815         COMPLETE(1)
1816         return r;
1817     }
1818     sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC);
1819     r = sql_step(stmt);
1820     sqlite3_reset(stmt);
1821
1822     if (r == SQLITE_BUSY)
1823     {
1824         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1825         COMPLETE(1)
1826         return r;
1827     }
1828
1829 #undef INDEX
1830 #define INDEX 27
1831
1832
1833
1834     {
1835         tmp = calloc( BLOCK_SIZE, sizeof(char));
1836
1837         if (end == 0)
1838             end = value->size;
1839         begin2 = (block_no = (begin / BLOCK_SIZE)) * BLOCK_SIZE;
1840         end2 = end;
1841         if (end2 > begin2 + BLOCK_SIZE)
1842             end2 = begin2 + BLOCK_SIZE;
1843
1844         {
1845             size_t old_size = 0;
1846             r = get_value_block(sqlfs, key, tmp, block_no, &old_size);
1847             length = end2 - begin;
1848             memcpy(tmp + (begin - begin2), (value->data - value->offset) + begin, length);
1849             length = end2 - begin2;
1850             if (length < old_size)
1851                 length = old_size;
1852             r = set_value_block(sqlfs, key, tmp, block_no, length);
1853             block_no++;
1854             begin2 += BLOCK_SIZE;
1855         }
1856         for ( ; begin2 < end / BLOCK_SIZE * BLOCK_SIZE; begin2 += BLOCK_SIZE, block_no++)
1857         {
1858
1859             r = set_value_block(sqlfs, key, (value->data - value->offset) + BLOCK_SIZE * block_no, block_no, BLOCK_SIZE);
1860             if (r != SQLITE_OK)
1861                 break;
1862         }
1863
1864         if (begin2 < end)
1865         {
1866
1867             assert(begin2 % BLOCK_SIZE == 0);
1868             assert(end - begin2 < (size_t) BLOCK_SIZE);
1869
1870             memset(tmp, 0, BLOCK_SIZE);
1871             r = get_value_block(sqlfs, key, tmp, block_no, &i);
1872             if (r != SQLITE_OK)
1873                 i = 0;
1874             memcpy(tmp, (value->data - value->offset) + begin2, end - begin2 );
1875             if (i < (int)(end - begin2))
1876                 i = (int)(end - begin2);
1877
1878             r = set_value_block(sqlfs, key, tmp, block_no, i);
1879         }
1880
1881         free(tmp);
1882     }
1883     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd2, -1, &stmt,  &tail);
1884     if (r != SQLITE_OK)
1885     {
1886         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1887         COMPLETE(1)
1888         return r;
1889     }
1890 #ifdef SQLFS_FAST_TUNNING
1891     time(&now);
1892     sqlite3_bind_int64(stmt, 1, now);
1893     sqlite3_bind_int64(stmt, 2, now);
1894     sqlite3_bind_int64(stmt, 3, now);
1895     sqlite3_bind_int64(stmt, 4, value->size);
1896     sqlite3_bind_text(stmt, 5, key, -1, SQLITE_STATIC);
1897     r = sql_step(stmt);
1898     sqlite3_reset(stmt);
1899     if (r == SQLITE_DONE)
1900         r = SQLITE_OK;
1901 #else
1902     sqlite3_bind_int64(stmt, 1, value->size);
1903     sqlite3_bind_text(stmt, 2, key, -1, SQLITE_STATIC);
1904     r = sql_step(stmt);
1905     sqlite3_reset(stmt);
1906     if (r == SQLITE_DONE)
1907         r = SQLITE_OK;
1908     key_modified(sqlfs, key);
1909 #endif
1910     /*ensure_parent_existence(sqlfs, key);*/
1911     COMPLETE(1)
1912     return r;
1913
1914 }
1915
1916
1917 #undef INDEX
1918 #define INDEX 28
1919
1920
1921 static int key_shorten_value(sqlfs_t *sqlfs, const char *key, size_t new_length)
1922 {
1923     int r, i;
1924     size_t l;
1925     int block_no;
1926     char *tmp;
1927     const char *tail;
1928     sqlite3_stmt *stmt;
1929     static const char *cmd1 = "delete from value_data where key = :key and block_no > :block_no; ";
1930
1931 // baik - time ????기????데??트 ??다.
1932 #ifdef SQLFS_FAST_TUNNING
1933    static const char *cmd2 = "update meta_data set atime = :atime, mtime = :mtime, ctime = :ctime, size = :size where key =  :key  ; ";
1934 #else
1935     static const char *cmd2 = "update meta_data set size = :size where key =  :key  ; ";
1936 #endif
1937     time_t now;
1938
1939 #ifdef FAST_ATTRIBUTE_SEARCH
1940         if(g_prev_attribute_path!=NULL)
1941                 if(strcmp(g_prev_attribute_path,key)==0)
1942                 {
1943                         free(g_prev_attribute_path);
1944                         g_prev_attribute_path = NULL;
1945                 }
1946 #endif
1947
1948     BEGIN
1949     if ((i = key_exists(sqlfs, key, &l)), (i == 0))
1950     {
1951         assert(0);
1952         show_msg(stderr, "Illegal truncateion on non-existence key %s\n", key);
1953         COMPLETE(1)
1954         return SQLITE_ERROR;
1955     }
1956     else if (i == 2)
1957     {
1958         COMPLETE(1)
1959         return SQLITE_BUSY;
1960     }
1961
1962     assert(l > new_length);
1963     block_no = new_length / BLOCK_SIZE;
1964
1965     tmp = calloc(BLOCK_SIZE, sizeof(char));
1966     assert(tmp);
1967     r = get_value_block(sqlfs, key, tmp, block_no, &i);
1968     assert(new_length % BLOCK_SIZE <= (unsigned int) i);
1969     r = set_value_block(sqlfs, key, tmp, block_no, new_length % BLOCK_SIZE);
1970     if (r != SQLITE_OK)
1971     {
1972         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1973
1974     }
1975
1976     if (r == SQLITE_OK)
1977     {
1978         SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd1, -1, &stmt,  &tail);
1979         if (r != SQLITE_OK)
1980         {
1981             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1982
1983         }
1984         else
1985         {
1986             sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC);
1987             sqlite3_bind_int(stmt, 2, block_no);
1988             r = sql_step(stmt);
1989             /*if (r != SQLITE_DONE)
1990             {
1991                 show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
1992
1993             }*/
1994             /*ignore the result */
1995             if (r == SQLITE_BUSY)
1996                 ;
1997             else
1998                 r = SQLITE_OK;
1999             sqlite3_reset(stmt);
2000         }
2001     }
2002
2003
2004 #undef INDEX
2005 #define INDEX 29
2006
2007     if (r == SQLITE_OK)
2008     {
2009         SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd2, -1, &stmt,  &tail);
2010         if (r != SQLITE_OK)
2011         {
2012             show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
2013
2014         }
2015         else
2016         {
2017 #ifdef SQLFS_FAST_TUNNING
2018                 time(&now);
2019                 sqlite3_bind_int64(stmt, 1, now);
2020                 sqlite3_bind_int64(stmt, 2, now);
2021                 sqlite3_bind_int64(stmt, 3, now);
2022                 sqlite3_bind_int64(stmt, 4, new_length);
2023                 sqlite3_bind_text(stmt, 5, key, -1, SQLITE_STATIC);
2024                 r = sql_step(stmt);
2025                 sqlite3_reset(stmt);
2026                 if (r == SQLITE_DONE)
2027                         r = SQLITE_OK;
2028 #else
2029
2030             sqlite3_bind_int64(stmt, 1, new_length);
2031             sqlite3_bind_text(stmt, 2, key, -1, SQLITE_STATIC);
2032             r = sql_step(stmt);
2033             sqlite3_reset(stmt);
2034             if (r == SQLITE_DONE)
2035                 r = SQLITE_OK;
2036                key_modified(sqlfs, key);
2037 #endif
2038         }
2039     }
2040     free(tmp);
2041     /*ensure_parent_existence(sqlfs, key);*/
2042     COMPLETE(1)
2043     return r;
2044
2045 }
2046
2047 static int check_parent_access(sqlfs_t *sqlfs, const char *path)
2048 {
2049     char ppath[PATH_MAX];
2050
2051     int r, result = 0;
2052
2053     BEGIN
2054     r = get_parent_path(path, ppath);
2055 //fprintf(stderr, "%s #1 returns %d on %s\n", __func__, r, path);//???
2056     if (r == SQLITE_OK)
2057     {
2058         result = check_parent_access(sqlfs, ppath);
2059 //fprintf(stderr, "%s #2 returns %d on %s\n", __func__, result, path);//???
2060         if (result == 0)
2061             result = (sqlfs_proc_access(sqlfs, (ppath), X_OK));
2062 //fprintf(stderr, "%s #3 returns %d on %s %s\n", __func__, result, path, ppath);//???
2063     }
2064     /* else if no parent, we return 0 by default */
2065
2066     COMPLETE(1)
2067 //fprintf(stderr, "%s returns %d on %s\n", __func__, result, path);//???
2068     return result;
2069 }
2070
2071
2072 static int check_parent_write(sqlfs_t *sqlfs, const char *path)
2073 {
2074     char ppath[PATH_MAX];
2075
2076     int r, result = 0;
2077
2078     BEGIN
2079     r = get_parent_path(path, ppath);
2080     if (r == SQLITE_OK)
2081     {
2082         result = (sqlfs_proc_access(sqlfs, (ppath), W_OK | X_OK));
2083 //fprintf(stderr, "check directory write 1st %s %d uid %d gid %d\n",   ppath, result, get_sqlfs(sqlfs)->uid, get_sqlfs(sqlfs)->gid);//???
2084
2085 #ifndef FUSE
2086         if (result == -ENOENT)
2087         {
2088             result = check_parent_write(sqlfs, ppath);
2089             if (result == 0)
2090                 ensure_existence(sqlfs, ppath, TYPE_DIR);
2091             result = (sqlfs_proc_access(sqlfs, (ppath), W_OK | X_OK));
2092         }
2093 #endif
2094     }
2095     COMPLETE(1)
2096 //fprintf(stderr, "check directory write %s %d\n",   ppath, result);//???
2097     return result;
2098 }
2099
2100 #ifndef SQLFS_FAST_TUNNING 
2101 #define CHECK_PARENT_PATH(p) result = check_parent_access(sqlfs, (p)); if (result != 0) { COMPLETE(1); return result; }
2102
2103 #define CHECK_READ(p)  result = (sqlfs_proc_access(sqlfs, (p), R_OK | F_OK));  if (result != 0) { COMPLETE(1); return result; }
2104 #define CHECK_WRITE(p) result = (sqlfs_proc_access(sqlfs, (p), W_OK | F_OK));  if (result != 0) { COMPLETE(1); return result; }
2105
2106 #define CHECK_DIR_WRITE(p) result = (sqlfs_proc_access(sqlfs, (p), W_OK | F_OK | X_OK));  if (result != 0) { COMPLETE(1); return result; }
2107 #define CHECK_DIR_READ(p) result = (sqlfs_proc_access(sqlfs, (p), R_OK | F_OK | X_OK));  if (result != 0) {fprintf(stderr, "dir read failed %d\n", result); COMPLETE(1); return result; }
2108
2109 #define CHECK_PARENT_READ(p)  \
2110   { char ppath[PATH_MAX]; if (SQLITE_OK == get_parent_path((p), ppath))  {  result = (sqlfs_proc_access(sqlfs, (ppath), R_OK | X_OK));  if (result != 0) { COMPLETE(1); return result; }}}
2111 #define CHECK_PARENT_WRITE(p) \
2112   { result = check_parent_write(sqlfs, (p));  if (result != 0) { COMPLETE(1); return result; }}
2113
2114 #else   /* Enable fast tuning */
2115
2116 // baik - ??도?????해 access permission 체크????단 ???? ??는??
2117
2118 #if 0   /* Block permission check */
2119 #define CHECK_PARENT_PATH(p) result = 0;
2120
2121 #define CHECK_READ(p)  result = 0;
2122 #define CHECK_WRITE(p) result = 0; 
2123
2124 #define CHECK_DIR_WRITE(p) result = 0; 
2125 #define CHECK_DIR_READ(p) result = 0; 
2126
2127 #define CHECK_PARENT_READ(p) result = 0;
2128 #define CHECK_PARENT_WRITE(p) result = 0; 
2129 #endif /* if 0 */
2130
2131 /* Use basic permission checks */
2132 #define CHECK_PARENT_PATH(p) result = check_parent_access(sqlfs, (p)); if (result != 0) { COMPLETE(1); return result; }
2133
2134 #define CHECK_READ(p)  result = (sqlfs_proc_access(sqlfs, (p), R_OK | F_OK));  if (result != 0) { COMPLETE(1); return result; }
2135 #define CHECK_WRITE(p) result = (sqlfs_proc_access(sqlfs, (p), W_OK | F_OK));  if (result != 0) { COMPLETE(1); return result; }
2136
2137 #define CHECK_DIR_WRITE(p) result = (sqlfs_proc_access(sqlfs, (p), W_OK | F_OK | X_OK));  if (result != 0) { COMPLETE(1); return result; }
2138 #define CHECK_DIR_READ(p) result = (sqlfs_proc_access(sqlfs, (p), R_OK | F_OK | X_OK));  if (result != 0) {fprintf(stderr, "dir read failed %d\n", result); COMPLETE(1); return result; }
2139
2140 #define CHECK_PARENT_READ(p)  \
2141   { char ppath[PATH_MAX]; if (SQLITE_OK == get_parent_path((p), ppath))  {  result = (sqlfs_proc_access(sqlfs, (ppath), R_OK | X_OK));  if (result != 0) { COMPLETE(1); return result; }}}
2142 #define CHECK_PARENT_WRITE(p) \
2143   { result = check_parent_write(sqlfs, (p));  if (result != 0) { COMPLETE(1); return result; }}
2144
2145 #endif
2146
2147 int sqlfs_proc_getattr(sqlfs_t *sqlfs, const char *path, struct stat *stbuf)
2148 {
2149     key_attr attr = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2150     int r, result = 0;
2151
2152     BEGIN
2153     CHECK_PARENT_PATH(path)
2154     CHECK_READ(path)
2155
2156     r = get_attr(get_sqlfs(sqlfs), path, &attr);
2157     if (r == SQLITE_OK)
2158     {
2159         memset(stbuf, 0, sizeof(*stbuf));
2160         stbuf->st_mode = attr.mode;
2161         if (!strcmp(attr.type, TYPE_DIR))
2162             stbuf->st_mode |= S_IFDIR;
2163         else if (!strcmp(attr.type, TYPE_SYM_LINK))
2164             stbuf->st_mode |= S_IFLNK;
2165         else
2166             stbuf->st_mode |= S_IFREG;
2167         stbuf->st_nlink = 1;
2168         stbuf->st_uid = (uid_t) attr.uid;
2169         stbuf->st_gid = (gid_t) attr.gid;
2170         stbuf->st_size = (off_t) attr.size;
2171         stbuf->st_blksize = 512;
2172         stbuf->st_blocks = attr.size / 512;
2173         stbuf->st_atime = attr.atime;
2174         stbuf->st_mtime = attr.mtime;
2175         stbuf->st_ctime = attr.ctime;
2176         stbuf->st_ino = attr.inode;
2177         clean_attr(&attr);
2178
2179     }
2180     else{
2181         result =   -ENOENT;
2182         clean_attr(&attr);
2183     }
2184     COMPLETE(1)
2185     return result;
2186 }
2187
2188
2189 #if 0
2190 /* Because of bug, this function is commented out. 
2191  * uid_in_fgid() function is used instead of gid_in_supp_groups() */
2192 static int gid_in_supp_groups(gid_t gid)
2193 {
2194     int n, num_groups = getgroups(0, 0);
2195     int r = 0;
2196     if (num_groups)
2197     {
2198         gid_t *gids = malloc(sizeof(gids[0]) * num_groups);
2199         n = getgroups(num_groups, gids);
2200
2201         assert(n == num_groups);
2202         for (n = 0; n < num_groups; n++)
2203         {
2204             if (gid == gids[n])
2205             {
2206                 r = 1;
2207                 break;
2208             }
2209         }
2210         free(gids);
2211     }
2212     return r;
2213 }
2214 #endif
2215
2216 #include <pwd.h>
2217 #include <grp.h>
2218 static int uid_in_fgid(uid_t euid, gid_t fgid)
2219 {
2220         /* euid: effective uid
2221            fgid: file gid      */
2222         struct group* gr = getgrgid(fgid);
2223         if(!gr){
2224                 // Error
2225                 return 0;
2226         }
2227         if(!(gr->gr_mem)) return 0;
2228         char **gr_mem = gr->gr_mem;
2229         struct passwd *pwd = NULL;
2230         for(; *gr_mem; gr_mem++) {
2231                 pwd = getpwnam(*gr_mem);
2232                 if(!pwd) continue;
2233                 if(euid == pwd->pw_uid)
2234                         return 1;
2235         }
2236
2237         return 0;
2238 }
2239
2240
2241 int sqlfs_proc_access(sqlfs_t *sqlfs, const char *path, int mask)
2242 {
2243
2244     int i, r = SQLITE_OK, result = 0;
2245 #ifdef FUSE
2246 #ifdef ENABLE_DAC
2247         gid_t uid = fuse_get_context()->uid;
2248         uid_t gid = fuse_get_context()->gid;
2249         printf("[%s:%d]uid = %d, gid = %d\n", __FILE__, __LINE__, uid, gid);
2250 #else
2251     gid_t gid = getegid();
2252     uid_t uid = geteuid();
2253 #endif
2254 #else
2255     gid_t gid = get_sqlfs(sqlfs)->gid;
2256     uid_t uid = get_sqlfs(sqlfs)->uid;
2257 #endif
2258     uid_t fuid;
2259     gid_t fgid;
2260     mode_t fmode;
2261
2262     BEGIN
2263
2264     if (uid == 0) /* root user so everything is granted */
2265     {
2266         if ((i = key_exists(sqlfs, path, 0)), !i)
2267             result = -ENOENT;
2268         else if (i == 2)
2269             result = -EBUSY;
2270
2271         COMPLETE(1)
2272         //fprintf(stderr, "root access returns %d on %s\n", result, path);//???
2273         return result;
2274     }
2275
2276     if (mask & F_OK)
2277     {
2278         r = get_parent_permission_data(sqlfs, path, &fgid, &fuid, &fmode);
2279         if (r == SQLITE_OK)
2280         {
2281             if (uid == (uid_t) fuid)
2282             {
2283                 if ( !(S_IRUSR  & S_IXUSR & fmode))
2284                 {
2285                     result = -EACCES;
2286                 }
2287
2288             }
2289             // else if ((gid == (gid_t) fgid) || (gid_in_supp_groups(fgid)))
2290             else if ((gid == (gid_t) fgid) || (uid_in_fgid(uid, fgid)))
2291             {
2292                 if ( !(S_IRGRP  & S_IXGRP & fmode))
2293                 {
2294                     result = -EACCES;
2295                 }
2296             }
2297             else
2298             {
2299                 if ( !(S_IROTH  & S_IXOTH & fmode))
2300                 {
2301                     result = -EACCES;
2302                 }
2303             }
2304         }
2305         else if (r == SQLITE_NOTFOUND)
2306             result = -ENOENT;
2307
2308     }
2309
2310
2311     if (result == 0)
2312         r = get_permission_data(get_sqlfs(sqlfs), path, &fgid, &fuid, &fmode);
2313     //fprintf(stderr, "get permission returns %d\n", r);//???
2314     if ((r == SQLITE_OK) && (result == 0))
2315     {
2316         if (uid == (uid_t) fuid)
2317         {
2318             if (((mask & R_OK) && !(S_IRUSR & fmode))  ||
2319                     ((mask & W_OK) && !(S_IWUSR & fmode))  ||
2320                     ((mask & X_OK) && !(S_IXUSR & fmode)))
2321             {
2322
2323                 result = -EACCES;
2324             }
2325         }
2326         // else if ((gid == (uid_t) fgid) || (gid_in_supp_groups(fgid)))
2327         else if ((gid == (uid_t) fgid) || (uid_in_fgid(uid, fgid)))
2328         {
2329             if (((mask & R_OK) && !(S_IRGRP & fmode))  ||
2330                     ((mask & W_OK) && !(S_IWGRP & fmode))  ||
2331                     ((mask & X_OK) && !(S_IXGRP & fmode)))
2332             {
2333
2334                 result = -EACCES;
2335             }
2336         }
2337
2338         else if (((mask & R_OK) && !(S_IROTH & fmode))  ||
2339                  ((mask & W_OK) && !(S_IWOTH & fmode))  ||
2340                  ((mask & X_OK) && !(S_IXOTH & fmode)))
2341         {
2342
2343             result = -EACCES;
2344         }
2345
2346
2347     }
2348     else if (r == SQLITE_NOTFOUND)
2349         result = -ENOENT;
2350     else
2351         result = -EIO;
2352
2353     COMPLETE(1)
2354     return result;
2355 }
2356
2357
2358 int sqlfs_proc_readlink(sqlfs_t *sqlfs, const char *path, char *buf, size_t size)
2359 {
2360     key_attr attr = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2361     key_value value = { 0, 0, 0 };
2362     int r, result = 0;
2363     BEGIN
2364     CHECK_PARENT_PATH(path)
2365     CHECK_READ(path)
2366     r = get_attr(get_sqlfs(sqlfs), path, &attr);
2367     if (r == SQLITE_OK)
2368     {
2369         if (!strcmp(attr.type, TYPE_SYM_LINK))
2370         {
2371             r = get_value(get_sqlfs(sqlfs), path, &value, 0, 0);
2372             if (r == SQLITE_OK)
2373             {
2374                 if (value.size > size)
2375                 { /* too short a buffer */
2376                     show_msg(stderr,
2377                              "warning: readlink provided buffer too small\n");
2378
2379                 }
2380                 strncpy(buf, value.data, size);
2381             }
2382             clean_value(&value);
2383         }
2384         else
2385         {
2386             result = -EINVAL;
2387         }
2388     }
2389     clean_attr(&attr);
2390     COMPLETE(1)
2391     return result;
2392 }
2393
2394
2395 #undef INDEX
2396 #define INDEX 30
2397
2398 int sqlfs_proc_readdir(sqlfs_t *sqlfs, const char *path, void *buf, fuse_fill_dir_t filler,
2399                        off_t offset, struct fuse_file_info *fi)
2400 {
2401     int i, r, result = 0;
2402     const char *tail;
2403     const char *t, *t2;
2404     static const char *cmd = "select key, mode from meta_data where key glob :pattern; ";
2405     char tmp[PATH_MAX];
2406     char *lpath;
2407     sqlite3_stmt *stmt;
2408     BEGIN
2409     CHECK_PARENT_PATH(path)
2410     CHECK_DIR_READ(path)
2411
2412     if ((i = key_is_dir(get_sqlfs(sqlfs), path)), !i)
2413     {
2414         COMPLETE(1)
2415         return -ENOTDIR;
2416     }
2417     else if (i == 2)
2418     {
2419         COMPLETE(1)
2420         return -EBUSY;
2421     }
2422
2423     lpath = strndup(path,strlen(path));
2424     assert(lpath != NULL);
2425     remove_tail_slash(lpath);
2426     filler(buf, ".", NULL, 0);
2427     filler(buf, "..", NULL, 0);
2428     snprintf(tmp, sizeof(tmp), "%s/*", lpath);
2429
2430     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1, &stmt,  &tail);
2431     if (r != SQLITE_OK)
2432     {
2433         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
2434
2435         result = -EACCES;
2436     }
2437     if (result == 0)
2438     {
2439         sqlite3_bind_text(stmt, 1, tmp, -1, SQLITE_STATIC);
2440
2441         while (1)
2442         {
2443             r = sql_step(stmt);
2444             if (r == SQLITE_ROW)
2445             {
2446                 t = sqlite3_column_text(stmt, 0);
2447                 if (!strcmp(t, lpath))
2448                     continue;
2449                 t2 = t + strlen(lpath) + 1;
2450                 if (strchr(t2, '/'))
2451                     continue; /* grand child, etc. */
2452                 if (*t2 == 0) /* special case when dir the root directory */
2453                     continue;
2454
2455                 if (filler(buf, t2, NULL, 0))
2456                     break;
2457             }
2458             else if (r == SQLITE_DONE)
2459             {
2460                 break;
2461             }
2462             else if (r == SQLITE_BUSY)
2463                 result = -EBUSY;
2464             else
2465             {
2466                 show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
2467                 result = -EACCES;
2468                 break;
2469             }
2470         }
2471         sqlite3_reset(stmt);
2472     }
2473     COMPLETE(1)
2474     free(lpath);
2475     return result;
2476 }
2477
2478 int sqlfs_proc_mknod(sqlfs_t *sqlfs, const char *path, mode_t mode, dev_t rdev)
2479 {
2480     key_attr attr = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2481     int r, result = 0;
2482     if ((S_IFCHR & mode) || (S_IFBLK & mode))
2483         return -EACCES; /* not supported, not allowed */
2484
2485     if (!((S_IFREG & mode) || (S_IFIFO & mode) || (S_IFSOCK & mode)))
2486         return -EINVAL;
2487     BEGIN
2488     CHECK_PARENT_WRITE(path)
2489
2490     r = get_attr(get_sqlfs(sqlfs), path, &attr);
2491     if (r == SQLITE_OK)
2492     {
2493         clean_attr(&attr);
2494         COMPLETE(1)
2495         return -EEXIST;
2496     }
2497     attr.path = strndup(path,strlen(path));
2498     assert(attr.path != NULL);
2499     attr.type = strndup(TYPE_BLOB, strlen(TYPE_BLOB));
2500     assert(attr.path != NULL);
2501     attr.mode = mode;
2502 #ifdef FUSE
2503 #ifdef ENABLE_DAC
2504         attr.uid = fuse_get_context()->uid;
2505         attr.gid = fuse_get_context()->gid;
2506         /* printf("[%s:%d]attr.uid = %d, attr.gid = %d\n", __FILE__, __LINE__, attr.uid, attr.gid); */
2507 #else
2508     attr.gid = getegid();
2509     attr.uid = geteuid();
2510 #endif
2511 #else
2512     attr.gid = get_sqlfs(sqlfs)->gid;
2513     attr.uid = get_sqlfs(sqlfs)->uid;
2514 #endif
2515     attr.size = 0;
2516     attr.inode = get_new_inode();
2517     r = set_attr(get_sqlfs(sqlfs), path, &attr);
2518     if (r == SQLITE_BUSY)
2519         result = -EBUSY;
2520     else if (r != SQLITE_OK)
2521     {
2522
2523         result =  -EINVAL;
2524     }
2525     clean_attr(&attr);
2526     COMPLETE(1)
2527     return result;
2528 }
2529
2530 int sqlfs_proc_mkdir(sqlfs_t *sqlfs, const char *path, mode_t mode)
2531 {
2532     key_attr attr = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2533     int r, result = 0;
2534     BEGIN
2535     CHECK_PARENT_WRITE(path)
2536
2537     r = get_attr(get_sqlfs(sqlfs), path, &attr);
2538     if (r == SQLITE_OK)
2539     {
2540         clean_attr(&attr);
2541         COMPLETE(1)
2542         return -EEXIST;
2543     }
2544     attr.path = strndup(path,strlen(path));
2545     assert(attr.path != NULL);
2546     attr.type = strndup(TYPE_DIR,strlen(TYPE_DIR));
2547     assert(attr.type != NULL);
2548     attr.mode = mode;
2549
2550 #ifdef FUSE
2551 #ifdef ENABLE_DAC
2552         attr.uid = fuse_get_context()->uid;
2553         attr.gid = fuse_get_context()->gid;
2554         /* printf("[%s:%d]attr.uid = %d, attr.gid = %d\n", __FILE__, __LINE__, attr.uid, attr.gid); */
2555 #else 
2556     attr.gid = getegid();
2557     attr.uid = geteuid();
2558 #endif
2559 #else
2560     attr.gid = get_sqlfs(sqlfs)->gid;
2561     attr.uid = get_sqlfs(sqlfs)->uid;
2562 #endif
2563     attr.size = 0;
2564     attr.inode = get_new_inode();
2565     r = set_attr(get_sqlfs(sqlfs), path, &attr);
2566     if (r == SQLITE_BUSY)
2567         result = -EBUSY;
2568     else  if (r != SQLITE_OK)
2569     {
2570         result = -EINVAL;
2571     }
2572     clean_attr(&attr);
2573     COMPLETE(1)
2574     return result;
2575 }
2576
2577 int sqlfs_proc_unlink(sqlfs_t *sqlfs, const char *path)
2578 {
2579     int i, r, result = 0;
2580     BEGIN
2581     CHECK_PARENT_WRITE(path)
2582     CHECK_WRITE(path)
2583     if ((i = key_exists(get_sqlfs(sqlfs), path, 0)), (i == 0))
2584         result = -ENOENT;
2585     else if (i == 2)
2586         result = -EBUSY;
2587
2588     if (key_is_dir(get_sqlfs(sqlfs), path))
2589     {
2590         result = -EISDIR;
2591     }
2592
2593
2594     if (result == 0)
2595     {
2596         r = remove_key(get_sqlfs(sqlfs), path);
2597         if (r == SQLITE_BUSY)
2598             result = -EBUSY;
2599         else if (r != SQLITE_OK)
2600             result = -EIO;
2601     }
2602     COMPLETE(1)
2603     return result;
2604 }
2605
2606 int sqlfs_proc_rmdir(sqlfs_t *sqlfs, const char *path)
2607 {
2608     int r, result = 0;
2609     BEGIN
2610     CHECK_PARENT_WRITE(path)
2611
2612     if (get_dir_children_num(get_sqlfs(sqlfs), path) > 0)
2613     {
2614         result = -ENOTEMPTY;
2615     }
2616     else
2617     {
2618         r = remove_key(get_sqlfs(sqlfs), path);
2619         if (r != SQLITE_OK)
2620             result = -EIO;
2621     }
2622     COMPLETE(1)
2623     return result;
2624 }
2625
2626 int sqlfs_proc_symlink(sqlfs_t *sqlfs, const char *path, const char *to)
2627 {
2628     key_attr attr = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2629     key_value value = { 0, 0, 0 };
2630     int r, result = 0;
2631     BEGIN
2632     CHECK_PARENT_WRITE(to)
2633
2634     r = get_attr(get_sqlfs(sqlfs), to, &attr);
2635     if (r == SQLITE_OK)
2636     {
2637         clean_attr(&attr);
2638         COMPLETE(1)
2639         return -EEXIST;
2640     }
2641
2642     attr.path = strndup(to,strlen(to));
2643     assert(attr.path != NULL);
2644     attr.type = strndup(TYPE_SYM_LINK,strlen(TYPE_SYM_LINK));
2645     assert(attr.path != NULL);
2646     attr.mode = get_sqlfs(sqlfs)->default_mode; /* 0777 ?? */
2647 #ifdef FUSE
2648 #ifdef ENABLE_DAC
2649         attr.uid = fuse_get_context()->uid;
2650         attr.gid = fuse_get_context()->gid;
2651         /* printf("[%s:%d]attr.uid = %d, attr.gid = %d\n", __FILE__, __LINE__, attr.uid, attr.gid); */
2652 #else
2653     attr.uid = geteuid();
2654     attr.gid = getegid();
2655 #endif
2656 #else
2657     attr.uid = get_sqlfs(sqlfs)->uid;
2658     attr.gid = get_sqlfs(sqlfs)->gid;
2659
2660 #endif
2661     attr.size = 0;
2662     attr.inode = get_new_inode();
2663     r = set_attr(get_sqlfs(sqlfs), to, &attr);
2664
2665     if (r != SQLITE_OK)
2666     {
2667         clean_attr(&attr);
2668         COMPLETE(1)
2669         if (r == SQLITE_BUSY)
2670             return -EBUSY;
2671         return -EINVAL;
2672     }
2673     clean_attr(&attr);
2674     value.data = strndup(path,strlen(path));
2675     assert(value.data != NULL);
2676     value.size = strlen(value.data) + 1;
2677
2678     r = set_value(get_sqlfs(sqlfs), to, &value, 0, 0);
2679     if (r != SQLITE_OK)
2680     {
2681         result = -EIO;
2682     }
2683
2684     clean_value(&value);
2685     COMPLETE(1)
2686     return result;
2687
2688 }
2689
2690 int sqlfs_proc_rename(sqlfs_t *sqlfs, const char *from, const char *to)
2691 {
2692
2693     int i, r = SQLITE_OK, result = 0;
2694     BEGIN
2695     CHECK_PARENT_WRITE(from)
2696     CHECK_PARENT_WRITE(to)
2697
2698     if ((i = key_exists(get_sqlfs(sqlfs), from, 0)), !i)
2699     {
2700         COMPLETE(1)
2701
2702         return -EIO;
2703     }
2704     else if (i == 2)
2705     {
2706
2707         COMPLETE(1)
2708         return -EBUSY;
2709     }
2710
2711     if (key_is_dir(get_sqlfs(sqlfs), to) == 1)
2712     {
2713         if (get_dir_children_num(get_sqlfs(sqlfs), to) > 0)
2714         {
2715
2716             result =  -ENOTEMPTY;
2717         }
2718         if (!key_is_dir(get_sqlfs(sqlfs), from))
2719         {
2720
2721             result = -EISDIR;
2722         }
2723     }
2724     if ((result == 0) && (key_is_dir(get_sqlfs(sqlfs), from) == 1))
2725     {
2726         if (key_is_dir(get_sqlfs(sqlfs), to) == 0)
2727         {
2728
2729             result = -ENOTDIR;
2730         }
2731     }
2732
2733     if ((i = key_exists(get_sqlfs(sqlfs), to, 0)), (i == 1))
2734     {
2735         r = remove_key(get_sqlfs(sqlfs), to);
2736
2737         if (r != SQLITE_OK)
2738         {
2739             result = -EIO;
2740             if (r == SQLITE_BUSY)
2741                 result = -EBUSY;
2742
2743
2744         }
2745     }
2746     else if (i == 2)
2747         result = -EBUSY;
2748
2749     if (result == 0)
2750     {
2751         r = rename_key(get_sqlfs(sqlfs), from, to);
2752
2753         if (r != SQLITE_OK)
2754         {
2755             result = -EIO;
2756             if (r == SQLITE_BUSY)
2757                 result = -EBUSY;
2758
2759
2760         }
2761
2762     }
2763     COMPLETE(1)
2764     return result;
2765 }
2766
2767 int sqlfs_proc_link(sqlfs_t *sqlfs, const char *from, const char *to)
2768 { /* hard link not supported, not allowed */
2769     return - EACCES;
2770
2771 }
2772
2773 int sqlfs_proc_chmod(sqlfs_t *sqlfs, const char *path, mode_t mode)
2774 {
2775     int r, result = 0;
2776     key_attr attr = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ;
2777     BEGIN
2778
2779     CHECK_PARENT_PATH(path)
2780
2781     r = get_attr(get_sqlfs(sqlfs), path, &attr);
2782     if (r != SQLITE_OK)
2783     {
2784         COMPLETE(1)
2785         clean_attr(&attr);
2786         if (r == SQLITE_BUSY)
2787             return -EBUSY;
2788         return -ENOENT;
2789     }
2790 #ifdef FUSE
2791 #ifdef ENABLE_DAC
2792         if (((fuse_get_context()->uid) != 0) && ((fuse_get_context()->uid) != (uid_t) attr.uid))
2793 #else
2794     if ((geteuid() != 0) && (geteuid() != (uid_t) attr.uid))
2795 #endif
2796 #else
2797     if ((get_sqlfs(sqlfs)->uid != 0) && (get_sqlfs(sqlfs)->uid != (uid_t) attr.uid))
2798 #endif
2799     {
2800         result = -EACCES;
2801     }
2802     else
2803     {
2804         attr.mode &= ~(S_IRWXU | S_IRWXG | S_IRWXO);
2805         attr.mode |= mode;
2806
2807         r = set_attr(get_sqlfs(sqlfs), path, &attr);
2808         if (r == SQLITE_BUSY)
2809             result = -EBUSY;
2810         else if (r != SQLITE_OK)
2811         {
2812             result = -EACCES;
2813         }
2814     }
2815
2816     clean_attr(&attr);
2817     COMPLETE(1)
2818     return result;
2819 }
2820
2821 int sqlfs_proc_chown(sqlfs_t *sqlfs, const char *path, uid_t uid, gid_t gid)
2822 {
2823     int r, result = 0;
2824     key_attr attr = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ;
2825     int group_change_only = 0;
2826     BEGIN
2827
2828     CHECK_PARENT_PATH(path)
2829
2830     r = get_attr(get_sqlfs(sqlfs), path, &attr);
2831     if (r != SQLITE_OK)
2832     {
2833         COMPLETE(1)
2834         clean_attr(&attr);
2835         if (r == SQLITE_BUSY)
2836             return -EBUSY;
2837         return -ENOENT;
2838     }
2839 #ifdef FUSE
2840 #ifdef ENABLE_DAC
2841         if (((fuse_get_context()->uid) == 0) || (((fuse_get_context()->uid) == attr.uid) && (uid == (uid_t) attr.uid)))
2842 #else
2843     if ((geteuid() == 0) || ((geteuid() == attr.uid) && (uid == (uid_t) attr.uid)))
2844 #endif
2845 #else
2846     if ((get_sqlfs(sqlfs)->uid == 0) || ((get_sqlfs(sqlfs)->uid == (uid_t) attr.uid) && (uid == (uid_t) attr.uid)))
2847 #endif
2848     {
2849         if(uid != -1){
2850             attr.uid = uid;
2851         }
2852         if(gid != -1){
2853             attr.gid = gid;
2854         }
2855
2856         r = set_attr(get_sqlfs(sqlfs), path, &attr);
2857         if (r == SQLITE_BUSY)
2858             result = -EBUSY;
2859         else if (r != SQLITE_OK)
2860         {
2861             result = -EACCES;
2862         }
2863     }
2864     else
2865     {
2866         result = -EACCES;
2867     }
2868     clean_attr(&attr);
2869     COMPLETE(1)
2870     return result;
2871
2872 }
2873
2874 int sqlfs_proc_truncate(sqlfs_t *sqlfs, const char *path, off_t size)
2875 {
2876     int r, result = 0;
2877     char *data;
2878     key_value value = { 0, 0, 0 };
2879
2880     BEGIN
2881     CHECK_PARENT_PATH(path)
2882     CHECK_WRITE(path)
2883
2884 // baik - get_value ???????요가 ??는 경우.
2885 #ifdef FAST_ATTRIBUTE_SEARCH
2886         if(g_prev_attribute_path!=NULL)
2887           if(strcmp(g_prev_attribute_path,path)==0)
2888           {
2889                         if(g_prev_attr.size > (size_t)size)
2890                         {
2891                                 value.size = g_prev_attr.size;
2892                                 goto truncate_shorten;
2893                         }
2894                 }
2895 #endif
2896
2897     r = get_value(get_sqlfs(sqlfs), path, &value, 0, 0);
2898
2899     if (r == SQLITE_NOTFOUND)
2900     {
2901         r = 0;
2902     }
2903     else
2904         if (r != SQLITE_OK)
2905         {
2906             COMPLETE(1)
2907             clean_value(&value);
2908             if (r == SQLITE_BUSY)
2909                 return -EBUSY;
2910             return -ENOENT;
2911         }
2912
2913     if (value.size > (size_t) size)
2914     {
2915 #ifdef FAST_ATTRIBUTE_SEARCH
2916 truncate_shorten:
2917 #endif
2918         value.size = size;
2919         r = key_shorten_value(get_sqlfs(sqlfs), path, value.size);
2920         if (r == SQLITE_BUSY)
2921             result = -EBUSY;
2922         else if (r != SQLITE_OK)
2923             result = -EIO;
2924     }
2925     else if (value.size < (size_t) size)
2926     {
2927         data = realloc(value.data, size);
2928         if (data == NULL)
2929         {
2930             result = -EINVAL;
2931         }
2932         else
2933         {
2934             memset(data + value.size, 0, size - value.size);
2935             value.data = data;
2936             value.size = size;
2937         }
2938         if (result == 0)
2939         {
2940             r = set_value(get_sqlfs(sqlfs), path, &value, 0, 0);
2941             if (r != SQLITE_OK)
2942             {
2943                 if (r == SQLITE_BUSY)
2944                     result = -EBUSY;
2945                 else result = -EACCES;
2946             }
2947         }
2948     }
2949     clean_value(&value);
2950     COMPLETE(1)
2951     return result;
2952
2953 }
2954
2955 int sqlfs_proc_utime(sqlfs_t *sqlfs, const char *path, struct utimbuf *buf)
2956 {
2957     int r, result = 0;
2958     time_t now;
2959     key_attr attr = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ;
2960     BEGIN
2961     CHECK_PARENT_PATH(path)
2962     CHECK_WRITE(path)
2963     r = get_attr(get_sqlfs(sqlfs), path, &attr);
2964     if (r != SQLITE_OK)
2965     {
2966         COMPLETE(1)
2967         clean_attr(&attr);
2968         if (r == SQLITE_BUSY)
2969             return -EBUSY;
2970         return -ENOENT;
2971     }
2972     if (!buf)
2973     {
2974         time(&now);
2975         attr.atime = now;
2976         attr.mtime = now;
2977     }
2978     else
2979     {
2980
2981         attr.atime = buf->actime;
2982         attr.mtime = buf->modtime;
2983     }
2984     r = set_attr(get_sqlfs(sqlfs), path, &attr);
2985     if (r != SQLITE_OK)
2986     {
2987         if (r == SQLITE_BUSY)
2988             result = -EBUSY;
2989         else result = -EACCES;
2990     }
2991
2992     clean_attr(&attr);
2993     COMPLETE(1)
2994     return result;
2995
2996 }
2997
2998 int sqlfs_proc_create(sqlfs_t *sqlfs, const char *path, mode_t mode, struct fuse_file_info *fi)
2999 {
3000     int r, result = 0;
3001     key_attr attr = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
3002
3003     if (fi->direct_io)
3004         return  -EACCES;
3005
3006     fi->flags |= O_CREAT | O_WRONLY | O_TRUNC;
3007     BEGIN
3008     CHECK_PARENT_WRITE(path)
3009
3010     r = get_attr(get_sqlfs(sqlfs), path, &attr);
3011     if (r == SQLITE_OK) /* already exists */
3012     {
3013         if (fi->flags & (O_CREAT | O_EXCL))
3014         {
3015
3016             result = -EEXIST;
3017         }
3018         else
3019             if (!strcmp(attr.type, TYPE_DIR) && (fi->flags & (O_WRONLY | O_RDWR)))
3020             {
3021
3022                 result = -EISDIR;
3023             }
3024     }
3025     else
3026         if (r == SQLITE_BUSY)
3027             result = -EBUSY;
3028         else
3029             /* does not exist */
3030             if ((fi->flags & O_CREAT) == 0)
3031                 result = - ENOENT ;
3032     if (result == 0)
3033     {
3034         attr.mode = mode;
3035 #ifdef FUSE
3036 #ifdef ENABLE_DAC
3037                 attr.uid = fuse_get_context()->uid;
3038                 attr.gid = fuse_get_context()->gid;
3039                 /* printf("[%s:%d]attr.uid = %d, attr.gid = %d\n", __FILE__, __LINE__, attr.uid, attr.gid); */ 
3040 #else
3041         attr.uid = geteuid();
3042         attr.gid = getegid();
3043 #endif
3044 #else
3045         attr.uid = get_sqlfs(sqlfs)->uid;
3046         attr.gid = get_sqlfs(sqlfs)->gid;
3047
3048 #endif
3049
3050         if (attr.path == 0)
3051         {
3052             attr.path = strndup(path,strlen(path));
3053             assert(attr.path != NULL);
3054             attr.inode = get_new_inode();
3055         }
3056         if (attr.type == 0){
3057             attr.type = strndup(TYPE_BLOB,strlen(TYPE_BLOB));
3058             assert(attr.type != NULL);
3059         }
3060         r = set_attr(get_sqlfs(sqlfs), path, &attr);
3061         if (r == SQLITE_BUSY)
3062             result = -EBUSY;
3063         else if (r != SQLITE_OK)
3064             result = -EACCES;
3065     }
3066     clean_attr(&attr);
3067     COMPLETE(1)
3068     return result;
3069
3070 }
3071
3072 int sqlfs_proc_open(sqlfs_t *sqlfs, const char *path, struct fuse_file_info *fi)
3073 {
3074     int r, result = 0;
3075     key_attr attr = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
3076
3077     if (fi->direct_io)
3078         return  -EACCES;
3079     BEGIN
3080
3081     if ((fi->flags & O_CREAT) )
3082     {
3083         CHECK_PARENT_WRITE(path)
3084     }
3085
3086     if (fi->flags & (O_WRONLY | O_RDWR))
3087     {
3088         CHECK_PARENT_PATH(path)
3089         CHECK_WRITE(path)
3090     }
3091     else
3092     {
3093         CHECK_PARENT_PATH(path)
3094         CHECK_READ(path)
3095     }
3096     r = get_attr(get_sqlfs(sqlfs), path, &attr);
3097     if (r == SQLITE_OK) /* already exists */
3098     {
3099         if (fi->flags & (O_CREAT | O_EXCL))
3100         {
3101
3102             result = -EEXIST;
3103         }
3104         else
3105             if (!strcmp(attr.type, TYPE_DIR) && (fi->flags & (O_WRONLY | O_RDWR)))
3106             {
3107
3108                 result = -EISDIR;
3109             }
3110     }
3111     else
3112         if (r == SQLITE_BUSY)
3113             result = -EBUSY;
3114         else
3115             /* does not exist */
3116             if ((fi->flags & O_CREAT) == 0)
3117                 result = - ENOENT ;
3118     if ((result == 0) && (fi->flags & O_CREAT))
3119     {
3120         attr.mode = get_sqlfs(sqlfs)->default_mode; /* to use some kind of default */
3121 #ifdef FUSE
3122 #ifdef ENABLE_DAC
3123                 attr.uid = fuse_get_context()->uid;
3124                 attr.gid = fuse_get_context()->gid;
3125                 /* printf("[%s:%d]attr.uid = %d, attr.gid = %d\n", __FILE__, __LINE__, attr.uid, attr.gid); */
3126 #else
3127         attr.uid = geteuid();
3128         attr.gid = getegid();
3129 #endif
3130 #else
3131         attr.uid = get_sqlfs(sqlfs)->uid;
3132         attr.gid = get_sqlfs(sqlfs)->gid;
3133
3134 #endif
3135         if (attr.path == 0)
3136         {
3137             attr.path = strndup(path,strlen(path));
3138             assert(attr.path != NULL);
3139             attr.inode = get_new_inode();
3140         }
3141         if (attr.type == 0){
3142             attr.type = strndup(TYPE_BLOB,strlen(TYPE_BLOB));
3143             assert(attr.type != NULL);
3144         }
3145         r = set_attr(get_sqlfs(sqlfs), path, &attr);
3146         if (r == SQLITE_BUSY)
3147             result = -EBUSY;
3148         else
3149             if (r != SQLITE_OK)
3150                 result = -EACCES;
3151     }
3152     clean_attr(&attr);
3153     COMPLETE(1)
3154     return result;
3155 }
3156
3157 int sqlfs_proc_read(sqlfs_t *sqlfs, const char *path, char *buf, size_t size, off_t offset, struct
3158                     fuse_file_info *fi)
3159 {
3160     int i, r, result = 0;
3161     int64_t length = size;
3162     key_value value = { 0, 0, 0 };
3163
3164     BEGIN
3165     CHECK_PARENT_PATH(path)
3166     CHECK_READ(path)
3167
3168 // baik - libc 가 기본??으???open??에 getattr ?????해 처리??다. libc 가 ??처리??다.
3169 #ifndef SQLFS_FAST_TUNNING
3170     if (i = key_is_dir(get_sqlfs(sqlfs), path), (i == 1))
3171     {
3172         COMPLETE(1)
3173         return -EISDIR;
3174     }
3175     else if (i == 2)
3176     {
3177         COMPLETE(1)
3178         return -EBUSY;
3179     }
3180 #endif
3181
3182     /*if (fi)
3183     if ((fi->flags & (O_RDONLY | O_RDWR)) == 0)
3184         return - EBADF;*/
3185
3186     r = get_value(get_sqlfs(sqlfs), path, &value, offset, offset + size);
3187     if (r != SQLITE_OK)
3188     {
3189         result = -EIO;
3190     }
3191     else if ((size_t) offset > value.size) /* nothing to read */
3192         result = 0;
3193     else
3194     {
3195         if (length > (int64_t) value.size - offset)
3196             length = (int64_t) value.size - offset;
3197         if (length < 0)
3198             length = 0;
3199         if (length > 0)
3200         {
3201             memcpy(buf, ((char*)value.data) + offset,  length);
3202         }
3203         result = length;
3204     }
3205     clean_value(&value);
3206     COMPLETE(1)
3207     return result;
3208 }
3209
3210 int sqlfs_proc_write(sqlfs_t *sqlfs, const char *path, const char *buf, size_t size, off_t offset,
3211                      struct fuse_file_info *fi)
3212 {
3213     int i, r, result = 0;
3214     char *data;
3215     size_t length = size, orig_size = 0;
3216     key_value value = { 0, 0, 0 };
3217
3218     BEGIN
3219
3220 // baik - libc 가 기본??으???open??에 getattr ?????해 처리??다. libc 가 ??처리??다.
3221 #ifndef SQLFS_FAST_TUNNING
3222     if (i = key_is_dir(get_sqlfs(sqlfs), path), (i == 1))
3223     {
3224         COMPLETE(1)
3225         return -EISDIR;
3226     }
3227     else if (i == 2)
3228     {
3229         COMPLETE(1)
3230         return -EBUSY;
3231     }
3232 #endif
3233
3234     /*if (fi)
3235     if ((fi->flags & (O_WRONLY | O_RDWR)) == 0)
3236         return - EBADF;*/
3237
3238     if ((i = key_exists(get_sqlfs(sqlfs), path, &orig_size) == 0), (i == 1))
3239     {
3240         key_attr attr = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
3241         CHECK_PARENT_WRITE(path)
3242         attr.path = strndup(path,strlen(path));
3243         assert(attr.path != NULL);
3244         attr.type = strndup(TYPE_BLOB,strlen(TYPE_BLOB));
3245         assert(attr.path != NULL);
3246         attr.mode = get_sqlfs(sqlfs)->default_mode; /* use default mode */
3247 #ifdef FUSE
3248 #ifdef ENABLE_DAC
3249                 attr.uid = fuse_get_context()->uid;
3250                 attr.gid = fuse_get_context()->gid;
3251                 /* printf("[%s:%d]attr.uid = %d, attr.gid = %d\n", __FILE__, __LINE__, attr.uid, attr.gid); */
3252 #else
3253         attr.uid = geteuid();
3254         attr.gid = getegid();
3255 #endif
3256 #else
3257         attr.uid = get_sqlfs(sqlfs)->uid;
3258         attr.gid = get_sqlfs(sqlfs)->gid;
3259
3260 #endif
3261         attr.inode = get_new_inode();
3262         r = set_attr(get_sqlfs(sqlfs), path, &attr);
3263         if (r != SQLITE_OK)
3264             result = -EIO;
3265         clean_attr(&attr);
3266         clean_value(&value);
3267     }
3268     else if (i == 2)
3269     {
3270         result = -EBUSY;
3271     }
3272     else
3273     {
3274         CHECK_PARENT_PATH(path)
3275         CHECK_WRITE(path)
3276     }
3277     if (result == 0)
3278     {
3279         if (orig_size)
3280         {
3281             value.data = calloc(orig_size, sizeof(char));
3282             value.size = orig_size;
3283         }
3284         if (length > value.size - offset)
3285         {
3286             data = realloc(value.data, offset + length);
3287             if (!data)
3288                 result = -EFBIG;
3289             else
3290             {
3291                 memset(data + value.size, 0, offset + length - value.size);
3292                 value.data = data;
3293                 value.size = offset + length;
3294             }
3295         }
3296         if (result == 0)
3297         {
3298             memcpy(value.data + offset, buf, length);
3299
3300             result = length;
3301         }
3302
3303         if ((size_t) offset > orig_size)
3304         {
3305             length += offset - orig_size;
3306             offset = orig_size; /* fill in the hole */
3307         }
3308         r = set_value(get_sqlfs(sqlfs), path, &value, offset, offset + length);
3309         if (r != SQLITE_OK)
3310             result = -EIO;
3311     }
3312     clean_value(&value);
3313     COMPLETE(1)
3314     return result;
3315 }
3316
3317 int sqlfs_proc_statfs(sqlfs_t *sqlfs, const char *path, struct statvfs *stbuf)
3318 {
3319     /* file system information not supported as we have no idea how
3320     to map that to a SQLite file */
3321     return -ENOSYS;
3322 }
3323
3324 int sqlfs_proc_release(sqlfs_t *sqlfs, const char *path, struct fuse_file_info *fi)
3325 {
3326     /* no operation */
3327     return 0;
3328 }
3329
3330 int sqlfs_proc_fsync(sqlfs_t *sqlfs, const char *path, int isfdatasync, struct fuse_file_info *fi)
3331 {
3332     sync(); /* just to sync everything */
3333     return 0;
3334 }
3335
3336 int g_full_db_transactioning = 0;
3337 pid_t g_transaction_pid = 0;
3338
3339 typedef enum {XATTR_NS_USER=0, XATTR_NS_SECURITY, XATTR_NS_SYSTEM, XATTR_NS_TRUSTED, XATTR_NS_INVALID} xattr_ns_t;
3340 static const char *validNS[] = {"user", "security", "system", "trusted"}; //man 5 attr
3341
3342
3343 /**
3344  * @param name must be NULL-terminated
3345  */
3346 static xattr_ns_t xattr_namespace(const char *name)
3347 {
3348         const char *dot = strchr(name, '.');
3349         if(!dot){
3350                 return XATTR_NS_INVALID;
3351         }
3352         int len = dot - name;
3353         int numValidNS = sizeof(validNS)/sizeof(validNS[0]);
3354         int i;
3355         for(i = 0; i < numValidNS; i++){
3356                 if(strncmp(name, validNS[i], len) == 0){
3357                         return i;
3358                 }
3359         }
3360         return XATTR_NS_INVALID;
3361 }
3362
3363 /**
3364  * @param namespace need not be null-terminated
3365  */
3366 static bool is_valid_xattr_namespace(const char *namespace, int len)
3367 {
3368         int numValidNS = sizeof(validNS)/sizeof(validNS[0]);
3369         int i;
3370         for(i = 0; i < numValidNS; i++){
3371                 if(strncmp(namespace, validNS[i], len) == 0){
3372                         return true;
3373                 }
3374         }
3375         return false;
3376 }
3377
3378 static bool has_cap(cap_value_t cap)
3379 {
3380         pid_t pid = fuse_get_context()->pid;
3381         cap_t capt = cap_get_pid(pid);
3382         cap_flag_value_t set = 0;
3383         int r = cap_get_flag(capt, cap, CAP_EFFECTIVE, &set);
3384         assert(r == 0);
3385         cap_free(capt);
3386         return (bool)set;
3387 }
3388
3389 static bool is_special_setxattr_use(const char* str)
3390 {
3391         static const char *cmds[] = {
3392                 "full_db_transaction_check",
3393                 "full_db_transaction_start",
3394                 "full_db_transaction_stop",
3395                 "full_db_transaction_rb" };
3396         int i;
3397         int numCmds = sizeof(cmds)/sizeof(cmds[0]);
3398         for(i = 0; i < numCmds; i++){
3399                 if(strcmp(str, cmds[i]) == 0){
3400                         return true;
3401                 }
3402         }
3403         return false;
3404 }
3405
3406 int sqlfs_proc_setxattr(sqlfs_t *sqlfs, const char *path, const char *name, const void *value,
3407                         size_t size, int flags)
3408 {
3409         const char *dot;
3410         if((dot = strchr(name,'.'))){
3411                 if(*(dot+1)==0){
3412                         // xyz.
3413                         return -EINVAL;
3414                 }
3415                 if(!is_valid_xattr_namespace(name, dot - name)){
3416                         return -ENOTSUP;
3417                 }
3418                 int r;
3419                 int result = 0;
3420                 const char *tail;
3421                 sqlite3_stmt *stmt;
3422                 BEGIN;
3423                 CHECK_PARENT_PATH(path)
3424                 CHECK_WRITE(path)
3425                 static const char *cmd = "insert or replace into xattr_data (key,xattr_name,xattr_value) VALUES(:key, :name, :value)";
3426                 static const char *cmd_select = "select key from xattr_data where key=:key and xattr_name=:name";
3427                 if(flags){
3428 #undef INDEX
3429 #define INDEX 36
3430                         SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd_select, -1, &stmt,  &tail);
3431                         if (r != SQLITE_OK)
3432                         {
3433                                 show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
3434                                 COMPLETE(1);
3435                                 return -EIO;
3436                         }
3437                         sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC);
3438                         sqlite3_bind_text(stmt, 2, name, -1, SQLITE_STATIC);
3439                         r = sql_step(stmt);
3440                         sqlite3_reset(stmt);
3441                         if(r == SQLITE_ROW){
3442                                 if(flags == XATTR_CREATE){
3443                                         COMPLETE(1);
3444                                         return -EEXIST;
3445                                 }
3446                         }else if(r == SQLITE_DONE){
3447                                 if(flags == XATTR_REPLACE){
3448                                         COMPLETE(1);
3449                                         return -ENOATTR;
3450                                 }
3451                         }else{
3452                                 COMPLETE(1);
3453                                 show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
3454                                 return -EIO;
3455                         }
3456                 }
3457 #undef INDEX
3458 #define INDEX 32
3459                         
3460                 SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1, &stmt,  &tail);
3461                 if (r != SQLITE_OK)
3462                 {
3463                         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
3464                         COMPLETE(1);
3465                         return -EIO;
3466                 }
3467                 sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC);
3468                 sqlite3_bind_text(stmt, 2, name, -1, SQLITE_STATIC);
3469                 sqlite3_bind_blob(stmt, 3, value, size, SQLITE_STATIC);
3470                 r = sql_step(stmt);
3471                 if (r != SQLITE_DONE)
3472                 {
3473                         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
3474                 }
3475
3476                 sqlite3_reset(stmt);
3477                 COMPLETE(1)
3478                 return 0;
3479         }else if(is_special_setxattr_use(name)){
3480         pid_t pid;
3481         char temp[20];
3482         char* temp_value;
3483         int i;
3484
3485         // alignment problem
3486         // pid = (pid_t*)value;
3487         temp_value = (char*)&pid;
3488         for(i=0; i<sizeof(pid); i++)
3489                 *(temp_value+i) = *((char*)(value+i));
3490
3491         // db_transaction 을 걸고, Process 가 죽었을 경우. lock 을 풀어주어야 한다.
3492         // TODO: timeout check
3493         if(g_full_db_transactioning)
3494         {
3495                 if(g_transaction_pid != pid)
3496                 {
3497                         sprintf(temp,"/proc/%d",g_transaction_pid);
3498                         if(access(temp,F_OK)==-1)
3499                         {
3500                                 fprintf(stderr,"[NOTE]db_transaction owner maybe died\n");
3501                                 commit_transaction(get_sqlfs(sqlfs),0);                 
3502                                 g_full_db_transactioning = 0;
3503                                 g_transaction_pid = 0;
3504                         }
3505                 }
3506         }
3507
3508         if(strcmp(name,"full_db_transaction_check")==0)
3509         {
3510                 return 0;
3511         }
3512
3513         if(strcmp(name,"full_db_transaction_start")==0)
3514         {
3515                 if(g_full_db_transactioning==0)
3516                 {
3517                         g_full_db_transactioning = 1;
3518                         g_transaction_pid = pid;
3519                         begin_transaction(get_sqlfs(sqlfs));
3520                         return 0;
3521                 }
3522                 else
3523                 {
3524                         if(g_transaction_pid != pid)
3525                         {
3526                                 fprintf(stderr,"[NOTE]someone have full_db_transaction\n");
3527                                 return -EEXIST;
3528                         }
3529                         else
3530                         {
3531                                 fprintf(stderr,"[NOTE]relock... check\n");
3532                                 return -EEXIST;
3533                         }
3534                 }
3535         }
3536         else if(strcmp(name,"full_db_transaction_stop")==0)
3537         {
3538                 if(g_full_db_transactioning==1)
3539                 {
3540                         commit_transaction(get_sqlfs(sqlfs),1);
3541                         g_full_db_transactioning = 0;
3542                         g_transaction_pid = 0;
3543                         return 0;
3544                 }
3545         }
3546         else if(strcmp(name,"full_db_transaction_rb")==0)
3547         {
3548                 if(g_full_db_transactioning==1)
3549                 {
3550                         commit_transaction(get_sqlfs(sqlfs),0);
3551                         g_full_db_transactioning = 0;
3552                         g_transaction_pid = 0;
3553                         return 0;
3554                 }
3555         }
3556         }else{
3557                 return -ENOTSUP;
3558         }
3559 }
3560
3561 #undef INDEX
3562 #define INDEX 33
3563 int sqlfs_proc_getxattr(sqlfs_t *sqlfs, const char *path, const char *name, char *value, size_t size)
3564 {
3565         int r;
3566         static const char *cmd = "select xattr_value from xattr_data where key = :key and xattr_name = :name";
3567         const char *tail;
3568         int result;
3569         int bytes = 0;
3570         sqlite3_stmt *stmt;
3571         BEGIN
3572         SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1, &stmt,  &tail);
3573         if (r != SQLITE_OK)
3574         {
3575                 show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
3576                 COMPLETE(1)
3577                 return r;
3578         }
3579         sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC);
3580         sqlite3_bind_text(stmt, 2, name, -1, SQLITE_STATIC);
3581         r = sql_step(stmt);
3582         if (r == SQLITE_DONE){
3583                 result = -ENOATTR;
3584         }else if(r == SQLITE_ROW){
3585                 const void *attr_value = sqlite3_column_blob(stmt, 0);
3586                 bytes = sqlite3_column_bytes(stmt, 0);
3587                 if(value){
3588                         if(size >= bytes){
3589                                 memcpy(value, attr_value, bytes);
3590                         }else{
3591                                 result = -ERANGE;
3592                                 goto ret;
3593                         }
3594                 }
3595                 result = bytes;
3596         }else{
3597                 show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
3598         }
3599 ret:
3600         sqlite3_reset(stmt);
3601         COMPLETE(1)
3602         return result;
3603 }
3604
3605 #undef INDEX
3606 #define INDEX 34
3607 int sqlfs_proc_listxattr(sqlfs_t *sqlfs, const char *path, char *list, size_t size)
3608 {
3609         int r;
3610         static const char *cmd = "select xattr_name from xattr_data where key = :key";
3611         const char *tail;
3612         sqlite3_stmt *stmt;
3613         BEGIN
3614         SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1, &stmt,  &tail);
3615         if (r != SQLITE_OK)
3616         {
3617                 show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
3618                 COMPLETE(1)
3619                 return r;
3620         }
3621         sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC);
3622         bool sysAdminCap = has_cap(CAP_SYS_ADMIN);
3623         int bytes = 0;
3624         while((r = sql_step(stmt)) == SQLITE_ROW){
3625                 const unsigned char *name = sqlite3_column_text(stmt, 0);
3626                 int n = sqlite3_column_bytes(stmt, 0);
3627                 if(!sysAdminCap && xattr_namespace(name) == XATTR_NS_TRUSTED){
3628                         continue;
3629                 }
3630                 if(list){
3631                         strncpy(list, name, size);
3632                         size -= n+1;
3633                         if(size < 0){
3634                                 bytes= -ERANGE;
3635                                 break;
3636                         }
3637                         list += n+1;
3638                 }
3639                 bytes += n+1;
3640         }
3641         if (r != SQLITE_DONE)
3642         {
3643                 show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
3644         }
3645
3646         sqlite3_reset(stmt);
3647         COMPLETE(1)
3648         return bytes;
3649 }
3650
3651 int sqlfs_proc_removexattr(sqlfs_t *sqlfs, const char *path, const char *name)
3652 {
3653         int r;
3654         const char *tail;
3655         sqlite3_stmt *stmt;
3656 #undef INDEX
3657 #define INDEX 36
3658         static const char *cmd_select = "select key from xattr_data where key=:key and xattr_name=:name";
3659         SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd_select, -1, &stmt,  &tail);
3660         if (r != SQLITE_OK)
3661         {
3662                 show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
3663                 return -EIO;
3664         }
3665         sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC);
3666         sqlite3_bind_text(stmt, 2, name, -1, SQLITE_STATIC);
3667         r = sql_step(stmt);
3668         sqlite3_reset(stmt);
3669         if(r != SQLITE_ROW){
3670                 //key,name pair doesn't exist in database
3671                 return -ENOATTR;
3672         }
3673 #undef INDEX
3674 #define INDEX 37
3675         static const char *cmd = "delete from xattr_data where key=:key and xattr_name=:name";
3676         SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1, &stmt,  &tail);
3677         if (r != SQLITE_OK)
3678         {
3679                 show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
3680                 return -EIO;
3681         }
3682         sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC);
3683         sqlite3_bind_text(stmt, 2, name, -1, SQLITE_STATIC);
3684         r = sql_step(stmt);
3685         sqlite3_reset(stmt);
3686         if(r != SQLITE_DONE){
3687                 return -EIO;
3688         }
3689         return 0;
3690 }
3691
3692
3693 int sqlfs_del_tree(sqlfs_t *sqlfs, const char *key)
3694 {
3695     int i, result = 0;
3696     BEGIN
3697     CHECK_PARENT_WRITE(key)
3698     CHECK_DIR_WRITE(key)
3699
3700     if ((i = key_exists(get_sqlfs(sqlfs), key, 0)), (i == 0))
3701         result = -ENOENT;
3702     else if (i == 2)
3703         result = -EBUSY;
3704
3705     if (result == 0)
3706     {
3707         if (SQLITE_OK == remove_key_subtree(get_sqlfs(sqlfs), key))
3708             result = 0;
3709         else
3710             result = -EIO;
3711     }
3712     COMPLETE(1)
3713     return result;
3714 }
3715
3716
3717 int sqlfs_del_tree_with_exclusion(sqlfs_t *sqlfs, const char *key, const char *exclusion_pattern)
3718 {
3719     int i, result = 0;
3720     BEGIN
3721     CHECK_PARENT_WRITE(key)
3722     CHECK_DIR_WRITE(key)
3723
3724     if ((i = key_exists(get_sqlfs(sqlfs), key, 0)) == 0)
3725         result = -ENOENT;
3726     else if (i == 2)
3727         result = -EBUSY;
3728
3729     if (result == 0)
3730     {
3731         if (SQLITE_OK == remove_key_subtree_with_exclusion(get_sqlfs(sqlfs), key, exclusion_pattern))
3732             result = 0;
3733         else
3734             result = -EIO;
3735     }
3736     COMPLETE(1)
3737     return result;
3738 }
3739
3740
3741
3742 int sqlfs_get_value(sqlfs_t *sqlfs, const char *key, key_value *value,
3743                     size_t begin, size_t end)
3744 {
3745     int r = SQLITE_OK;
3746     BEGIN
3747     if (check_parent_access(sqlfs, key) != 0)
3748         r = SQLITE_ERROR;
3749     else
3750         if (sqlfs_proc_access(sqlfs, key, R_OK | F_OK) != 0)
3751             r = SQLITE_ERROR;
3752         else
3753             r = get_value(get_sqlfs(sqlfs), key, value, begin, end);
3754
3755     COMPLETE(1)
3756     if (r == SQLITE_NOTFOUND)
3757         return -1;
3758     return SQLITE_OK == r;
3759 }
3760
3761 int sqlfs_set_value(sqlfs_t *sqlfs, const char *key, const key_value *value,
3762                     size_t begin,  size_t end)
3763 {
3764     int r = SQLITE_OK;
3765     BEGIN
3766     if (check_parent_access(sqlfs, key) != 0)
3767         r = SQLITE_ERROR;
3768     else
3769         if (sqlfs_proc_access(sqlfs, key, W_OK | F_OK) != 0)
3770             r = SQLITE_ERROR;
3771         else
3772             r = set_value(get_sqlfs(sqlfs), key, value, begin, end);
3773     COMPLETE(1)
3774     return SQLITE_OK == r;
3775 }
3776
3777 int sqlfs_get_attr(sqlfs_t *sqlfs, const char *key, key_attr *attr)
3778 {
3779     int i, r = 1;
3780     BEGIN
3781     if ((i = check_parent_access(sqlfs, key)) != 0)
3782     {
3783         if (i == -ENOENT)
3784             r = -1;
3785         else if (i == -EACCES)
3786             r = -2;
3787         else r = -1;
3788     }
3789     else
3790         if ((i = sqlfs_proc_access(sqlfs, key, R_OK | F_OK)) != 0)
3791         {
3792             if (i == -ENOENT)
3793                 r = -1;
3794             else if (i == -EACCES)
3795                 r = -2;
3796             else r = -1;
3797         }
3798         else
3799         {
3800             i = get_attr(get_sqlfs(sqlfs), key, attr);
3801             if (i == SQLITE_OK)
3802                 r = 1;
3803             else if (i == SQLITE_NOTFOUND)
3804                 r = -1;
3805         }
3806     COMPLETE(1)
3807 //fprintf(stderr, "return %d on %s\n", r, key);//???
3808     return r;
3809
3810 }
3811
3812 int sqlfs_set_attr(sqlfs_t *sqlfs, const char *key, const key_attr *attr)
3813 {
3814     int r = SQLITE_OK;
3815
3816     BEGIN
3817     if (check_parent_access(sqlfs, key) != 0)
3818         r = SQLITE_ERROR;
3819     else
3820         if (sqlfs_proc_access(sqlfs, key, W_OK | F_OK) != 0)
3821             r = SQLITE_ERROR;
3822         else
3823             r = set_attr(get_sqlfs(sqlfs), key, attr);
3824
3825     COMPLETE(1)
3826     return SQLITE_OK == r;
3827 }
3828
3829 int sqlfs_begin_transaction(sqlfs_t *sqlfs)
3830 {
3831     int r = SQLITE_OK;
3832     r = begin_transaction(get_sqlfs(sqlfs));
3833     if (r == SQLITE_BUSY)
3834         return 2;
3835     return SQLITE_OK == r;
3836 }
3837
3838
3839 int sqlfs_complete_transaction(sqlfs_t *sqlfs, int i)
3840 {
3841     int r = SQLITE_OK;
3842     r = commit_transaction(get_sqlfs(sqlfs), i);
3843     if (r == SQLITE_BUSY)
3844         return 2;
3845
3846     return SQLITE_OK == r;
3847 }
3848
3849
3850 int sqlfs_break_transaction(sqlfs_t *sqlfs)
3851 {
3852     int r;
3853     r = break_transaction(sqlfs, 0);
3854     if (r == SQLITE_BUSY)
3855         return 2;
3856     return SQLITE_OK == r;
3857 }
3858
3859
3860 int sqlfs_set_type(sqlfs_t *sqlfs, const char *key, const char *type)
3861 {
3862     int r = SQLITE_DONE;
3863     BEGIN
3864     if (check_parent_access(sqlfs, key) != 0)
3865         r = SQLITE_ERROR;
3866     else
3867         if (sqlfs_proc_access(sqlfs, key, W_OK | F_OK) != 0)
3868             r = SQLITE_ERROR;
3869         else
3870             r = key_set_type(get_sqlfs(sqlfs), key, type);
3871
3872     COMPLETE(1)
3873     if (r == SQLITE_BUSY)
3874         return 2;
3875     return (r == SQLITE_DONE);
3876 }
3877
3878
3879
3880 #undef INDEX
3881 #define INDEX 31
3882
3883 int sqlfs_list_keys(sqlfs_t *sqlfs, const char *pattern, void *buf, fuse_fill_dir_t filler)
3884 {
3885     int r, result = 0;
3886     const char *tail;
3887     const char *t;
3888     static const char *cmd = "select key, mode from meta_data where key glob :pattern; ";
3889     char tmp[PATH_MAX];
3890     char *lpath;
3891     sqlite3_stmt *stmt;
3892     BEGIN
3893
3894     lpath = strndup(pattern,strlen(pattern));
3895     assert(lpath != NULL);;
3896     remove_tail_slash(lpath);
3897
3898     snprintf(tmp, sizeof(tmp), "%s", pattern);
3899
3900     SQLITE3_PREPARE(get_sqlfs(sqlfs)->db, cmd, -1, &stmt,  &tail);
3901     if (r != SQLITE_OK)
3902     {
3903         show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
3904
3905         result = -EACCES;
3906     }
3907     if (result == 0)
3908     {
3909         sqlite3_bind_text(stmt, 1, tmp, -1, SQLITE_STATIC);
3910
3911         while (1)
3912         {
3913             r = sql_step(stmt);
3914             if (r == SQLITE_ROW)
3915             {
3916                 t = sqlite3_column_text(stmt, 0);
3917                 if (filler(buf, t, NULL, 0))
3918                     break;
3919             }
3920             else if (r == SQLITE_DONE)
3921             {
3922                 break;
3923             }
3924             else if (r == SQLITE_BUSY)
3925             {
3926                 result = -EBUSY;
3927                 break;
3928             }
3929             else
3930             {
3931                 show_msg(stderr, "%s\n", sqlite3_errmsg(get_sqlfs(sqlfs)->db));
3932                 result = -EACCES;
3933                 break;
3934             }
3935         }
3936         sqlite3_reset(stmt);
3937     }
3938     COMPLETE(1)
3939     free(lpath);
3940     return result;
3941 }
3942
3943 int sqlfs_is_dir(sqlfs_t *sqlfs, const char *key)
3944 {
3945     return key_is_dir(sqlfs, key);
3946 }
3947
3948
3949 static int create_db_table(sqlfs_t *sqlfs)
3950 {  /* ensure tables are created if not existing already
3951                   if already exist, command results ignored so no effects */
3952     static const char *cmd1 =
3953         " CREATE TABLE meta_data(key text, type text, inode integer, uid integer, gid integer, mode integer,"
3954         "acl text, attribute text, atime integer, mtime integer, ctime integer, size integer,"
3955         "block_size integer, primary key (key), unique(key))" ;
3956     static const char *cmd2 =
3957         " CREATE TABLE value_data (key text, block_no integer, data_block blob, unique(key, block_no))";
3958         static const char *cmd3 = "CREATE TABLE xattr_data (key text, xattr_name text, xattr_value blob, unique(key, xattr_name))";
3959     static const char *cmd4 = "create index meta_index on meta_data (key);";
3960
3961     sqlite3_exec(get_sqlfs(sqlfs)->db, cmd1, NULL, NULL, NULL);
3962     sqlite3_exec(get_sqlfs(sqlfs)->db, cmd2, NULL, NULL, NULL);
3963     sqlite3_exec(get_sqlfs(sqlfs)->db, cmd3, NULL, NULL, NULL);
3964     sqlite3_exec(get_sqlfs(sqlfs)->db, cmd4, NULL, NULL, NULL);
3965     return 1;
3966 }
3967
3968
3969
3970 static void * sqlfs_t_init(const char *db_file)
3971 {
3972     int i, r;
3973     sqlfs_t *sql_fs = calloc(1, sizeof(*sql_fs));
3974     assert(sql_fs);
3975     for (i = 0; i < (int)(sizeof(sql_fs->stmts) / sizeof(sql_fs->stmts[0])); i++)
3976     {
3977         sql_fs->stmts[i] = 0;
3978     }
3979     r = sqlite3_open(db_file, &(sql_fs->db));
3980     if (r != SQLITE_OK)
3981     {
3982         fprintf(stderr, "Cannot open the database file %s\n", db_file);
3983         return 0;
3984     }
3985
3986     sql_fs->default_mode = 0700; /* allows the creation of children under / , default user at initialization is 0 (root)*/
3987
3988     create_db_table( sql_fs);
3989
3990     if (max_inode == 0)
3991         max_inode = get_current_max_inode(sql_fs);
3992
3993     /*sqlite3_busy_timeout( sql_fs->db, 500); *//* default timeout 0.5 seconds */
3994     sqlite3_exec(sql_fs->db, "PRAGMA synchronous = FULL;", NULL, NULL, NULL);
3995     sqlite3_exec(sql_fs->db, "PRAGMA journal_mode = persist;", NULL, NULL, NULL);
3996     ensure_existence(sql_fs, "/", TYPE_DIR);
3997     return (void *) sql_fs;
3998 }
3999
4000
4001
4002 static void sqlfs_t_finalize(void *arg)
4003 {
4004     int i;
4005     sqlfs_t *sql_fs = (sqlfs_t *) arg;
4006     if (sql_fs)
4007     {
4008         for (i = 0; i < (int)(sizeof(sql_fs->stmts) / sizeof(sql_fs->stmts[0])); i++)
4009         {
4010             if (sql_fs->stmts[i])
4011                 sqlite3_finalize(sql_fs->stmts[i]);
4012         }
4013         sqlite3_close(sql_fs->db);
4014         free(sql_fs);
4015     }
4016
4017 }
4018
4019
4020 int sqlfs_open(const char *db_file, sqlfs_t **sqlfs)
4021 {
4022     if (db_file == 0)
4023         db_file = default_db_file;
4024     *sqlfs = sqlfs_t_init(db_file);
4025     if (!*sqlfs)
4026         return 0;
4027     return 1;
4028 }
4029
4030 int sqlfs_close(sqlfs_t *sqlfs)
4031 {
4032
4033     sqlfs_t_finalize(sqlfs);
4034     return 1;
4035 }
4036
4037
4038 #ifdef FUSE
4039
4040
4041 static int sqlfs_op_getattr(const char *path, struct stat *stbuf)
4042 {
4043     return sqlfs_proc_getattr(0, path, stbuf);
4044 }
4045
4046 static int sqlfs_op_access(const char *path, int mask)
4047 {
4048     return sqlfs_proc_access(0, path, mask);
4049 }
4050 static int sqlfs_op_readlink(const char *path, char *buf, size_t size)
4051 {
4052     return sqlfs_proc_readlink(0, path, buf, size);
4053 }
4054 static int sqlfs_op_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
4055                             off_t offset, struct fuse_file_info *fi)
4056 {
4057     return sqlfs_proc_readdir(0, path, buf, filler, offset, fi);
4058 }
4059 static int sqlfs_op_mknod(const char *path, mode_t mode, dev_t rdev)
4060 {
4061     return sqlfs_proc_mknod(0, path, mode, rdev);
4062 }
4063 static int sqlfs_op_mkdir(const char *path, mode_t mode)
4064 {
4065     return sqlfs_proc_mkdir(0, path, mode);
4066 }
4067 static int sqlfs_op_unlink(const char *path)
4068 {
4069     return sqlfs_proc_unlink(0, path);
4070 }
4071 static int sqlfs_op_rmdir(const char *path)
4072 {
4073     return sqlfs_proc_rmdir(0, path);
4074 }
4075 static int sqlfs_op_symlink(const char *path, const char *to)
4076 {
4077     return sqlfs_proc_symlink(0, path, to);
4078 }
4079 static int sqlfs_op_rename(const char *from, const char *to)
4080 {
4081     return sqlfs_proc_rename(0, from, to);
4082 }
4083 static int sqlfs_op_link(const char *from, const char *to)
4084 {
4085     return sqlfs_proc_link(0, from, to);
4086 }
4087 static int sqlfs_op_chmod(const char *path, mode_t mode)
4088 {
4089     return sqlfs_proc_chmod(0, path, mode);
4090 }
4091 static int sqlfs_op_chown(const char *path, uid_t uid, gid_t gid)
4092 {
4093     return sqlfs_proc_chown(0, path, uid, gid);
4094 }
4095 static int sqlfs_op_truncate(const char *path, off_t size)
4096 {
4097     return sqlfs_proc_truncate(0, path, size);
4098 }
4099 static int sqlfs_op_utime(const char *path, struct utimbuf *buf)
4100 {
4101     return sqlfs_proc_utime(0, path, buf);
4102 }
4103 int sqlfs_op_create(const char *path, mode_t mode, struct fuse_file_info *fi)
4104 {
4105     return sqlfs_proc_create(0, path, mode, fi);
4106 }
4107
4108 static int sqlfs_op_open(const char *path, struct fuse_file_info *fi)
4109 {
4110     return sqlfs_proc_open(0, path, fi);
4111 }
4112 static int sqlfs_op_read(const char *path, char *buf, size_t size, off_t offset, struct
4113                          fuse_file_info *fi)
4114 {
4115     return sqlfs_proc_read(0, path, buf, size, offset, fi);
4116 }
4117 static int sqlfs_op_write(const char *path, const char *buf, size_t size, off_t offset,
4118                           struct fuse_file_info *fi)
4119 {
4120     return sqlfs_proc_write(0, path, buf, size, offset, fi);
4121 }
4122 static int sqlfs_op_statfs(const char *path, struct statvfs *stbuf)
4123 {
4124     return sqlfs_proc_statfs(0, path, stbuf);
4125 }
4126 static int sqlfs_op_release(const char *path, struct fuse_file_info *fi)
4127 {
4128     return sqlfs_proc_release(0, path, fi);
4129 }
4130 static int sqlfs_op_fsync(const char *path, int isfdatasync, struct fuse_file_info *fi)
4131 {
4132     return sqlfs_proc_fsync(0, path, isfdatasync, fi);
4133 }
4134 static int sqlfs_op_setxattr(const char *path, const char *name, const char *value,
4135                              size_t size, int flags)
4136 {
4137     return sqlfs_proc_setxattr(0, path, name, value, size, flags);
4138 }
4139 static int sqlfs_op_getxattr(const char *path, const char *name, char *value, size_t size)
4140 {
4141     return sqlfs_proc_getxattr(0, path, name, value, size);
4142 }
4143 static int sqlfs_op_listxattr(const char *path, char *list, size_t size)
4144 {
4145     return sqlfs_proc_listxattr(0, path, list, size);
4146 }
4147 static int sqlfs_op_removexattr(const char *path, const char *name)
4148 {
4149     return sqlfs_proc_removexattr(0, path, name);
4150 }
4151
4152 static struct fuse_operations sqlfs_op;
4153
4154 #endif
4155
4156 int sqlfs_init(const char *db_file_name)
4157 {
4158 #ifdef FUSE
4159     sqlfs_op.getattr    = sqlfs_op_getattr;
4160     sqlfs_op.access     = sqlfs_op_access;
4161     sqlfs_op.readlink   = sqlfs_op_readlink;
4162     sqlfs_op.readdir    = sqlfs_op_readdir;
4163     sqlfs_op.mknod      = sqlfs_op_mknod;
4164     sqlfs_op.mkdir      = sqlfs_op_mkdir;
4165     sqlfs_op.symlink    = sqlfs_op_symlink;
4166     sqlfs_op.unlink     = sqlfs_op_unlink;
4167     sqlfs_op.rmdir      = sqlfs_op_rmdir;
4168     sqlfs_op.rename     = sqlfs_op_rename;
4169     sqlfs_op.link       = sqlfs_op_link;
4170     sqlfs_op.chmod      = sqlfs_op_chmod;
4171     sqlfs_op.chown      = sqlfs_op_chown;
4172     sqlfs_op.truncate   = sqlfs_op_truncate;
4173     sqlfs_op.utime      = sqlfs_op_utime;
4174     sqlfs_op.open       = sqlfs_op_open;
4175     sqlfs_op.create     = sqlfs_op_create;
4176     sqlfs_op.read       = sqlfs_op_read;
4177     sqlfs_op.write      = sqlfs_op_write;
4178     sqlfs_op.statfs     = sqlfs_op_statfs;
4179     sqlfs_op.release    = sqlfs_op_release;
4180     sqlfs_op.fsync      = sqlfs_op_fsync;
4181 #if 1 
4182
4183     sqlfs_op.setxattr   = sqlfs_op_setxattr;
4184     sqlfs_op.getxattr   = sqlfs_op_getxattr;
4185     sqlfs_op.listxattr  = sqlfs_op_listxattr;
4186     sqlfs_op.removexattr= sqlfs_op_removexattr;
4187 #endif
4188 #endif
4189
4190     if (db_file_name)
4191         strncpy(default_db_file, db_file_name, sizeof(default_db_file));
4192     pthread_key_create(&sql_key, sqlfs_t_finalize);
4193     return 0;
4194 }
4195
4196 #ifdef FUSE
4197
4198 int sqlfs_fuse_main(int argc, char **argv)
4199 {
4200
4201
4202     return fuse_main(argc, argv, &sqlfs_op);
4203 }
4204
4205 #endif