"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 }