abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 15:55 | Nová verze

    Byl vydán TrueNAS SCALE 24.04 “Dragonfish”. Přehled novinek této open source storage platformy postavené na Debianu v poznámkách k vydání.

    Ladislav Hagara | Komentářů: 0
    dnes 13:44 | IT novinky

    Oznámeny byly nové Raspberry Pi Compute Module 4S. Vedle původní 1 GB varianty jsou nově k dispozici také varianty s 2 GB, 4 GB a 8 GB paměti. Compute Modules 4S mají na rozdíl od Compute Module 4 tvar a velikost Compute Module 3+ a předchozích. Lze tak provést snadný upgrade.

    Ladislav Hagara | Komentářů: 0
    dnes 04:44 | Nová verze

    Po roce vývoje od vydání verze 1.24.0 byla vydána nová stabilní verze 1.26.0 webového serveru a reverzní proxy nginx (Wikipedie). Nová verze přináší řadu novinek. Podrobný přehled v souboru CHANGES-1.26.

    Ladislav Hagara | Komentářů: 0
    dnes 04:33 | Nová verze

    Byla vydána nová verze 6.2 živé linuxové distribuce Tails (The Amnesic Incognito Live System), jež klade důraz na ochranu soukromí uživatelů a anonymitu. Přehled změn v příslušném seznamu. Tor Browser byl povýšen na verzi 13.0.14.

    Ladislav Hagara | Komentářů: 0
    dnes 04:22 | Nová verze

    Byla vydána nová verze 30.0.0 frameworku pro vývoj multiplatformních desktopových aplikací pomocí JavaScriptu, HTML a CSS Electron (Wikipedie, GitHub). Chromium bylo aktualizováno na verzi 124.0.6367.49, V8 na verzi 12.4 a Node.js na verzi 20.11.1. Electron byl původně vyvíjen pro editor Atom pod názvem Atom Shell. Dnes je na Electronu postavena celá řada dalších aplikací.

    Ladislav Hagara | Komentářů: 1
    dnes 04:11 | Nová verze

    Byla vydána nová verze 9.0.0 otevřeného emulátoru procesorů a virtualizačního nástroje QEMU (Wikipedie). Přispělo 220 vývojářů. Provedeno bylo více než 2 700 commitů. Přehled úprav a nových vlastností v seznamu změn.

    Ladislav Hagara | Komentářů: 0
    včera 23:22 | IT novinky

    Evropský parlament dnes přijal směrnici týkající se tzv. práva spotřebitele na opravu. Poslanci ji podpořili 584 hlasy (3 bylo proti a 14 se zdrželo hlasování). Směrnice ujasňuje povinnosti výrobců opravovat zboží a motivovat spotřebitele k tomu, aby si výrobky nechávali opravit a prodloužili tak jejich životnost.

    Ladislav Hagara | Komentářů: 5
    včera 16:11 | Nová verze

    Bylo oznámeno (cs) vydání Fedora Linuxu 40. Přehled novinek ve Fedora Workstation 40 a Fedora KDE 40 na stránkách Fedora Magazinu. Současně byl oznámen notebook Slimbook Fedora 2.

    Ladislav Hagara | Komentářů: 20
    včera 13:44 | Upozornění

    ČTK (Česká tisková kancelář) upozorňuje (X), že na jejím zpravodajském webu České noviny byly dnes dopoledne neznámým útočníkem umístěny dva smyšlené texty, které nepocházejí z její produkce. Jde o text s titulkem „BIS zabránila pokusu o atentát na nově zvoleného slovenského prezidenta Petra Pelligriniho“ a o údajné mimořádné prohlášení ministra Lipavského k témuž. Tyto dezinformace byly útočníky zveřejněny i s příslušnými notifikacemi v mobilní aplikaci Českých novin. ČTK ve svém zpravodajském servisu žádnou informaci v tomto znění nevydala.

    Ladislav Hagara | Komentářů: 28
    včera 13:33 | Komunita

    Byla založena nadace Open Home Foundation zastřešující více než 240 projektů, standardů, ovladačů a knihoven (Home Assistant, ESPHome, Zigpy, Piper, Improv Wi-Fi, Wyoming, …) pro otevřenou chytrou domácnost s důrazem na soukromí, možnost výběru a udržitelnost.

    Ladislav Hagara | Komentářů: 0
    KDE Plasma 6
     (72%)
     (9%)
     (2%)
     (17%)
    Celkem 719 hlasů
     Komentářů: 4, poslední 6.4. 15:51
    Rozcestník

    Administrace komentářů

    Jste na stránce určené pro řešení chyb a problémů týkajících se diskusí a komentářů. Můžete zde našim administrátorům reportovat špatně zařazenou či duplicitní diskusi, vulgární či osočující příspěvek a podobně. Děkujeme vám za vaši pomoc, více očí více vidí, společně můžeme udržet vysokou kvalitu AbcLinuxu.cz.

    Příspěvek
    7.1.2014 19:11 tomes.io | skóre: 12 | blog: tomesh
    Rozbalit Rozbalit vše Jak osetrit komunikaci POSIX serveru s (a mezi) vice klienty?
    Ahoj, pisu jako skolni projekt neco jako dropbox v C. Synchronizacni server a klient. Hapruje mi komunikace mezi nimi. Kdyz bezi server, tak se po pripojeni prvniho klienta zesychnronizuje s jeho "dropbox" adresare. Dalsi klienti se sychnronizuji uz podle domovskeho adresare serveru.

    Klienti sve adresare monitoruji pomoci inotify a pri zachyceni udalosti (vytvoreni, prejmenovani, smazani souboru/adresare) poslou zpravu serveru spolu s cestou k afektovane polozce. A tady nastava problem.

    Kdyz je k serveru pripojen jeden klient, vse vicemene funguje (vicemene protoze jeste nemam osetrene vsechny mallocy a napriklad pri zkopirovani velkeho mnozstvi polozek do klienta se abortne server). Klient se synchronizuje s adresarem serveru. Kdyz ale pripojim dalsiho klienta, tak se stane, ze server vypise, ze obdrzel prazdnou zpravu a hodi error:
    Reading from socket: Bad file descriptor
    Received message: 
    ERROR writing to socket: Bad file descriptor
    
    Jeden z klientu se tvari ze vse probehlo v poradku - obdrzel zpravu ze servru ze synchronizace probehla:
    The directory New Folder was created.
    Synced with server.
    
    Druhy z klientu ovsem tuto zpravu neobdrzi a co je hlavni, jeho inotify prestane reagovat na udalosti v monitorovanem adresari. Nemuze tedy pokracovat v praci. Pritom se do tohoto "poskozeneho" adresare klienta zkopiruje vsechno jak ma. Dokonce se z nej u odstrani soubory, pokud si je jiny klient ve svem adresari smazal. Ale poskozeny klient uz ve svem adresari nic nemonitoruje a neposila tedy zpravy serveru.

    Zajimalo by me, co zapricinuje, ze na socket dorazi prazdna, nebo necitelna zprava a jak to souvisi s tim, ze klient prestane monitorovat adresar. Zatim jsem se nedopatral, kde se zasekl a proc. Velmi bych ocenil, kdyby se na kod nekdo podival a poradil, protoze sam s timto asi nepohnu.

    Kod pro server je nasledujici:
    #define _GNU_SOURCE
    #include <stdio.h>        
    #include <stdlib.h>         
    #include <string.h>        
    #include <fcntl.h>          
    #include <sys/stat.h>       
    #include <errno.h>
    #include <strings.h>
    #include <sys/types.h> 
    #include <sys/wait.h>
    #include <unistd.h>
    #include <netinet/in.h>      
    #include <sys/socket.h>      
    #include <arpa/inet.h>      
    #include <sched.h>  
    #include <pthread.h>          
    #include <signal.h>         
    #include <semaphore.h>      
    #include <fcntl.h>
    #include <sys/ioctl.h> 
    #include <sys/inotify.h>
    #include <dirent.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <sys/sendfile.h>
    #include <sys/stat.h>
    #include <libgen.h>
    #include <assert.h>
    #include <ctype.h>
    
    #define BUF_SIZE            1024     // buffer size in bytes
    #define PORT_NUM            7011    // Port number for a Web server (TCP 5080)
    #define PEND_CONNECTIONS     250     // pending connections to hold
    #define TRUE                   1
    #define FALSE                  0
    
    /* store paths to clients folders */
    char storage[100][1024];
    pthread_mutex_t lock;
    int clients;
    
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    
    
    int send_file(const char *source,const char *destination);
    
    /**
     * @brief concatenates strings to create a path when copying a directory
     * 
     * @param s1
     * @param s2
     * @return 
     */
    
    char* concat(const char *s1, const char *s2) {
        char *result = malloc(strlen(s1) + strlen(s2) + 1); //+1 for the zero-terminator
    
        if (!result)
            perror("ERROR when concatening");
    
        strcpy(result, s1);
        strcat(result, "/");
        strcat(result, s2);
        return result;
    }
    /**
     * @brief Tests if an item of the same name already exists in directory
     * 
     * @param parent
     * @param name
     * @return 
     */
    
    int testdir(char *parent, char *name) {
        DIR *dir;
        struct dirent *entry;
        int ret = 1;
    
        if (!(dir = opendir(parent))) {
            printf("Creating a new directory. ");
            /* prevent trying to copy files to directories, which are not in
             destination folder yet */
            mkdir(parent, S_IRWXU | S_IRWXG | S_IRWXO);
    
            if (!(dir = opendir(parent)))
                perror("Cannot open the new dir.");
        }
    
        if (!(entry = readdir(dir)))
            perror("Cannot read dir. ");
    
        do {
            if (entry->d_type == DT_DIR) {
                if (strcmp(entry->d_name, ".") == 0 ||
                        strcmp(entry->d_name, "..") == 0)
                    continue;
    
                if (strcmp(entry->d_name, name) == 0)
                    ret = 0;
    
            } else {
                if (strcmp(entry->d_name, name) == 0)
                    ret = 0;
            }
    
        } while ((entry = readdir(dir)));
    
        closedir(dir);
        return ret;
    }
    
    /**
     * @brief Creates a path to server's or client's main directory
     * 
     * @param recpath - path of the destination source
     * @param ssfold - path to the server folder
     * @param len - length of characters to be cut from destination source
     * @return a path where a directory or file is handled.
     */
    
    char* create_path(char* recpath, char* ssfold, int len) {
        char tempath [1024];
        char *buffer;
    
        strcpy(tempath, recpath + len);
        buffer = malloc(strlen(ssfold) + strlen(tempath) + 1);
    
        if (!buffer)
            perror("ERROR when creating path");
    
        strcpy(buffer, ssfold);
        strcat(buffer, tempath);
        return buffer;
    }
    
    /**
     * @brief Copies one directory to another
     * 
     * @param source
     * @param destination
     * @param level
     */
    
    void copydir(const char *source, const char *destination, int level) {
        DIR *dir;
        struct dirent *entry;
        char path[1024];
        char dest[1024];
        char *sendpath;
        
        strcpy(dest, destination);
    
        if (!(dir = opendir(source)))
            return;
    
        if (!(entry = readdir(dir)))
            return;
    
        do {
            if (entry->d_type == DT_DIR) {
    
                int len = snprintf(path, sizeof (path) - 1, "%s/%s",
                        source, entry->d_name);
                path[len] = 0;
    
                if (strcmp(entry->d_name, ".") == 0 ||
                        strcmp(entry->d_name, "..") == 0)
                    continue;
    
                mkdir(concat(dest, entry->d_name), S_IRWXU | S_IRWXG | S_IRWXO);
                copydir(path, concat(dest, entry->d_name), level + 1);
                
            } else {
                /* check that source file exists and can be opened */
                int len = snprintf(path, sizeof (path) - 1, "%s/%s",
                        source, entry->d_name);
                path[len] = 0;
                sendpath = concat(dest, entry->d_name);
                send_file(path, sendpath);
            }
    
        } while ((entry = readdir(dir)));
    
        closedir(dir);
    }
    
    /**
     * @brief Sends a file
     * 
     * @param source
     * @param destination
     */
    
    int send_file(const char *source, const char *destination) {
        FILE * filer, * filew;
        int numr;
        const int SIZE_OF_BUFFER=1024;
        char buffer[SIZE_OF_BUFFER];
        char dest[1024];
        
        strcpy(dest,destination);
    
        if ((filer = fopen(source, "rb")) == NULL) {
            perror("send_file: open read file error.\n");
            printf("debug source: %s\n", source);
            //exit(1);
            return 0;
        }
    
        if ((filew = fopen(dest, "wb")) == NULL) {
            perror("send_file: open write file error.\n");
            printf("debug destination: %s\n", dest);
            fclose(filer);
            exit(1);
            return 0;
        }
    
        while (feof(filer) == 0) {
    
            if ((numr = fread(buffer, 1, SIZE_OF_BUFFER, filer)) != SIZE_OF_BUFFER) {
    
                if (ferror(filer) != 0) {
                    perror("read file error.\n");
                    fclose(filer);
                    fclose(filew);
                    exit(1);
                }
            }
    
            if (fwrite(buffer, 1, numr, filew) != numr) {
                perror("write file error.\n");
                fclose(filer);
                fclose(filew);
                exit(1);
            }
        }
    
        if(fclose(filer) != 0)
          printf("read file - close error.\n");//has read-file been deleted ... ???
    
        if(fclose(filew) != 0)
          printf("write file - close error.\n");//flush C buffer fails
    
        return 1;
        //fsync ????
    
    }
    
    /**
     * @biref Delete a directory
     * 
     * @param pathname
     */
    
    void deldir(char *pathname) {
        DIR *dir;
        struct dirent *entry;
        char path[1024];
    
        if (!(dir = opendir(pathname)))
            return;
    
        if (!(entry = readdir(dir)))
            return;
    
        do {
            if (entry->d_type == DT_DIR) {
    
                int len = snprintf(path, sizeof (path) - 1, "%s/%s",
                        pathname, entry->d_name);
                path[len] = 0;
    
                if (strcmp(entry->d_name, ".") == 0 ||
                        strcmp(entry->d_name, "..") == 0)
                    continue;
    
                deldir(path);
    
            } else {
    
                int len = snprintf(path, sizeof (path) - 1, "%s/%s",
                        pathname, entry->d_name);
                path[len] = 0;
                unlink(path);
            }
    
        } while ((entry = readdir(dir)));
    
        closedir(dir);
        rmdir(pathname);
    }
    
    /**
     * @brief Get a name of an affected item from a path
     * 
     * @param source
     * @return 
     */
    
    char *get_suffix(char *source) {
        char *pch;
        char temp[1024];
        strcpy(temp, source);
        char *suffix = malloc(strlen(temp));
        /* find suffix */
        pch = strtok(temp, "/");
        while (pch != NULL) {
            strcpy(suffix, pch);
            pch = strtok(NULL, "/");
        }
    
        return suffix;
    }
    
    /**
     * @brief Get a parent directory from path
     * 
     * @param source
     * @return 
     */
    
    char *get_parentdir(char *source) {
        char *suffix;
        char *result = malloc(strlen(source) + 3);
        /* backup path*/
        strcpy(result, source);
        /* find suffix */
        suffix = get_suffix(source);
        /* cut path */
        result[strlen(result) - strlen(suffix)] = 0;
    
        return result;
    }
    
    /**
     * @brief Handles received message
     * 
     * @param buffer
     * @param ssfold
     * @param count
     */
    
    void handle_recv_msg(char *buffer, char *ssfold) {
        int i, j, flag, len;
        char *p_str;
        char recpath [1024];
        struct stat isdir;
    
        /* check if a new client wants to be connected */
        if (buffer[0] == '/') {
    
            if (clients == 0) {
                strcpy(storage[0], buffer);
                copydir(storage[0], ssfold, 0);
                
            } else {
                
                for (i = 0; i < clients + 1; i++) {
                    
                    if (strlen(storage[i]) == 0) {
                        strcpy(storage[i], buffer);
                        copydir(ssfold, storage[i], 0); /* synchronize the client with the server. */
                    }
                }
            }
    
            clients++;
            flag = 0;
        } else {
            /* split the message into tokens*/
            j = 0;
            p_str = strtok(buffer, ":");
    
            while (p_str != NULL) {
    
                if (j == 0)
                    flag = atoi(p_str);
                else if (j == 1)
                    len = atoi(p_str);
                else
                    strcpy(recpath, p_str);
    
                p_str = strtok(NULL, ":");
                j++;
            }
    
        }
    
        if ((flag == IN_CREATE)) {
    
            p_str = create_path(recpath, ssfold, len);  //create path to server's folder
            char *name = get_suffix(recpath);
            char *parent;
            
            
            if (stat(recpath, &isdir) == 0 && S_ISDIR(isdir.st_mode)) {
                                        
                if (testdir(get_parentdir(p_str), name)) {
                    mkdir(p_str, S_IRWXU | S_IRWXG | S_IRWXO);
                    copydir(recpath, p_str, 0);
                }
    
                for (i = 0; i < clients; i++) {
    
                    p_str = create_path(recpath, storage[i], len);
                    parent = get_parentdir(p_str);
    
                    if (testdir(parent, name)) {
                        mkdir(p_str, S_IRWXU | S_IRWXG | S_IRWXO);
                        copydir(recpath, p_str, 0);
                        
                    }
                }
    
            } else {
    
                if (testdir(get_parentdir(p_str), name))
                    send_file(recpath, p_str);
    
                for (i = 0; i < clients; i++) {
    
                    parent = get_parentdir(create_path(recpath, storage[i], len));
    
                    if (testdir(parent, name))
                        send_file(recpath, create_path(recpath, storage[i], len));
                }
            }
        }
    
        if ((flag == IN_MOVED_TO)) {
            
            p_str = create_path(recpath, ssfold, len);
            char *name = get_suffix(recpath);
            char *parent;
            
            if (stat(recpath, &isdir) == 0 && S_ISDIR(isdir.st_mode)) {
                                     
                if (testdir(get_parentdir(p_str), name)) {               
                    mkdir(p_str, S_IRWXU | S_IRWXG | S_IRWXO);
                    copydir(recpath, p_str, 0);
                }
                    
                for (i = 0; i < clients; i++) {
    
                    p_str = create_path(recpath, storage[i], len);
                    parent = get_parentdir(p_str);
    
                    if (testdir(parent, name)) {
                        mkdir(create_path(recpath, storage[i], len), S_IRWXU | S_IRWXG | S_IRWXO);
                        copydir(recpath, p_str, 0);
                    }                    
                }
    
            } else {
    
                if (testdir(get_parentdir(p_str), name))
                    send_file(recpath, p_str);
    
                for (i = 0; i < clients; i++) {
    
                    parent = get_parentdir(create_path(recpath, storage[i], len));
                    
                    if (testdir(parent, name))
                        send_file(recpath, create_path(recpath, storage[i], len));
                }
            }
        }
    
        if ((flag == IN_MOVED_FROM) || (flag == IN_DELETE)) {
    
            p_str = create_path(recpath, ssfold, len);
            char *name = get_suffix(recpath);
            char *parent;
    
            if (stat(create_path(recpath, ssfold, len), &isdir) == 0 && 
                    S_ISDIR(isdir.st_mode)) {
                
                parent = get_parentdir(p_str);
                
                if (testdir(parent, name) == 0) {
                     
                    deldir(p_str);
                }
                
                for (i = 0; i < clients; i++) {
    
                    p_str = create_path(recpath, storage[i], len);
                    parent = get_parentdir(p_str);
    
                    if (testdir(parent, name) == 0) {
                        
                        deldir(p_str);
                    }                    
                }
    
            } else {
                
                if (testdir(get_parentdir(p_str), name) == 0)
                    unlink(p_str);
                                              
                for (i = 0; i < clients; i++) {
                    
                    p_str = create_path(recpath, storage[i], len);
                    
                    if (testdir(get_parentdir(p_str), name) == 0)              
                        unlink(p_str);
                }
            }
        }
    }
    
    void *my_thread(void * arg) {
        int my_clisock; //copy socket
        char buffer[BUF_SIZE];
        int n;
        //path to the server's main directory
        char ssfold[] = "/home/tomesh/Dropbox/C/sync"; 
    
        my_clisock = *(int *) arg; // copy the socket
        bzero(buffer, 1024);
    
        n = read(my_clisock, buffer, 1023);
    
        if (n < 0)
            perror("Reading from socket");
    
        printf("Received message: %s\n", buffer);
        
        if (strlen(buffer) > 6 ) {
            
            pthread_mutex_lock (&lock);
            handle_recv_msg(buffer, ssfold);  
            pthread_mutex_unlock (&lock);
            n = write(my_clisock, "Synced with server.", 19);
        }
    
        if (n < 0)
            perror("ERROR writing to socket");
    
        close(my_clisock); // close the client connection
        pthread_exit(NULL);
    }
    
    int main(void) {
        int server_s;
        int clisock;
        struct sockaddr_in server_addr;
        struct sockaddr_in client_addr;
        socklen_t addr_len;
        //unsigned int args;
        pthread_attr_t attr;
        pthread_t threads;
        int i;
    
        server_s = socket(AF_INET, SOCK_STREAM, 0);
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(PORT_NUM);
        server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        bind(server_s, (struct sockaddr *) &server_addr, sizeof (server_addr));
        listen(server_s, PEND_CONNECTIONS);
        pthread_attr_init(&attr);
        pthread_attr_setschedpolicy(&attr, SCHED_FIFO); // FIFO scheduling for threads 
        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // Don't want threads (particualrly main)
                                                                   // waiting on each other
        /* init storage */
        for (i = 0; i < 100; i++) {
            storage[i][0] = 0;
        }
    
        printf("server is ready ...\n");
        clients = 0;
        //sem_init(&sem, 0, 0);
    
        while (TRUE) {
            addr_len = sizeof (client_addr);
            clisock = accept(server_s, (struct sockaddr *) &client_addr, &addr_len);
    
            if (clisock < 0) {
                printf("ERROR - Unable to create socket \n");
                exit(FALSE);
                
            } else {
                
                pthread_create(&threads, &attr, my_thread, &clisock);
                sleep(0); // Giving threads some CPU time
            }
        }
        //close(server_s); // close the primary socket
        return 0;
    }
    
    a pro klienta:
    #define _GNU_SOURCE
    #include <string.h> 
    #include <time.h>
    #include <unistd.h>
    #include <stdlib.h>    
    #include <sys/types.h> 
    #include <sys/wait.h>
    #include <dirent.h>
    #include <unistd.h>
    #include <sys/inotify.h>
    #include <stdio.h>  
    #include <sys/stat.h>
    #include <fcntl.h>   
    #include <sys/ioctl.h>>
    #include <string.h>
    #include <errno.h>
    #include <sys/sendfile.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <ctype.h>
    
    
    int inotify;
    char files[100][1024];
    struct inotify_event *event;
    struct sockaddr_in serv_addr;
    int sockfd;
    
    
    /**
     * @brief Test if only a correct message is about to be sent
     * 
     * @param s
     * @return 
     */
    
    int is_empty(const char *s) {
    
        char buff[1024];
        strcpy(buff,s);;
        
        buff[strlen(buff)] = '\0';
    
        if (buff[0] == '/' || isdigit(buff[0])){      
            return 1;
        }
       
        return 0;
    }
    
    /**
     * @brief Sends a message to the server.
     * 
     * @param message
     * @param portno
     */
    
    void send_msg(char *message, int portno) {
        
        int n;
        char recvbuff[255];
        
        serv_addr.sin_port = htons(portno);
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
    
        if (sockfd < 0)
            perror("send_msg: ERROR opening socket");
    
        if (connect(sockfd, (struct sockaddr *) &serv_addr,
                sizeof (serv_addr)) < 0)
            perror("send msg: ERROR connecting");
    
        n = write(sockfd, message, strlen(message) +1);
    
        if (n < 0)
            perror("send msg: ERROR writing to socket");
    
        n = read(sockfd, recvbuff, 255);
    
        if (n < 0)
            perror(" send_msg: ERROR reading from socket");
    
        printf("%s\n", recvbuff);
        free(message);
        close(sockfd);
    }
    
    /**
     * @brief Recursively watches a directory.
     * 
     * @param file
     */
    
    void watch_dir(char *file) {
        int ret;
        struct stat buf;
        struct dirent *data;
    
        if (lstat(file, &buf))
            return;
    
        if (!S_ISDIR(buf.st_mode))
            return;
    
        //Now recursive part
        DIR *dir = opendir(file);
    
        if (dir == NULL)
            return;
    
        while ((data = readdir(dir)) != NULL) {
            if (strcmp(data->d_name, ".") == 0 ||
                    strcmp(data->d_name, "..") == 0)
                continue;
    
            if (strstr(data->d_name, ".") == data->d_name)
                continue;
    
            char *path2 = (char *) malloc(1024 + sizeof (path2));
            asprintf(&path2, "%s/%s", file, data->d_name);
    
            if (lstat(path2, &buf))
                continue;
            //If it's a dir then launch watch_dir himself on it
            if (S_ISDIR(buf.st_mode))
                watch_dir(path2);
    
            free(path2);
        }
    
        closedir(dir);
        // now set watch for the argument of watch_dir
        ret = inotify_add_watch(inotify, file, IN_ALL_EVENTS);
    
        if (ret == -1) {
            printf("%s\n", file);
            perror("Error in watcher setting\n");
            exit(0);
        }
    
        strcpy(files[ret], file);
        return;
    }
    
    /**
     * @brief Handles notified events.
     * 
     * @param path
     * @param dest
     */
    
    void handle_event(char *path, char *dest, int portno) {
        
        char *message = (char *) malloc((strlen(path) * sizeof (message)) + 10);   
    
        if (event->mask & IN_CREATE) {
            if (event->mask & IN_ISDIR) {
                
                printf("The directory %s was created.\n", event->name);
                watch_dir(dest);
                
            } else {
                
                printf("The file %s was created.\n", event->name);
            }
    
            asprintf(&message, "%d:%d:%s", IN_CREATE,
                    (int) strlen(dest), path);
            
            int j = is_empty(message);
    
            if (j == 1)
                send_msg(message, portno);
            
            //printf("")
        }
    
        if (event->mask & IN_DELETE) {
            if (event->mask & IN_ISDIR) {
                
                printf("The directory %s was deleted.\n", event->name);
                
            } else {
                
                printf("The file %s was deleted.\n", event->name);
            }
    
            asprintf(&message, "%d:%d:%s", IN_DELETE,
                    (int) strlen(dest), path);
    
            int j = is_empty(message);
    
            if (j == 1)
                send_msg(message, portno);
        }
        
        if (event->mask & IN_MODIFY) {
            if (event->mask & IN_ISDIR) {
                
                printf("The directory %s was modified.\n", event->name);
                
            } else {
    
                printf("The file %s was modified.\n", event->name);
            }
    
            asprintf(&message, "%d:%d:%s", IN_MODIFY,
                    (int) strlen(dest), path);
    
            int j = is_empty(message);
    
            if (j == 1)
                send_msg(message, portno);
        }
    
        if (event->mask & IN_MOVED_FROM) {
            if (event->mask & IN_ISDIR) {
    
                printf("Directory %s with cookie %d has been "
                        "moved from the sync directory.\n",
                        event->name, event->cookie);
                
            } else {
                
                printf("Directory %s with cookie %d has been "
                        "moved from the sync directory.\n",
                        event->name, event->cookie);
            }
    
            asprintf(&message, "%d:%d:%s", IN_MOVED_FROM,
                    (int) strlen(dest), path);
            
            int j = is_empty(message);
    
            if (j == 1)
                send_msg(message, portno);
        }
        if (event->mask & IN_MOVED_TO) {
            if (event->mask & IN_ISDIR) {
                
                printf("Directory %s with cookie %d has been "
                        "moved to the sync directory.\n",
                        event->name, event->cookie);
                
            } else {
                
                printf("Directory %s with cookie %d has been "
                        "moved to the sync directory.\n",
                        event->name, event->cookie);
            }
    
            asprintf(&message, "%d:%d:%s", IN_MOVED_TO,
                    (int) strlen(dest), path);
            
            int j = is_empty(message);
    
            if (j == 1)
                send_msg(message, portno);
        }
    }
    
    int main(int agrc, char *argv[]) {
    
        int portno, n;
        struct hostent *server;
        char buffer[4096];
        char *dest = malloc(strlen(argv[1]) + 1);
    
        strcpy(dest, argv[1]);
        inotify = inotify_init();
    
        if (!inotify) {
            perror("Open inotify device");
            fprintf(stderr, "Are you sure your kernel supports inotify?\n");
        }
        //launch recursive watching
        watch_dir(dest);
        printf("Start monitoring!\n");
        portno = atoi(argv[2]);
        server = gethostbyname("localhost");
    
        if (server == NULL) {
            fprintf(stderr, "ERROR, no such host\n");
            exit(0);
        }
    
        bzero((char *) &serv_addr, sizeof (serv_addr));
        serv_addr.sin_family = AF_INET;
        
        bcopy((char *) server->h_addr,
                (char *) &serv_addr.sin_addr.s_addr,
                server->h_length);
    
        /*First connection to the server. 
         * Client sends to a server a path 
         * to client's "dropbox" folder*/
        serv_addr.sin_port = htons(portno);
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
    
        if (connect(sockfd, (struct sockaddr *) &serv_addr,
                sizeof (serv_addr)) < 0)
            perror("ERROR connecting");
    
        n = write(sockfd, dest, strlen(dest) + 1);
    
        if (n < 0)
            perror("ERROR writing to socket");
    
        close(sockfd);
    
        while (1) {
            int ret;
            int i = 0;
            ret = read(inotify, buffer, 4096);
    
            if (ret < 0)
                perror("read");
    
            if (ret == 0)
                sleep(1);
    
            while (i < ret) {
                char *name = NULL;
                event = (struct inotify_event *) &buffer[i];
    
                if (event->len)
                    name = &buffer[i] + sizeof (struct inotify_event);
               
                char *path = (char *) malloc(1024 * sizeof (path));
    
                asprintf(&path, "%s/%s", files[event->wd], name);                     
                handle_event(path, dest, portno);           
                i += sizeof (struct inotify_event) +event->len;
            }
        }
    
        close(sockfd);
        return 0;
    }
    

    V tomto formuláři můžete formulovat svou stížnost ohledně příspěvku. Nejprve vyberte typ akce, kterou navrhujete provést s diskusí či příspěvkem. Potom do textového pole napište důvody, proč by měli admini provést vaši žádost, problém nemusí být patrný na první pohled. Odkaz na příspěvek bude přidán automaticky.

    Vaše jméno
    Váš email
    Typ požadavku
    Slovní popis
    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.