vnstat  2.9
About: vnStat is a console-based network traffic monitor (using the /proc filesystem).
  Fossies Dox: vnstat-2.9.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

fs.c
Go to the documentation of this file.
1#include "common.h"
2#include "id.h"
3#include "fs.h"
4
5int direxists(const char *dir)
6{
7 return fileexists(dir);
8}
9
10int fileexists(const char *file)
11{
12 struct stat statbuf;
13
14 if (stat(file, &statbuf) != 0) {
15 if (errno == ENOENT) {
16 return 0;
17 }
18 if (debug)
19 printf("Error (debug): stat() \"%s\": %s\n", file, strerror(errno));
20 }
21 return 1;
22}
23
24int mkpath(const char *dir, const mode_t mode)
25{
26 int ret = 1;
27 size_t i = 0, len = 0;
28 char *tmp = NULL;
29
30 if (!strlen(dir)) {
31 if (debug)
32 printf("Error (debug): mkpath(), no directory given\n");
33 return 0;
34 }
35
36 if (direxists(dir)) {
37 if (debug)
38 printf("already exists: %s\n", dir);
39 return 1;
40 }
41
42 if (!cfg.createdirs) {
43 return 0;
44 }
45
46 tmp = strdup(dir);
47 if (tmp == NULL) {
48 return 0;
49 }
50
51 len = strlen(tmp);
52 if (tmp[len - 1] == '/') {
53 tmp[len - 1] = '\0';
54 }
55
56 if (tmp[0] == '/') {
57 i++;
58 }
59
60 for (; i < len; i++) {
61 if (tmp[i] == '/') {
62 tmp[i] = '\0';
63 if (!direxists(tmp)) {
64 if (mkdir(tmp, mode) != 0) {
65 if (debug)
66 printf("Error (debug): mkdir() \"%s\": %s\n", tmp, strerror(errno));
67 ret = 0;
68 break;
69 }
70 }
71 tmp[i] = '/';
72 }
73 }
74 if (ret) {
75 if (mkdir(tmp, mode) != 0) {
76 if (debug)
77 printf("Error (debug): mkdir() \"%s\": %s\n", tmp, strerror(errno));
78 ret = 0;
79 } else if (debug) {
80 printf("created: %s\n", tmp);
81 }
82 }
83
84 free(tmp);
85 return ret;
86}
87
88void preparevnstatdir(const char *dir, const char *user, const char *group)
89{
90 size_t i, len, lastslash = 0;
91 char *path, *base;
92
93 if (dir == NULL) {
94 return;
95 }
96
97 len = strlen(dir);
98 if (len < 2) {
99 return;
100 }
101
102 if (dir[len - 1] == '/') {
103 return;
104 }
105
106 path = strdup(dir);
107 if (path == NULL) {
108 return;
109 }
110
111 /* verify that path ends with vnstat or vnstatd */
112 base = basename(dirname(path));
113 if (strcmp(base, "vnstat") != 0 && strcmp(base, "vnstatd") != 0) {
114 free(path);
115 return;
116 }
117 free(path);
118
119 path = strdup(dir);
120 if (path == NULL) {
121 return;
122 }
123
124 /* extract path */
125 for (i = 0; i < len; i++) {
126 if (path[i] == '/') {
127 lastslash = i;
128 }
129 }
130 if (lastslash == 0) {
131 free(path);
132 return;
133 }
134 path[lastslash] = '\0';
135
136 /* create & chmod if needed */
137 if (mkpath(path, 0775)) {
138 updatedirowner(path, user, group);
139 }
140 free(path);
141}
142
143void updatedirowner(const char *dir, const char *user, const char *group)
144{
145 uid_t uid;
146 gid_t gid;
147
148 if (!cfg.updatefileowner) {
149 return;
150 }
151
152 if (!hasroot()) {
153 if (debug)
154 printf("user not root, skipping chmod\n");
155 return;
156 }
157
158 uid = getuser(user);
159 gid = getgroup(group);
160
161 updatedirownerid(dir, uid, gid);
162}
163
164void updatedirownerid(const char *dir, const uid_t uid, const gid_t gid)
165{
166 DIR *d;
167 struct dirent *di;
168 struct stat statbuf;
169 char entryname[512];
170 int dir_fd, file_fd;
171
172 if (!cfg.updatefileowner) {
173 return;
174 }
175
176 if (!hasroot()) {
177 if (debug)
178 printf("user not root, skipping chmod\n");
179 return;
180 }
181
182 if ((dir_fd = open(dir, FS_OPEN_RO_FLAGS)) == -1)
183 return;
184 if (fstat(dir_fd, &statbuf) != 0) {
185 close(dir_fd);
186 return;
187 }
188
189 if (statbuf.st_uid != uid || statbuf.st_gid != gid) {
190 if (fchown(dir_fd, uid, gid) != 0) {
191 if (debug)
192 printf("Error (debug): updatedirowner() chown() \"%s\": %s\n", dir, strerror(errno));
193 close(dir_fd);
194 return;
195 } else {
196 if (debug)
197 printf("\"%s\" chown completed\n", dir);
198 }
199 }
200
201 if ((d = fdopendir(dir_fd)) == NULL) {
202 if (debug)
203 printf("Error (debug): updatedirowner() diropen() \"%s\": %s\n", dir, strerror(errno));
204 close(dir_fd);
205 return;
206 }
207
208 while ((di = readdir(d))) {
209 if (di->d_type != DT_REG) {
210 continue;
211 }
212 snprintf(entryname, 512, "%s/%s", dir, di->d_name);
213 if ((file_fd = open(entryname, FS_OPEN_RO_FLAGS)) == -1)
214 continue;
215 if (fstat(file_fd, &statbuf) != 0) {
216 close(file_fd);
217 continue;
218 }
219 if (statbuf.st_uid != uid || statbuf.st_gid != gid) {
220 if (fchown(file_fd, uid, gid) != 0) {
221 if (debug)
222 printf("Error (debug): chown() \"%s\": %s\n", entryname, strerror(errno));
223 } else {
224 if (debug)
225 printf("\"%s\" chown completed\n", entryname);
226 }
227 }
228 close(file_fd);
229 }
230
231 closedir(d);
232}
int debug
Definition: common.c:8
CFG cfg
Definition: common.c:4
void updatedirownerid(const char *dir, const uid_t uid, const gid_t gid)
Definition: fs.c:164
void updatedirowner(const char *dir, const char *user, const char *group)
Definition: fs.c:143
int direxists(const char *dir)
Definition: fs.c:5
int mkpath(const char *dir, const mode_t mode)
Definition: fs.c:24
void preparevnstatdir(const char *dir, const char *user, const char *group)
Definition: fs.c:88
int fileexists(const char *file)
Definition: fs.c:10
#define FS_OPEN_RO_FLAGS
Definition: fs.h:8
gid_t getgroup(const char *group)
Definition: id.c:33
uid_t getuser(const char *user)
Definition: id.c:4
int hasroot(void)
Definition: id.c:130
int32_t createdirs
Definition: common.h:322
int32_t updatefileowner
Definition: common.h:322