Tuesday, November 17, 2009

SW302 - Лабораторын ажил 7B

Энэ лабораторын ажлаар бид linux системийн оролт гаралтын функцийг ашигласан энгийн програм турших болно.

Програм нь командын мөрнөөс өгөгдсөн директорын файлуудыг шалгаад өгөгдсөн үгийг агуулсан файлыг *-р тэмдэглэж хэвлэнэ.

1. Програм 2 аргумент авна: Эхнийх нь шалгах директорын нэр, дараагийнх нь файлаас хайгдах үг болно.
2. Ажилласан жишээ.

      $ ./pathscanner /home/teachers/chiyeh mypath
      818401 .
      817738 ..
      834481 etc
      822880     *file1
      824239     *file2
      824242     *file3
      824134     *file4
      824098     *file5
      867145 lecture03
      824389 report
      834858 lab06
      834850 sunlab_mike
      822829 file6
      829570 anyorder
      824934 myfiles
      834652 file7
      834826 lecture08
      818888 diagram32.png

Энд file1, file2, file3, file4, file5 файлууд mypath үгийг агуулсан учраас урдаа * тэмдэгээр тэмдэглэгдсэн байна. Эхний тоо нь inode -ийн дугаар болно.

3. Програм нь файл болон директортой холбоотой бүх ажиллагаанд системийн сангийн функцийг ашиглах ёстой. Энд хэрэг болох зарим функцүүд байна. Функцийн тайлбарыг man командыг ашиглаж болно. Жишээ нь man 3 opendir, man 3 closedir, man 2 read, man 2 close, man 2 open:
         1. opendir()
         2. closedir()
         3. readdir()
         4. open()
         5. close()
         6. read()

4. Програм алдаа боловсруулалттай байх ёстой буюу буруу оруулсан аргументийг боловсруулдаг байх хэрэгтэй.

5. Програм дэд директорууд руу шилжин хайдаг байна.

6. Хэрэв буруу аргумент эсвэл ерөөсөө аргумент тавиагүй бол програм доорх тусламжийн мэдээллийг гаргадаг байна:

      Usage: pathscanner [зам] [хайх_үг]
            зам нь хайгдах директорын бүтэн нэр байна.
            хайх_үг нь [зам]-ын дагуу байгаа файлуудаас хайх үг болно,
            хэрэв [хайх_үг] олдвол файлын нэр нь урдаа *-оор тэмдэглэгдэж хэвлэгдэх болно.

Энэ лабораторын бодолт 04 сарын 19-нд гарах бөгөөд энэ хугацаанаас өмнө бодож үзүүлсэн оюутан нэмэлт оноо авах болно.


Програмын бодолт буюу жинхэнэ Лаб #7

Дараах програмын кодыг аваад хөрвүүлж ажиллуулж үзнэ. Програмын шаардлагатай мөрүүдэд тайлбар бичнэ. (~/sw302/lab07/pathscanner.c, ~/sw302/lab07/pathscanner гэсэн эх кодын болон ажилладаг файл байх ёстой) Эцсийн хугацаа:

#include <stdio.h>  
#include <string.h>  
#include <dirent.h>  
#include <fcntl.h>  
#include <stdlib.h>  
 
/* doorhi ifdef macrod tailbar heregtei */
#ifdef NAME_MAX  
  #undef NAME_MAX  
  #define NAME_MAX 1000  
#endif  
 
 
void print_argument_error();
int has_word(char *file_name, char *word);
void opendir_and_mark(char *path, char *word);
 
int main(int argc, char *argv[]){
    if ( argc <= 2){
        print_argument_error();
    }
     
    char dirname[NAME_MAX];
    strcpy(dirname, argv[1]);
    opendir_and_mark(dirname, argv[2]);  
    return 0;
}
 
 
/* doorhi funktsed tailbar heregtei */
void opendir_and_mark(char *dirname, char *word){
    DIR *dir = opendir(dirname);
    /* doorhi if uildeld tailbar heregtei */
    if( dir == NULL){
        char err[NAME_MAX];
        sprintf(err, "Can't open the directory (%s)", dirname);
        perror(err);
        return;
    }
    struct dirent * current = readdir(dir);
     
    /* doorhi if uildeld tailbar heregtei */
    if ( dirname[strlen(dirname) - 1] != '/'){
        strcat(dirname, "/");
    }
    /* doorhi uildeld tailbar heregtei */
    char *subitem_offset = dirname + strlen(dirname);
    while(current != NULL){
        /* doorhi if uildeld tailbar heregtei */
        if ( strcmp(current->d_name, "..") != 0 && strcmp(current->d_name, ".") != 0 ){
            if ( current->d_type == DT_DIR ){
                /* doorhi strcpy funktsed tailbar heregtei */
                strcpy(subitem_offset, current->d_name);
                opendir_and_mark(dirname, word);
            }
            else if ( current->d_type == DT_REG ){
                strcpy(subitem_offset, current->d_name);
                int result;      
                /* doorhi if uildeld tailbar heregtei */        
                if( (result = has_word(dirname, word)) > 0){
                    printf("%d  *%s\n", current->d_ino, dirname);
                }
                else if(result == 0){
                    printf("%d %s\n", current->d_ino, dirname);
                }
                 
            }
        }
        current = readdir(dir);
    }
    closedir(dir);
}
 
/* doorhi funktsed tailbar heregtei */
int has_word(char *file_name, char *word){
    int fd = open(file_name, O_RDONLY);
    /* doorhi if uildeld tailbar heregtei */
    if( fd < 0){
        char err[NAME_MAX];
        sprintf(err, "Can't open the file (%s)", file_name);
        perror(err);
        return -1;
    }
    char buffer[100];
    int found = 0;
    /* doorhi lseek funktsed tailbar heregtei */
    long size = lseek(fd, 0, SEEK_END);
    /* doorhi lseek funksted tailbar heregtei */
    lseek(fd, 0, SEEK_SET);
    /* doorhi malloc funktsed tailbar heregtei */
    char *file_content = malloc(size);
    char *current_ptr = file_content;
    int count;
    /* doorhi while uildeld tailbar heregtei */
    while ( (count = read(fd, current_ptr, 100)) > 0 ){
        current_ptr += count;
    }
    close(fd);
    /* doorhi if uildeld tailbar heregtei */
    if ( strstr(file_content, word) != NULL){
        found = 1;
    }
    /* doorhi free funktsed tailbar heregtei */
    free(file_content);
    return found;
}
 
void print_argument_error(){
    printf("Usage: pathscanner [зам] [хайх_үг]\n\tзам нь хайгдах директорын бүтэн нэр байна."
        "\n\tхайх_үг нь [зам]-ын дагуу байгаа файлуудаас хайх үг болно,\n\t"
        "хэрэв [хайх_үг] олдвол файлын нэр нь урдаа *-оор тэмдэглэгдэж хэвлэгдэх болно.\n");
    exit(0);
}

No comments:

Post a Comment