"Fossies" - the Fresh Open Source Software Archive 
Member "smbnetfs-0.6.3/src/event.c" (10 Jan 2015, 8464 Bytes) of package /linux/misc/smbnetfs-0.6.3.tar.bz2:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "event.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
0.5.3b_vs_0.6.0.
1 #include "config.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <signal.h>
5 #include <pthread.h>
6 #include <libsmbclient.h>
7 #include <fuse/fuse.h>
8 #include <glib.h>
9
10 #include "common.h"
11 #include "smbitem.h"
12 #include "auth.h"
13 #include "process.h"
14 #include "samba.h"
15 #include "stat_workaround.h"
16 #include "reconfigure.h"
17
18 static int event_query_browser_flag = 1;
19 static int event_time_step = 10;
20 static int event_smb_tree_scan_period = 300;
21 static int event_smb_tree_elements_ttl = 900;
22 static int event_config_update_period = 300;
23
24 static time_t event_last_smb_tree_scan = (time_t) 0;
25 static time_t event_last_config_update = (time_t) 0;
26
27 static pthread_mutex_t m_evthread = PTHREAD_MUTEX_INITIALIZER;
28
29 static pthread_t event_ev_thread_id;
30 static pthread_t event_smb_thread_id;
31
32 int event_set_query_browser_flag(int flag){
33 DPRINTF(7, "flag=%d\n", flag);
34 g_atomic_int_set(&event_query_browser_flag, flag);
35 return 1;
36 }
37
38 static inline int event_get_query_browser_flag(void){
39 return g_atomic_int_get(&event_query_browser_flag);
40 }
41
42 int event_set_time_step(int step){
43 if (step < 1) return 0;
44 DPRINTF(7, "step=%d\n", step);
45 g_atomic_int_set(&event_time_step, step);
46 return 1;
47 }
48
49 static inline int event_get_time_step(void){
50 return g_atomic_int_get(&event_time_step);
51 }
52
53 int event_set_smb_tree_scan_period(int period){
54 if (period < event_get_time_step()) return 0;
55 DPRINTF(7, "period=%d\n", period);
56 pthread_mutex_lock(&m_evthread);
57 event_smb_tree_scan_period = period;
58 pthread_mutex_unlock(&m_evthread);
59 return 1;
60 }
61
62 static inline int event_get_smb_tree_scan_period(void){
63 int period;
64
65 pthread_mutex_lock(&m_evthread);
66 period = event_smb_tree_scan_period;
67 pthread_mutex_unlock(&m_evthread);
68 return period;
69 }
70
71 int event_set_smb_tree_elements_ttl(int ttl){
72 if (ttl < event_get_smb_tree_scan_period()) return 0;
73 DPRINTF(7, "ttl=%d\n", ttl);
74 g_atomic_int_set(&event_smb_tree_elements_ttl, ttl);
75 return 1;
76 }
77
78 static inline int event_get_smb_tree_elements_ttl(void){
79 return g_atomic_int_get(&event_smb_tree_elements_ttl);
80 }
81
82 int event_set_config_update_period(int period){
83 if ((period != 0) && (period < event_get_time_step())) return 0;
84 DPRINTF(7, "period=%d\n", period);
85 pthread_mutex_lock(&m_evthread);
86 event_config_update_period = period;
87 pthread_mutex_unlock(&m_evthread);
88 return 1;
89 }
90
91 static void event_set_last_smb_tree_scan(time_t scan_time){
92 pthread_mutex_lock(&m_evthread);
93 event_last_smb_tree_scan = scan_time;
94 pthread_mutex_unlock(&m_evthread);
95 }
96
97 static int event_is_time_for_smb_tree_scan(void){
98 int flag;
99
100 pthread_mutex_lock(&m_evthread);
101 flag = (time(NULL) >= event_last_smb_tree_scan +
102 event_smb_tree_scan_period) ? 1 : 0;
103 pthread_mutex_unlock(&m_evthread);
104 return flag;
105 }
106
107 static void event_set_last_config_update(time_t update_time){
108 pthread_mutex_lock(&m_evthread);
109 event_last_config_update = update_time;
110 pthread_mutex_unlock(&m_evthread);
111 }
112
113 static int event_is_time_for_config_update(void){
114 int flag;
115
116 pthread_mutex_lock(&m_evthread);
117 flag = ((event_config_update_period > 0) &&
118 (time(NULL) >= event_last_config_update +
119 event_config_update_period)) ? 1 : 0;
120 pthread_mutex_unlock(&m_evthread);
121 return flag;
122 }
123
124 static void event_scan_samba_group(const char *group){
125 char buf[4096], name[256], link[256];
126 int count;
127 samba_fd fd;
128
129 DPRINTF(5, "group=%s\n", group);
130 snprintf(name, sizeof(name), "/%s", group);
131 fd = samba_opendir(name);
132 while(1){
133 struct smb_conn_dirent_rec *rec;
134
135 count = samba_readdir(fd, buf, sizeof(buf));
136 if (count <= 0) break;
137
138 rec = (struct smb_conn_dirent_rec *) buf;
139 for( ; count >= (int) sizeof(struct smb_conn_dirent_rec);
140 count -= sizeof(struct smb_conn_dirent_rec)){
141 switch(rec->smbc_type){
142 case SMBC_SERVER:
143 smbitem_mkhost(rec->d_name, group, 1, SMBITEM_SAMBA_TREE);
144 snprintf(name, sizeof(name), "%s/%s", group, rec->d_name);
145 snprintf(link, sizeof(link), "../%s", rec->d_name);
146 smbitem_mklink(name, link, SMBITEM_SAMBA_TREE);
147 break;
148 default:
149 DPRINTF(6, "ups..., smbc_type=%d, d_name=%s\n",
150 rec->smbc_type, rec->d_name);
151 }
152 rec++;
153 }
154 }
155 samba_closedir(fd);
156 }
157
158 static void event_scan_smb_root(void){
159 char buf[4096];
160 int count;
161 samba_fd fd;
162
163 DPRINTF(5, "reading group list\n");
164 fd = samba_opendir("/");
165 while(1){
166 struct smb_conn_dirent_rec *rec;
167
168 count = samba_readdir(fd, buf, sizeof(buf));
169 if (count <= 0) break;
170
171 rec = (struct smb_conn_dirent_rec *) buf;
172 for( ; count >= (int) sizeof(struct smb_conn_dirent_rec);
173 count -= sizeof(struct smb_conn_dirent_rec)){
174 switch(rec->smbc_type){
175 case SMBC_WORKGROUP:
176 smbitem_mkgroup(rec->d_name, SMBITEM_SAMBA_TREE);
177 break;
178 default:
179 DPRINTF(6, "ups..., smbc_type=%d, d_name=%s\n",
180 rec->smbc_type, rec->d_name);
181 }
182 rec++;
183 }
184 }
185 samba_closedir(fd);
186 }
187
188 void event_scan_smb_tree(void){
189 int i;
190 struct smbitem *dir;
191
192 if (event_get_query_browser_flag()) event_scan_smb_root();
193 dir = smbitem_get_samba_groups();
194 for(i = 0; i < dir->child_cnt; i++){
195 if (dir->childs[i]->type != SMBITEM_GROUP) continue;
196 event_scan_samba_group(dir->childs[i]->name);
197 }
198 smbitem_release_dir(dir);
199 }
200
201 static void* event_update_smb_tree_thread(void *data){
202 time_t scan_time;
203 time_t die_threshold;
204 int time_step;
205
206 (void)data;
207
208 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
209
210 scan_time = time(NULL);
211 event_scan_smb_tree();
212 event_set_last_smb_tree_scan(scan_time);
213
214 while(1){
215 time_step = event_get_time_step();
216 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
217 sleep(time_step);
218 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
219
220 if (event_is_time_for_smb_tree_scan()){
221 scan_time = time(NULL);
222 die_threshold = scan_time - event_get_smb_tree_elements_ttl();
223 DPRINTF(5, "start at timestamp=%u, die_threshold=%u\n",
224 (unsigned) scan_time, (unsigned) die_threshold);
225
226 event_scan_smb_tree();
227 smbitem_delete_obsolete(die_threshold, SMBITEM_SAMBA_TREE);
228 event_set_last_smb_tree_scan(scan_time);
229 }
230 }
231 return NULL;
232 }
233
234 static void event_reread_config(void){
235 time_t reread_time;
236
237 reread_time = time(NULL);
238 DPRINTF(5, "start at timestamp=%u\n", (unsigned) reread_time);
239
240 reconfigure_read_config(0);
241 smbitem_delete_obsolete(reread_time, SMBITEM_USER_TREE);
242 auth_delete_obsolete(reread_time);
243 stat_workaround_delete_obsolete(reread_time);
244 event_set_last_config_update(reread_time);
245 }
246
247 static void* event_thread(void *data){
248 siginfo_t siginfo;
249 sigset_t signal_set;
250 time_t start_time;
251 struct timespec timeout;
252 int sigret;
253
254 (void)data;
255
256 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
257
258 start_time = time(NULL);
259 event_set_last_config_update(start_time);
260
261 /* set signals to watch */
262 sigemptyset(&signal_set);
263 sigaddset(&signal_set, SIGHUP);
264 sigaddset(&signal_set, SIGCHLD);
265
266 while(1){
267 timeout.tv_sec = event_get_time_step();
268 timeout.tv_nsec = 0;
269 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
270 sigret = sigtimedwait(&signal_set, &siginfo, &timeout);
271 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
272
273 process_cleanup_from_zombies();
274 if ((sigret != -1 && siginfo.si_signo == SIGHUP)
275 || event_is_time_for_config_update())
276 event_reread_config();
277 }
278 return NULL;
279 }
280
281 static void* event_init(struct fuse_conn_info *conn){
282 (void) conn;
283
284 if (pthread_create(&event_smb_thread_id, NULL,
285 event_update_smb_tree_thread, NULL) != 0){
286 fprintf(stderr, "Could not create smb_tree thread\n");
287 exit(1);
288 }
289 if (pthread_create(&event_ev_thread_id, NULL,
290 event_thread, NULL) != 0){
291 fprintf(stderr, "Could not create event thread\n");
292 exit(1);
293 }
294 return NULL;
295 }
296
297 static void event_destroy(void *private_data){
298 (void)private_data;
299
300 DPRINTF(1, "Destroy cfg and smb_tree threads\n");
301 process_disable_new_smb_conn_starting();
302 process_kill_all();
303 pthread_cancel(event_ev_thread_id);
304 pthread_cancel(event_smb_thread_id);
305 pthread_join(event_ev_thread_id, NULL);
306 pthread_join(event_smb_thread_id, NULL);
307 }
308
309 void event_set_event_handler(struct fuse_operations *file_oper){
310 file_oper->init = event_init;
311 file_oper->destroy = event_destroy;
312 }