-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfsfr_internal.c
184 lines (175 loc) · 6.06 KB
/
fsfr_internal.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
* fsfr_internal.c
*
* Copyright (c) 2010, Tyler Larson <[email protected]>
*
* This software is licensed under the terms of the MIT License.
* See the included file "LICENSE" for more information.
*
*/
#include "fsfr.h"
#include <dlfcn.h>
#include <stdlib.h>
/****************************************************************
* Internal helper functions
****************************************************************/
// fetch the "real" syscall for the provided function
void * fsfr_dlnext(const char *sym) {
//fprintf(stderr,"LOADING %s\n",sym);
void * rtn = dlsym(RTLD_NEXT,sym);
//fprintf(stderr,"SYM %s: %llu\n",sym,(long long unsigned int)rtn);
if (NULL==rtn) {
const char *err = dlerror();
if (err) {
fprintf(stderr,"Failed loading %s: %s\n",sym,dlerror());
} else {
//retry, but with "default" symbol instead
rtn = dlsym(RTLD_DEFAULT,sym);
if (NULL==rtn) fprintf(stderr,"Failed loading %s: (unknown error)\n",sym);
}
// not sure what would be a good generic error, since dlsym doesn't set errno
if (NULL==rtn) {
//fprintf(stderr,"Failed to load %s.",sym);
errno = EINVAL;
}
}
return rtn;
}
int fsfr_proxygetxattr_int(int64_t inode, const char *name)
{
char *proxy_dir = getenv("FSFR_PROXY_DIR");
if (!proxy_dir) return -1;
char fpath[PATH_MAX];
snprintf(fpath,PATH_MAX,"%s/%lli.fsfr",proxy_dir,(long long int) inode);
return fsfr_getxattr_int(fpath,name);
}
int fsfr_proxysetxattr_int(int64_t inode, const char *name, int64_t val)
{
char *proxy_dir = getenv("FSFR_PROXY_DIR");
if (!proxy_dir) return 0;
// fails silently if FSFR_PROXY_DIR is unset, as this extension
// is optional. This is a judgement call; if you don't like it, change
// 0 to -1 above.
char fpath[PATH_MAX];
snprintf(fpath,PATH_MAX,"%s/%lli.fsfr",proxy_dir,(long long int) inode);
struct stat st;
if (fsfr_base_stat(fpath,&st)) {
fsfr_base_open(fpath,O_WRONLY|O_CREAT|O_TRUNC,0644);
}
return fsfr_setxattr_int(fpath,name,val);
}
int fsfr_proxyunsetxattr_int(int64_t inode, const char *name)
{
char *proxy_dir = getenv("FSFR_PROXY_DIR");
if (!proxy_dir) return 0;
// Also fails silently. See note in fsfr_proxysetxattr_int
char fpath[PATH_MAX];
snprintf(fpath,PATH_MAX,"%s/%lli.fsfr",proxy_dir,(long long int) inode);
return fsfr_unset_attr(fpath,name);
}
// fsfr_Xgetxattr_int: Gets an integer stored in xattrs
// stored explicitly as int64 for cross-architecture safety and future-proofing
int fsfr_getxattr_int(const char *fpath, const char *name)
{
int64_t rtn = -1;
if (getxattr(fpath,name,&rtn,sizeof(rtn))>0) return (int) rtn;
return -1;
}
int fsfr_lgetxattr_int(const char *fpath, const char *name)
{
int64_t rtn = -1;
if (lgetxattr(fpath,name,&rtn,sizeof(rtn))>0) return (int) rtn;
return -1;
}
int fsfr_fgetxattr_int(int fd, const char *name)
{
int64_t rtn = -1;
if (fgetxattr(fd,name,&rtn,sizeof(rtn))>0) return (int) rtn;
return -1;
}
int fsfr_setxattr_int(const char *fpath, const char* name, int64_t val)
{
//fprintf(stderr,"%s: 0x%llx 0%llo\n",name,val,val);
return setxattr(fpath,name,&val,sizeof(val),0)?-errno:0;
}
int fsfr_fsetxattr_int(int fd, const char* name, int64_t val)
{
//fprintf(stderr,"%s: 0x%llx 0%llo\n",name,val,val);
return fsetxattr(fd,name,&val,sizeof(val),0)?-errno:0;
}
int fsfr_lsetxattr_int(const char *fpath, const char* name, int64_t val)
{
return lsetxattr(fpath,name,&val,sizeof(val),0)?-errno:0;
}
int fsfr_unset_attr(const char *fpath, const char* name)
{
return removexattr(fpath,name)?-errno:0;
}
int fsfr_funset_attr(int fd, const char* name)
{
return fremovexattr(fd,name)?-errno:0;
}
int fsfr_lunset_attr(const char *fpath, const char* name)
{
return lremovexattr(fpath,name)?-errno:0;
}
int fsfr_getxattr_int_stat(const char *fpath, const char *name, const struct stat *st)
{
if (S_ISLNK(st->st_mode)) return fsfr_proxygetxattr_int(st->st_ino,name);
return fsfr_getxattr_int(fpath,name);
}
int fsfr_lgetxattr_int_stat(const char *fpath, const char *name, const struct stat *st)
{
if (S_ISLNK(st->st_mode)) return fsfr_proxygetxattr_int(st->st_ino,name);
return fsfr_lgetxattr_int(fpath,name);
}
int fsfr_fgetxattr_int_stat(int fd, const char *name, const struct stat *st)
{
if (S_ISLNK(st->st_mode)) return fsfr_proxygetxattr_int(st->st_ino,name);
return fsfr_fgetxattr_int(fd,name);
}
int fsfr_setxattr_int_stat(const char *fpath, const char* name, int64_t val, const struct stat *st)
{
if (S_ISLNK(st->st_mode)) return fsfr_proxysetxattr_int(st->st_ino,name,val);
return fsfr_setxattr_int(fpath,name,val);
}
int fsfr_fsetxattr_int_stat(int fd, const char* name, int64_t val, const struct stat *st)
{
if (S_ISLNK(st->st_mode)) return fsfr_proxysetxattr_int(st->st_ino,name,val);
return fsfr_fsetxattr_int(fd,name,val);
}
int fsfr_lsetxattr_int_stat(const char *fpath, const char* name, int64_t val, const struct stat *st)
{
if (S_ISLNK(st->st_mode)) return fsfr_proxysetxattr_int(st->st_ino,name,val);
return fsfr_lsetxattr_int(fpath,name,val);
}
int fsfr_unset_attr_stat(const char *fpath, const char* name, const struct stat *st)
{
if (S_ISLNK(st->st_mode)) return fsfr_proxyunsetxattr_int(st->st_ino,name);
return fsfr_unset_attr(fpath,name);
}
int fsfr_funset_attr_stat(int fd, const char* name, const struct stat *st)
{
if (S_ISLNK(st->st_mode)) return fsfr_proxyunsetxattr_int(st->st_ino,name);
return fsfr_funset_attr(fd,name);
}
int fsfr_lunset_attr_stat(const char *fpath, const char* name, const struct stat *st)
{
if (S_ISLNK(st->st_mode)) return fsfr_proxyunsetxattr_int(st->st_ino,name);
return fsfr_lunset_attr(fpath,name);
}
int fsfr_getxattr_int_stat64(const char *fpath, const char *name, const struct stat64 *st)
{
if (S_ISLNK(st->st_mode)) return fsfr_proxygetxattr_int(st->st_ino,name);
return fsfr_getxattr_int(fpath,name);
}
int fsfr_lgetxattr_int_stat64(const char *fpath, const char *name, const struct stat64 *st)
{
if (S_ISLNK(st->st_mode)) return fsfr_proxygetxattr_int(st->st_ino,name);
return fsfr_lgetxattr_int(fpath,name);
}
int fsfr_fgetxattr_int_stat64(int fd, const char *name, const struct stat64 *st)
{
if (S_ISLNK(st->st_mode)) return fsfr_proxygetxattr_int(st->st_ino,name);
return fsfr_fgetxattr_int(fd,name);
}