use larger string heap
[rrq/fuse_xattrs.git] / utils.c
1 /*
2   fuse_xattrs - Add xattrs support using sidecar files
3
4   Copyright (C) 2016  Felipe Barriga Richards <felipe {at} felipebarriga.cl>
5
6   This program can be distributed under the terms of the GNU GPL.
7   See the file COPYING.
8 */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <sys/stat.h>
14
15 #include "utils.h"
16 #include "fuse_xattrs_config.h"
17 #include "xattrs_config.h"
18 #include "stringmem.h"
19
20 /* TODO: re-use memory to avoid calling malloc every time */
21 char *prepend_source_directory(const char *b) {
22     return strjoin( xattrs_config.source_dir, b, 0 );
23 }
24
25 int is_directory(const char *path) {
26     struct stat statbuf;
27     if (stat(path, &statbuf) != 0) {
28         fprintf(stderr, "cannot get source directory status: %s\n", path);
29         return -1;
30     }
31
32     if (!S_ISDIR(statbuf.st_mode)) {
33         fprintf(stderr, "source directory must be a directory: %s\n", path);
34         return -1;
35     }
36
37     return 1;
38 }
39
40 int is_regular_file(const char *path) {
41     struct stat statbuf;
42     if (stat(path, &statbuf) != 0) {
43         return -1;
44     }
45
46     if (!S_ISREG(statbuf.st_mode)) {
47         return -1;
48     }
49
50     return 1;
51 }
52
53 char *get_sidecar_path(const char *path)
54 {
55 #define CFG xattrs_config
56     if ( strncmp( path, CFG.source_dir, CFG.source_dir_size ) == 0 ) {
57         const char *p = path + CFG.source_dir_size;
58         if ( CFG.sidecar_dir ) {
59             return strjoin( CFG.sidecar_dir, p, BINARY_SIDECAR_EXT, 0 );
60         }
61     }
62     return strjoin( path, BINARY_SIDECAR_EXT, 0 );
63 #undef CFG
64 }
65
66 // TODO: make it work for binary data
67 char *sanitize_value(const char *value, size_t value_size)
68 {
69     char *sanitized = malloc(value_size + 1);
70     memcpy(sanitized, value, value_size);
71     sanitized[value_size] = '\0';
72     return sanitized;
73 }
74
75
76 const size_t BINARY_SIDECAR_EXT_SIZE = strlen(BINARY_SIDECAR_EXT);
77
78 const int filename_is_sidecar(const char *string) {
79     if(string == NULL)
80         return 0;
81
82     size_t size = strlen(string);
83     if (size <= BINARY_SIDECAR_EXT_SIZE)
84         return 0;
85
86     if (memcmp(string+size-BINARY_SIDECAR_EXT_SIZE, BINARY_SIDECAR_EXT, BINARY_SIDECAR_EXT_SIZE) == 0) {
87         return 1;
88     }
89
90     return 0;
91 }
92
93 #define USER_NAMESPACE "user."
94 #define SYSTEM_NAMESPACE "system."
95 #define SECURITY_NAMESPACE "security."
96 #define TRUSTED_NAMESPACE "trusted."
97
98 const size_t USER_NAMESPACE_SIZE     = strlen(USER_NAMESPACE);
99 const size_t SYSTEM_NAMESPACE_SIZE   = strlen(SYSTEM_NAMESPACE);
100 const size_t SECURITY_NAMESPACE_SIZE = strlen(SECURITY_NAMESPACE);
101 const size_t THRUSTED_NAMESPACE_SIZE = strlen(TRUSTED_NAMESPACE);
102
103 enum namespace get_namespace(const char *name) {
104     size_t name_size = strlen(name);
105
106     if (name_size > USER_NAMESPACE_SIZE && memcmp(name, USER_NAMESPACE, USER_NAMESPACE_SIZE) == 0) {
107         return USER;
108     }
109
110     if (name_size > SYSTEM_NAMESPACE_SIZE && memcmp(name, SYSTEM_NAMESPACE, SYSTEM_NAMESPACE_SIZE) == 0) {
111         return SYSTEM;
112     }
113
114     if (name_size > SECURITY_NAMESPACE_SIZE && memcmp(name, SECURITY_NAMESPACE, SECURITY_NAMESPACE_SIZE) == 0) {
115         return SECURITY;
116     }
117
118     if (name_size > THRUSTED_NAMESPACE_SIZE && memcmp(name, TRUSTED_NAMESPACE, THRUSTED_NAMESPACE_SIZE) == 0) {
119         return TRUSTED;
120     }
121
122     error_print("invalid namespace for key: %s\n", name);
123     return ERROR;
124 }