Lines C



  • I've got a code under Linux that's supposed to monitor the changes of directors or files. It's called surveillance. I have two questions on this code.

    (1) How do you get out of the program? We use an endless cycle here.

    while(1)
    

    the user is unable to complete the process. There's only a CTRL+C, but there's no text from the buffer. That's why I wrote down the function.

    fflush(fp_log); 
    

    that pushes the text from the buffer to the file. But short, it's not beautiful. How do we get out of the cycle? I tried gettingch or getchar, but I'm making mistakes.

    (2) When I create a director or change a file, the message goes to the terminal, but when I remove the file or file, or rename it, it's not out. How do we get out? Add another mask? What?

       /* Inotify используется для наблюдения за поддиректориями выбранной директории*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/inotify.h>
    #include <dirent.h>
    #include <limits.h>
    

    #define MAX_LEN 1024 /длина пути для директории/
    #define MAX_EVENTS 1024 /максимальное количество событий для обработки за один раз/
    #define LEN_NAME 16 /предположим, что длина имени файла не превышает 16 байт/
    #define EVENT_SIZE ( sizeof (struct inotify_event) ) /размер структуры события/
    #define BUF_LEN ( MAX_EVENTS * ( EVENT_SIZE + LEN_NAME )) /буфер для хранения данных события/

    /* Файл журнала*/
    FILE *fp_log;

    /* Добавим наблюдения inotify для поддиректорий сразу после добавления корневой директории */

    void add_watches(int fd, char *root)
    {
    int wd;
    char *abs_dir;
    DIR *dp;

    dp = opendir(root);
    if (dp == NULL)
    {
        perror("Error opening the starting directory");
        exit(0);
    }
    
    /* добавление наблюдения для корневой директории */
    wd = inotify_add_watch(fd, root, IN_CREATE | IN_MODIFY | IN_DELETE); 
    if (wd == -1)
    {
        fprintf(fp_log,"Couldn't add watch to %s\n",root);
    }
    else
    {
        printf("Watching:: %s\n",root);
    }
    closedir(dp);
    

    }

    /* Функция main*/
    int main( int argc, char **argv )
    {
    int length, i = 0;
    int fd;
    char buffer[BUF_LEN], root[MAX_LEN];
    char s;

    /*Проверка наличия параметра командной строки*/
    switch(argc)
    {
        case 1: printf("No directory specified. Will monitor the entire filesystem...\n\n");
            strcpy(root,"/");
            break;
    
        case 2: strcpy(root,argv[1]);
            if(root[strlen(root)-1]!='/')
                strcat(root,"/");
            puts(root);
    
            break;
    
        default: printf("Ignoring all other arguments after the first\n");
    }
    
    
    /* Открытие файла журнала*/
    fp_log = fopen("asasas111.log","w+");
    if (fp_log == NULL)
    {
        printf("Error opening logger. All output will be redirected to the stdout\n");
    }
    
    fd = inotify_init();
    if ( fd &lt; 0 ) {
        perror( "Couldn't initialize inotify");
    }
    
    /* обход поддиректорий первого уровня и добавление наблюдений */
    add_watches(fd,root);
    
    /* бесконечный цикл*/
    while(1)
    {
        i = 0;
        length = read( fd, buffer, BUF_LEN );  
    
        if ( length &lt; 0 ) {
            perror( "read" );
        }  
    
        /* чтентие событий*/
        while ( i &lt; length ) {
            struct inotify_event *event = ( struct inotify_event * ) &amp;buffer[ i ];
            if ( event-&gt;len ) {
                if ( event-&gt;mask &amp; IN_CREATE) {
                    if (event-&gt;mask &amp; IN_ISDIR) {
                        fprintf(fp_log,"%d DIR::%s CREATED\n", event-&gt;wd,event-&gt;name );
                        fflush(fp_log);
                        printf("%d DIR::%s CREATED\n", event-&gt;wd,event-&gt;name );
                        }
                    else    {
                        fprintf(fp_log, "%d FILE::%s CREATED\n", event-&gt;wd, event-&gt;name);
                        fflush(fp_log);
                        printf("%d FILE::%s CREATED\n", event-&gt;wd,event-&gt;name );
                        }
                }
    
                if ( event-&gt;mask &amp; IN_MODIFY) {
                    if (event-&gt;mask &amp; IN_ISDIR) {
                        fprintf(fp_log,"%d DIR::%s MODIFIED\n", event-&gt;wd,event-&gt;name );
                        fflush(fp_log);
                        printf("%d DIR::%s MODIFIED\n", event-&gt;wd,event-&gt;name );
                        }
                    else    {
                        fprintf(fp_log,"%d FILE::%s MODIFIED\n", event-&gt;wd,event-&gt;name );
                        printf("%d FILE::%s MODIFIED\n", event-&gt;wd,event-&gt;name );
                        }
    
                }
    
                if ( event-&gt;mask &amp; IN_DELETE) {
                    if (event-&gt;mask &amp; IN_ISDIR) {
                        fprintf(fp_log,"%d DIR::%s DELETED\n", event-&gt;wd,event-&gt;name );    
                        fflush(fp_log);   
                        printf("%d DIR::%s DELETED\n", event-&gt;wd,event-&gt;name ); 
                        } 
                    else    {
                        fprintf(fp_log,"%d FILE::%s DELETED\n", event-&gt;wd,event-&gt;name );     
                        fflush(fp_log); 
                        printf("%d FILE::%s DELETED\n", event-&gt;wd,event-&gt;name );  
                        }      
                }  
    
                i += EVENT_SIZE + event-&gt;len;
    
            }
        }
    }
    /* освобождение ресурсов*/
    ( void ) close( fd );
    
    return 0;
    

    }



  • How do you get out of the program?

    Same CTRL+C. We just need to get signals. Here's a moron to demonstrate the approach:

    #include <signal.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <stdio.h>
    

    static int terminate = 0;

    static void signal_handler(int signo)
    {
    switch (signo)
    {
    case SIGINT:
    case SIGTERM:
    case SIGTSTP:
    /* не помешает проверить: /
    if (!terminate)
    {
    terminate = 1;
    /
    завершаем начатое и выходим: /
    printf("Got signal %u, bye!\n", signo);
    /

    * fclose(fp_log);
    * close(fd);
    * и т.д.
    */
    exit(EXIT_SUCCESS);
    }
    break;
    default:
    break;
    }
    }

    int main()
    {
    /* Ctrl+C: /
    signal(SIGINT, signal_handler);
    /
    Ctrl+Z, если надо: */
    signal(SIGTSTP, signal_handler);
    signal(SIGTERM, signal_handler);

    while (1)
    {
        if (!terminate)
        {
            /* что-то делаем: */
            puts("do something...");
            /* просто для имитации деятельности: */
            sleep(10);
        }
    }
    /*
     * а вот сюда мы никогда попасть не должны, но на всякий случай
     * вернём ошибку для индикации этого вопиющего недоразумения:
     */
    return EXIT_FAILURE;
    

    }




Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2