본 소스는 임의 유포시에는 반드시 아래의 내용과 함께 배포할것을 유념해주세요. (잘못된 사용으로 사용자의 데이터가 유실되는것을 방지하기 위해서)


본 프로그램의 최근 내용은 http://bbs.minzkn.com/viewtopic.php?f=2&t=849에서 확인하실수 있습니다.

Copyright (저작권)
~~~~~~~~~~~~~~~~~~

Copyright (C) 2008 JaeHyuk Cho
All rights reserved.

http://www.minzkn.com/


특징
~~~~

이 프로그램은 파일명 또는 디렉토리명의 charset이 EUCKR인 경우 이것을 UTF-8로
변경해주는 것
입니다.


주의
~~~~

이 프로그램으로 파일명을 변경하려고 한다면 백업을 반드시 하시고서 실행하시기
바랍니다.

본 프로그램의 제작자는 이 프로그램의 실행으로 발생하는 어떠한 문제도 책임을
지지 않습니다.




사용법
~~~~~~

Quote:
export nameconv=[yes | no]

nameconv <path>



환경변수 nameconv 를 yes로 export 하지 않는한 실제 이름 변경동작을 수행하지
않습니다. 즉, 사전에 먼저 검사해보고 문제가 없을것이라고 판단되면 환경변수
nameconv를 yes 로 export 하여 사용하도록 하여 혹시나 잘못된 변환에 대한
문제점을 사전에 검사하도록 유도하는 방법으로 사용됩니다.

nameconv 실행파일의 인자로 변경할 디렉토리 또는 파일명을 넘겨주면
하위디렉토리까지 재귀적으로 모두 변경하게 됩니다.



사용예
~~~~~~

만약 /mnt/my_data_disk 디렉토리의 하위 모든 파일을 EUCKR 에서 UTF-8 로
변경하고자 한다면 다음과 같은 순서로 실행하면 됩니다.

1. 제대로 변환되는지 검사만 수행

Quote:
sh$ nameconv=no nameconv /mnt/my_data_disk


2. 출력되는 내용에서 문제없이 변경가능할것이라고 판단된다면 실제 변경 시작

Quote:
sh$ nameconv=yes nameconv /mnt/my_data_disk



Code:
/*
 Copyright (C) Information Equipment co.,LTD.
 All rights reserved.
 Code by JaeHyuk Cho <mailto:minzkn@infoeq.com>
 CVSTAG="$Header: /cvsroot/inbt/mzapi/memo/nameconv/nameconv.c,v 1.1 2008/02/13 06:20:19 minzkn Exp $"
*/

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <dirent.h>

#include <iconv.h>

int g_nameconv_enable=0, g_nameconv_total = 0, g_nameconv_done = 0, g_nameconv_error = 0;

static char * nameconv_iconv(const char *s_to_charset, const char *s_from_charset, char *s_name)
{
    char *s_result = (char *)0;
    iconv_t s_iconv;
    unsigned char s_buffer[ 4 << 10 ];
    char *s_in, *s_out;
    size_t s_in_size, s_out_size;

    s_iconv = iconv_open(s_to_charset, s_from_charset);
    if(s_iconv == ((iconv_t)(-1))) {
        perror("iconv_open");
        return((char *)0);
    }
    
    s_in = s_name;
    s_in_size = strlen(s_name);
    s_out = (char *)(&s_buffer[0]);
    s_out_size = sizeof(s_buffer);

    if(iconv(s_iconv, (char **)(&s_in), (size_t *)(&s_in_size), (char **)(&s_out), (size_t *)(&s_out_size)) != ((size_t)(-1))) {
    s_out_size = sizeof(s_buffer) - s_out_size;
        if((s_in_size == ((size_t)0)) && (s_out_size > ((size_t)0))) {
            s_result = (char *)malloc(s_out_size + ((size_t)2));
        if(s_result != ((char *)0)) {
            (void)memcpy(memset((void *)s_result, 0, s_out_size + ((size_t)2)), (char *)(&s_buffer[0]), s_out_size);
        }
    }
    }

    (void)iconv_close(s_iconv);
    return(s_result);
}

static void nameconv(const char *s_to_charset, const char *s_from_charset, const char *s_path)
{
    DIR *s_dir;
    struct dirent *s_dirent;
    struct stat s_stat;
    size_t s_path_size;
    char *s_full_path;
    char *s_to_name;
    char *s_to_path;
    
    s_dir = opendir(s_path);
    if(s_dir == ((DIR *)0))return;

    for(;;) {
        s_dirent = readdir(s_dir);
        if(s_dirent == ((struct dirent *)0))break;

        if((strcmp(s_dirent->d_name, ".") == 0) || (strcmp(s_dirent->d_name, "..") == 0))continue;
 
        s_path_size = strlen(s_path) + ((size_t)1) + strlen(s_dirent->d_name);

        s_full_path = (char *)malloc(s_path_size + ((size_t)1));
        if(s_full_path == ((char *)0))continue;
        (void)sprintf(s_full_path, "%s%s%s", s_path, "/", s_dirent->d_name);
 
        if(lstat(s_full_path, (struct stat *)(&s_stat)) != 0) {
            free((void *)s_full_path);
            continue;
        }

        s_to_path = (char *)0;
    s_to_name = nameconv_iconv(s_to_charset, s_from_charset, s_dirent->d_name);
    if(s_to_name != ((char *)0)) {
            s_path_size = strlen(s_path) + ((size_t)1) + strlen(s_to_name);
        s_to_path = (char *)malloc(s_path_size + ((size_t)1));
            if(s_to_path != ((char *)0))(void)sprintf(s_to_path, "%s%s%s", s_path, "/", s_to_name);
        free((void *)s_to_name);
    }
 
        if(S_ISDIR(s_stat.st_mode))nameconv(s_to_charset, s_from_charset, s_full_path);

        g_nameconv_total++;

    if(s_to_path != ((char *)0)) {
        int s_cmp;
            s_cmp = strcmp(s_full_path, s_to_path);
       
        if(s_cmp == 0) {
            (void)fprintf(stdout, "\x1b[0m%s\x1b[0m => \x1b[1;37m%s\x1b[0m\n", s_full_path, s_to_path);
        }
        else {
            (void)fprintf(stdout, "\x1b[1;33m%s\x1b[0m => \x1b[1;37m%s\x1b[0m\n", s_full_path, s_to_path);
        }
            
        if((g_nameconv_enable == 0) || (s_cmp == 0))g_nameconv_done++;
        else if(rename(s_full_path, s_to_path) == 0)g_nameconv_done++;
        else {
            perror("rename");
            g_nameconv_error++;
            }
        free((void *)s_to_path);
    }
    else {
        (void)fprintf(stdout, "\x1b[1;31m%s\x1b[0m\n", s_full_path);
        g_nameconv_error++;
    }
    }

    closedir(s_dir);
}

int main(int s_argc, char **s_argv)
{
    const char *s_to_charset;
    const char *s_from_charset;
    const char *s_env;

    s_to_charset = "UTF-8";
    s_from_charset = "EUCKR";
    
    s_env = getenv("nameconv");
    if(s_env != ((char *)0)) {
        if(strcmp(s_env, "yes") == 0)g_nameconv_enable = 1;
    }

    nameconv(s_to_charset, s_from_charset, s_argc >= 2 ? s_argv[1] : ".");

    (void)fprintf(stdout, "nameconv result: total=%d, done=%d, error=%d\n", g_nameconv_total, g_nameconv_done, g_nameconv_error);

    return(EXIT_SUCCESS);
}

/* End of source */
크리에이티브 커먼즈 라이센스
Creative Commons License
Posted by minzkn

트랙백 주소 :: http://blog.minzkn.com/trackback/233

댓글을 달아 주세요