clsync
Toggle main menu visibility
Loading...
Searching...
No Matches
fileutils.c
Go to the documentation of this file.
1
/*
2
clsync - file tree sync utility based on inotify
3
4
Copyright (C) 2013 Dmitry Yu Okunev <dyokunev@ut.mephi.ru> 0x8E30679C
5
6
This program is free software: you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation, either version 3 of the License, or
9
(at your option) any later version.
10
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
15
16
You should have received a copy of the GNU General Public License
17
along with this program. If not, see <http://www.gnu.org/licenses/>.
18
*/
19
20
#include "
common.h
"
21
22
#include "
error.h
"
23
#include "
malloc.h
"
24
25
26
char
*
fd2fpath_malloc
(
int
fd )
27
{
28
#if __linux__
29
stat64_t
st64;
30
31
if
( fd <= 0 ) {
32
error
(
"Invalid file descriptor supplied: fd2fpath_malloc(%i)."
, fd );
33
errno = EINVAL;
34
return
NULL;
35
}
36
37
char
*fsym = xmalloc ( ( 1 << 8 ) + 2 );
38
sprintf ( fsym,
"/proc/self/fd/%i"
, fd );
39
40
if
( lstat64 ( fsym, &st64 ) ) {
41
error
(
"Cannot lstat64(\"%s\", st64)."
, fsym );
42
return
NULL;
43
}
44
45
ssize_t fpathlen = st64.st_size;
46
47
char
*fpath = xmalloc ( fpathlen + 2 );
48
49
debug
( 3,
"Getting file path from symlink \"%s\". Path length is: %i."
, fsym, fpathlen );
50
51
if
( ( fpathlen = readlink ( fsym, fpath, fpathlen + 1 ) ) < 0 ) {
52
error
(
"Cannot readlink(\"%s\", fpath, bufsize)."
, fsym );
53
free(fsym);
54
return
NULL;
55
}
56
57
fpath[fpathlen] = 0;
58
debug
( 3,
"The path is: \"%s\""
, fpath );
59
free(fsym);
60
return
fpath;
61
#else
62
critical
(
"Function fd2fpath_malloc() is not supported in this OS"
);
63
return
NULL;
64
#endif
65
}
66
67
/**
68
* @brief Copies file
69
*
70
* @param[in] path_from Source file path
71
* @param[in] path_to Destination file path
72
*
73
* @retval zero Successfully copied
74
* @retval non-zero Got error, while copying
75
*
76
*/
77
78
int
fileutils_copy
(
const
char
*path_from,
const
char
*path_to )
79
{
80
char
buf[
BUFSIZ
];
81
FILE *from, *to;
82
from = fopen ( path_from,
"r"
);
83
84
if
( from == NULL ) {
85
error
(
"fileutils_copy(\"%s\", \"%s\"): Cannot open file \"%s\" for reading"
,
86
path_from, path_to, path_from );
87
return
errno;
88
}
89
90
to = fopen ( path_to,
"w"
);
91
92
if
( to == NULL ) {
93
error
(
"fileutils_copy(\"%s\", \"%s\"): Cannot open file \"%s\" for writing"
,
94
path_from, path_to, path_to );
95
return
errno;
96
}
97
98
while
( !feof ( from ) ) {
99
int
err;
100
size_t
r, w;
101
r = fread ( buf, 1,
BUFSIZ
, from );
102
103
if
( ( err = ferror ( from ) ) ) {
104
error
(
"fileutils_copy(\"%s\", \"%s\"): Cannot read from file \"%s\""
,
105
path_from, path_to, path_from );
106
return
errno;
// CHECK: Is the "errno" should be used in fread() case?
107
}
108
109
w = fwrite ( buf, 1, r, to );
110
111
if
( ( err = ferror ( to ) ) ) {
112
error
(
"fileutils_copy(\"%s\", \"%s\"): Cannot write to file \"%s\""
,
113
path_from, path_to, path_to );
114
return
errno;
// CHECK: is the "errno" should be used in fwrite() case?
115
}
116
117
if
( r != w ) {
118
error
(
"fileutils_copy(\"%s\", \"%s\"): Got error while writing to file \"%s\" (%u != %u)"
,
119
path_from, path_to, path_to, r, w );
120
return
errno;
// CHECK: is the "errno" should be used in case "r != w"?
121
}
122
}
123
124
return
0;
125
}
126
127
128
/**
129
* @brief Calculates directory level of a canonized path (actually it just counts "/"-s)
130
*
131
* @param[in] path Canonized path (with realpath())
132
*
133
* @retval zero or prositive Direcory level
134
* @retval negative Got error, while calculation. Error-code is placed to errno.
135
*
136
*/
137
138
short
int
fileutils_calcdirlevel
(
const
char
*path )
139
{
140
short
int
dirlevel = 0;
141
const
char
*ptr = path;
142
143
if
( path == NULL ) {
144
error
(
"path is NULL."
);
145
errno = EINVAL;
146
return
-1;
147
}
148
149
if
( *path == 0 ) {
150
error
(
"path has zero length."
);
151
errno = EINVAL;
152
return
-2;
153
}
154
155
if
( *path !=
'/'
) {
156
error
(
"path \"%s\" is not canonized."
, path );
157
errno = EINVAL;
158
return
-3;
159
}
160
161
while
( * ( ptr++ ) )
162
if
( *ptr ==
'/'
)
163
dirlevel++;
164
165
return
dirlevel;
166
}
167
168
/**
169
* @brief Combination of mkdirat() and openat()
170
*
171
* @param[in] dir_path Path to directory to create and open
172
* @param[in] dirfd_parent File descriptor of directory for relative paths
173
* @param[in] dir_mode Modes for newly created directory (e.g. 750)
174
*
175
* @retval dirfd File descriptor to newly created directory
176
* @retval NULL On error
177
*
178
*/
179
int
mkdirat_open
(
const
char
*
const
dir_path,
int
dirfd_parent, mode_t dir_mode )
180
{
181
int
dirfd;
182
debug
( 5,
"mkdirat(%u, \"%s\", %o)"
, dirfd_parent, dir_path, dir_mode );
183
184
if
( mkdirat ( dirfd_parent, dir_path, dir_mode ) )
185
return
-1;
186
187
debug
( 5,
"openat(%u, \"%s\", %x)"
, dirfd_parent, dir_path, O_RDWR | O_DIRECTORY | O_PATH );
188
dirfd = openat ( dirfd_parent, dir_path, O_RDWR | O_DIRECTORY | O_PATH );
189
190
if
( dirfd == -1 )
191
return
-1;
192
193
return
dirfd;
194
}
195
196
/*
197
* @brief Opens a directory with open()
198
*
199
* @param[out] fd_p Pointer to the result file descriptor
200
* @param[in] dir_path Path to the directory
201
*
202
* @retval *fd_p On success
203
* @retval -1 On error
204
*
205
* /
206
int open_dir(int *fd_p, const char *const dir_path) {
207
int fd = open(dir_path, O_RDONLY|O_DIRECTORY|O_PATH);
208
if (fd == -1) {
209
error("Got error while open(\"%s\", O_RDWR|O_DIRECTORY|O_PATH)", dir_path);
210
return fd;
211
}
212
213
*fd_p = fd;
214
return fd;
215
}
216
*/
217
218
219
uint32_t
stat_diff
(
stat64_t
*a,
stat64_t
*b )
220
{
221
uint32_t difference;
222
#ifdef PARANOID
223
critical_on
( a == NULL );
224
critical_on
( b == NULL );
225
#endif
226
difference = 0x0000;
227
#define STAT_COMPARE(bit, field) \
228
if (a->field != b->field) \
229
difference |= bit;
230
STAT_COMPARE
(
STAT_FIELD_DEV
, st_dev );
231
STAT_COMPARE
(
STAT_FIELD_INO
, st_ino );
232
STAT_COMPARE
(
STAT_FIELD_MODE
, st_mode );
233
STAT_COMPARE
(
STAT_FIELD_NLINK
, st_nlink );
234
STAT_COMPARE
(
STAT_FIELD_UID
, st_uid );
235
STAT_COMPARE
(
STAT_FIELD_GID
, st_gid );
236
STAT_COMPARE
(
STAT_FIELD_RDEV
, st_rdev );
237
STAT_COMPARE
(
STAT_FIELD_SIZE
, st_size );
238
STAT_COMPARE
(
STAT_FIELD_BLKSIZE
, st_blksize );
239
STAT_COMPARE
(
STAT_FIELD_BLOCKS
, st_blocks );
240
STAT_COMPARE
(
STAT_FIELD_ATIME
, st_atime );
241
STAT_COMPARE
(
STAT_FIELD_MTIME
, st_mtime );
242
STAT_COMPARE
(
STAT_FIELD_CTIME
, st_ctime );
243
#undef STAT_COMPARE
244
return
difference;
245
}
246
common.h
BUFSIZ
#define BUFSIZ
Definition
configuration.h:6
STAT_FIELD_RDEV
@ STAT_FIELD_RDEV
Definition
ctx.h:297
STAT_FIELD_ATIME
@ STAT_FIELD_ATIME
Definition
ctx.h:301
STAT_FIELD_INO
@ STAT_FIELD_INO
Definition
ctx.h:292
STAT_FIELD_CTIME
@ STAT_FIELD_CTIME
Definition
ctx.h:303
STAT_FIELD_BLOCKS
@ STAT_FIELD_BLOCKS
Definition
ctx.h:300
STAT_FIELD_NLINK
@ STAT_FIELD_NLINK
Definition
ctx.h:294
STAT_FIELD_SIZE
@ STAT_FIELD_SIZE
Definition
ctx.h:298
STAT_FIELD_MTIME
@ STAT_FIELD_MTIME
Definition
ctx.h:302
STAT_FIELD_GID
@ STAT_FIELD_GID
Definition
ctx.h:296
STAT_FIELD_UID
@ STAT_FIELD_UID
Definition
ctx.h:295
STAT_FIELD_MODE
@ STAT_FIELD_MODE
Definition
ctx.h:293
STAT_FIELD_DEV
@ STAT_FIELD_DEV
Definition
ctx.h:291
STAT_FIELD_BLKSIZE
@ STAT_FIELD_BLKSIZE
Definition
ctx.h:299
error.h
critical
#define critical(...)
Definition
error.h:32
error
#define error(...)
Definition
error.h:36
debug
#define debug(debug_level,...)
Definition
error.h:50
critical_on
#define critical_on(cond)
Definition
error.h:33
mkdirat_open
int mkdirat_open(const char *const dir_path, int dirfd_parent, mode_t dir_mode)
Combination of mkdirat() and openat().
Definition
fileutils.c:179
fd2fpath_malloc
char * fd2fpath_malloc(int fd)
Definition
fileutils.c:26
fileutils_copy
int fileutils_copy(const char *path_from, const char *path_to)
Copies file.
Definition
fileutils.c:78
fileutils_calcdirlevel
short int fileutils_calcdirlevel(const char *path)
Calculates directory level of a canonized path (actually it just counts "/"-s).
Definition
fileutils.c:138
stat_diff
uint32_t stat_diff(stat64_t *a, stat64_t *b)
Definition
fileutils.c:219
STAT_COMPARE
#define STAT_COMPARE(bit, field)
malloc.h
stat64_t
struct stat64 stat64_t
Definition
port-hacks.h:65
Generated on
for clsync by
1.17.0