Пример #1
0
void watch(char *path, bool is_link)
{
    // Add initial path to the watch list
    LIST_NODE *node = get_from_path(path);
    if (node == NULL)
        node = add_to_watch_list(path);
    
    // Searchs and increments the reference counter
    // of the link in list_link
    if (is_link)
        add_to_link_list(node);
    
    // Temporary list to perform breath-first-search
    LIST *list = list_init();
    list_push(list, (void *) path);

    // Traverse directory
    DIR *dir_stream;
    struct dirent *dir;

    while (list->first != NULL)
    {
        // Directory to watch
        char *p = (char*) list_pop(list);
        
        // Traverse directory
        dir_stream = opendir(p);
        
        while (dir = readdir(dir_stream))
        {
            if (dir->d_type == DT_DIR &&
                strcmp(dir->d_name, ".") == 1 &&
                strcmp(dir->d_name, "..") == 1)
            {
                char *path_to_watch = (char*) malloc(sizeof(char) * (strlen(p) + strlen(dir->d_name) + 2));
                strcpy(path_to_watch, p);
                strcat(path_to_watch, dir->d_name);
                strcat(path_to_watch, "/");

                // Add to the watch list
                if (get_from_path(path_to_watch) == NULL)
                    add_to_watch_list(path_to_watch);
                
                // Continue directory traversing
                list_push(list, (void*) path_to_watch);
            }
            // Resolve symbolic link
            else if (dir->d_type == DT_LNK)
            {
                char *path_to_watch = (char*) malloc(sizeof(char) * (strlen(p) + strlen(dir->d_name) + 1));
                strcpy(path_to_watch, p);
                strcat(path_to_watch, dir->d_name);
                
                char *real_path = resolve_real_path(path_to_watch);
                
                // Test for:
                // 1. is a real path
                // 2. is a directory
                if (real_path != NULL && opendir(real_path) != NULL)
                {
                    // Add to the watch list if it's not present
                    LIST_NODE *node = get_from_path(real_path);
                    if (node == NULL)
                        node = add_to_watch_list(real_path);
                    
                    // Searchs and increments the reference counter
                    // of the link in list_link
                    add_to_link_list(node);
                    
                    // Continue directory traversing
                    list_push(list, (void*) real_path);
                }
            }
        }
        closedir(dir_stream);
    }
    
    // Free memory
    list_free(list);
}
Пример #2
0
void watch(char *path, bool is_link)
{
    /* Add initial path to the watch list */
    LIST_NODE *node = get_from_path(path);
    if (node == NULL)
        node = add_to_watch_list(path, is_link);   
    
    /* Temporary list to perform breath-first-search */
    LIST *list = list_init();
    list_push(list, (void *) path);

    /* Traverse directory */
    DIR *dir_stream;
    struct dirent *dir;

    while (list->first != NULL)
    {
        /* Directory to watch */
        char *p = (char*) list_pop(list);
        
        /* Traverse directory */
        dir_stream = opendir(p);
        
        while (dir = readdir(dir_stream))
        {
            if (dir->d_type == DT_DIR &&
                strcmp(dir->d_name, ".") != 0 &&
                strcmp(dir->d_name, "..") != 0)
            {
                char *path_to_watch = (char*) malloc(sizeof(char) * (strlen(p) + strlen(dir->d_name) + 2));
                strcpy(path_to_watch, p);
                strcat(path_to_watch, dir->d_name);
                strcat(path_to_watch, "/");

                /* Add to the watch list with is_link = 0 because is a folder */
                if (get_from_path(path_to_watch) == NULL)
                    add_to_watch_list(path_to_watch, 0);
                /**
                 * XXX: [it] prima di inserire path_to_watch
                 * in `list` sarebbe opportuto controllare che
                 * non sia gia' stata inserita in passato da un qualche ln
                 * che, risolto, puntava ad essa
				 * prima di inserire questo controllo bisogna assicurarsi che sia
				 * effettivamente necessario per evetitare spreco di risorse.
				 * Ad ogni modo senza, effettuerebbe cicli inutili ma non dovrebbe essere compromessa
				 * la stabilita'.
                 */
				                
                /* Continue directory traversing */
                list_push(list, (void*) path_to_watch);
            }
            /* Resolve symbolic link */
            else if (dir->d_type == DT_LNK)
            {
                char *path_to_watch = (char*) malloc(sizeof(char) * (strlen(p) + strlen(dir->d_name) + 1));
                strcpy(path_to_watch, p);
                strcat(path_to_watch, dir->d_name);
                
                char *real_path = resolve_real_path(path_to_watch);
                
                /**
                 * Test for:
                 * 1. is a real path
                 * 2. is a directory
                 */
                if (real_path != NULL && opendir(real_path) != NULL)
                {
                    /**
                     * If it's not present add to the watch list with is_link = 1,
                     * because is pointed by a symbolic link.
                     */
                    LIST_NODE *node = get_from_path(real_path);
                    if (node == NULL)
                        node = add_to_watch_list(real_path, 1);
                    
                    /**
                     * Otherwise path_to_watch is a symbolic_link that point
                     * to real_path, so add path_to_watch in links LIST in node->data
                     */
                    WD_DATA *wd_data = (WD_DATA*) node->data;
                    wd_data->symbolic_link = 1;
                    list_push(wd_data->links, (char*) path_to_watch);

                    /* Continue directory traversing */
                    list_push(list, (void*) real_path);
                }
            }
        }
        closedir(dir_stream);
    }
    
    list_free(list);
}