smbnetfs  0.6.3
About: SMBNetFS is a Linux/FreeBSD filesystem that allow you to use samba/microsoft network in the same manner as the network neighborhood in Microsoft Windows.
  Fossies Dox: smbnetfs-0.6.3.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

event.c
Go to the documentation of this file.
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 
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 
54  if (period < event_get_time_step()) return 0;
55  DPRINTF(7, "period=%d\n", period);
56  pthread_mutex_lock(&m_evthread);
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);
67  pthread_mutex_unlock(&m_evthread);
68  return period;
69 }
70 
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 
83  if ((period != 0) && (period < event_get_time_step())) return 0;
84  DPRINTF(7, "period=%d\n", period);
85  pthread_mutex_lock(&m_evthread);
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 
98  int flag;
99 
100  pthread_mutex_lock(&m_evthread);
101  flag = (time(NULL) >= event_last_smb_tree_scan +
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 
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:
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 
189  int i;
190  struct smbitem *dir;
191 
193  dir = smbitem_get_samba_groups();
194  for(i = 0; i < dir->child_cnt; i++){
195  if (dir->childs[i]->type != SMBITEM_GROUP) continue;
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);
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 
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 
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 
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 
274  if ((sigret != -1 && siginfo.si_signo == SIGHUP)
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");
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 }
void auth_delete_obsolete(time_t threshold)
Definition: auth.c:355
#define DPRINTF(level, fmt, args...)
Definition: common.h:47
static pthread_t event_smb_thread_id
Definition: event.c:30
static int event_is_time_for_config_update(void)
Definition: event.c:113
static void * event_init(struct fuse_conn_info *conn)
Definition: event.c:281
static void event_destroy(void *private_data)
Definition: event.c:297
int event_set_time_step(int step)
Definition: event.c:42
static int event_time_step
Definition: event.c:19
static int event_query_browser_flag
Definition: event.c:18
static pthread_mutex_t m_evthread
Definition: event.c:27
static int event_smb_tree_scan_period
Definition: event.c:20
static int event_get_smb_tree_elements_ttl(void)
Definition: event.c:78
static time_t event_last_config_update
Definition: event.c:25
int event_set_smb_tree_elements_ttl(int ttl)
Definition: event.c:71
void event_set_event_handler(struct fuse_operations *file_oper)
Definition: event.c:309
static void event_reread_config(void)
Definition: event.c:234
static int event_get_smb_tree_scan_period(void)
Definition: event.c:62
int event_set_config_update_period(int period)
Definition: event.c:82
static int event_config_update_period
Definition: event.c:22
static pthread_t event_ev_thread_id
Definition: event.c:29
int event_set_query_browser_flag(int flag)
Definition: event.c:32
static void event_set_last_smb_tree_scan(time_t scan_time)
Definition: event.c:91
static void * event_thread(void *data)
Definition: event.c:247
void event_scan_smb_tree(void)
Definition: event.c:188
static int event_get_query_browser_flag(void)
Definition: event.c:38
static void * event_update_smb_tree_thread(void *data)
Definition: event.c:201
static int event_is_time_for_smb_tree_scan(void)
Definition: event.c:97
static void event_set_last_config_update(time_t update_time)
Definition: event.c:107
static time_t event_last_smb_tree_scan
Definition: event.c:24
static int event_get_time_step(void)
Definition: event.c:49
int event_set_smb_tree_scan_period(int period)
Definition: event.c:53
static void event_scan_smb_root(void)
Definition: event.c:158
static void event_scan_samba_group(const char *group)
Definition: event.c:124
static int event_smb_tree_elements_ttl
Definition: event.c:21
void process_kill_all(void)
Definition: process.c:230
void process_disable_new_smb_conn_starting(void)
Definition: process.c:63
void process_cleanup_from_zombies(void)
Definition: process.c:276
int reconfigure_read_config(int flags)
Definition: reconfigure.c:664
ssize_t samba_readdir(samba_fd fd, void *buf, size_t bufsize)
Definition: samba.c:381
int samba_closedir(samba_fd fd)
Definition: samba.c:365
samba_fd samba_opendir(const char *url)
Definition: samba.c:349
int smbitem_mklink(const char *path, const char *linkpath, enum smbitem_tree_t tree)
Definition: smbitem.c:331
void smbitem_delete_obsolete(time_t threshold, enum smbitem_tree_t tree)
Definition: smbitem.c:523
int smbitem_mkgroup(const char *path, enum smbitem_tree_t tree)
Definition: smbitem.c:212
struct smbitem * smbitem_get_samba_groups(void)
Definition: smbitem.c:404
int smbitem_mkhost(const char *path, const char *group, int is_hidden, enum smbitem_tree_t tree)
Definition: smbitem.c:256
void smbitem_release_dir(struct smbitem *item)
Definition: smbitem.c:513
@ SMBITEM_GROUP
Definition: smbitem.h:9
@ SMBITEM_USER_TREE
Definition: smbitem.h:13
@ SMBITEM_SAMBA_TREE
Definition: smbitem.h:14
void stat_workaround_delete_obsolete(time_t threshold)
unsigned int smbc_type
struct smbitem ** childs
Definition: smbitem.h:39
char * name
Definition: smbitem.h:27
int child_cnt
Definition: smbitem.h:37
enum smbitem_t type
Definition: smbitem.h:28