Linux 에서 동적 착탈되는 파일시스템을 검출하는 예제입니다.
개념적인 이해만 되면 USB drive 나 Floppy, CDROM 등을 검출하는 프로그램을 작성할수 있겠지요
현재 이 예제는 일단 USB drive 만 인식하도록 되어 있습니다. (정확히는 "*/sd*" 장치를 검출하게 작성되었습니다.
mzdetectfs.c
partition.c
partition.h
Makefile
개념적인 이해만 되면 USB drive 나 Floppy, CDROM 등을 검출하는 프로그램을 작성할수 있겠지요
현재 이 예제는 일단 USB drive 만 인식하도록 되어 있습니다. (정확히는 "*/sd*" 장치를 검출하게 작성되었습니다.
mzdetectfs.c
| 코드: |
| /* Copyright (C) Information Equipment co.,LTD All rights reserved. Code by JaeHyuk Cho <mailto:minzkn@infoeq.com> CVSTAG="$Id$" */ #include <sys/types.h> #include <sys/ioctl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <getopt.h> #include <signal.h> #include <errno.h> #include "partition.h" #define __def_detectfs_debug__ (1) static volatile int g_mz_detectfs_break = 0; static volatile int g_mz_detectfs_verify = 0; static void mz_detectfs_signal(int s_signal) { switch(s_signal) { case SIGINT: case SIGTERM: case SIGQUIT: g_mz_detectfs_break = 1; (void)signal(s_signal, mz_detectfs_signal); break; case SIGSEGV: case SIGFPE: (void)raise(s_signal); exit(1); break; default: if(g_mz_detectfs_verify != 0)(void)fprintf(stderr, "detectfs: [ERROR] unknown signal ! (signal=%08XH)\n", s_signal); break; } } static int (mz_detectfs_filter)(struct ts_mz_partition *s_partition) { if((s_partition->name == ((char *)0)) || (s_partition->name_size < ((size_t)3)))return(0); if((s_partition->name[0] != 's') || (s_partition->name[1] != 'd'))return(0); return(1); } /* ------------------- */ static int (mz_detectfs_do_work)(int s_valid, struct ts_mz_partition *s_partition, const char *s_entry) { int s_result = 0; if(s_valid != 0) { if(g_mz_detectfs_verify != 0) { unsigned char s_buffer[ 4 << 10 ]; if(s_partition->level[1] == 0u)(void)sprintf((char *)(&s_buffer[0]), "%s/%u", s_entry, s_partition->level[0]); else (void)sprintf((char *)(&s_buffer[0]), "%s/%u/%u", s_entry, s_partition->level[0], s_partition->level[1]); (void)fprintf(stdout, "entry[%s]\n", (char *)(&s_buffer[0])); } } return(s_result); } /* ------------------- */ int (main)(int s_argc, char **s_argv) { int s_result = 0, s_option, s_help = 0, s_interval = 1, s_check; const char *s_entry = (char *)0; struct ts_mz_partition *s_partition, *s_trace; (void)signal(SIGINT, mz_detectfs_signal); (void)signal(SIGTERM, mz_detectfs_signal); (void)signal(SIGQUIT, mz_detectfs_signal); (void)signal(SIGSEGV, mz_detectfs_signal); (void)signal(SIGFPE, mz_detectfs_signal); while((s_option = getopt(s_argc, s_argv, "hve:i:")) != (-1)) { switch(s_option) { case 'h': s_help = 1; case 'v': g_mz_detectfs_verify = 1; break; case 'e': s_entry = optarg; break; case 'i': if(sscanf(optarg, "%d", &s_interval) != 1)s_interval = 1; break; default: break; } } if(s_entry == ((char *)0))s_entry = "/mnt/usb"; if(g_mz_detectfs_verify != 0)(void)fprintf(stdout, "mzdetectfs v0.0.1 build 0 (%s %s) by <minzkn@infoeq.com>\n\n", __DATE__, __TIME__); if(s_help != 0) { (void)fprintf(stdout, "Usage: %s [-h] [-e <mount entry>] [-i <interval>] [-v]\n" "Options:\n" "\t-h : display this help and exit\n" "\t-e <mount entry> : mount entry\n" "\t-i <interval> : check interval (sec)\n" "\t-v : be verbose\n", s_argv[0]); } else { do { s_trace = s_partition = mz_get_partition_list("/proc/partitions"); if(s_partition != ((struct ts_mz_partition *)0)) { while(s_trace != ((struct ts_mz_partition *)0)) { s_check = mz_detectfs_filter(s_trace); (void)mz_detectfs_do_work(s_check, s_trace, s_entry); if(g_mz_detectfs_verify != 0) { (void)fprintf(stdout, "\tmajor=%3u, minor=%3u, blocks=%11llu, name_size=%2u, ", s_trace->major, s_trace->minor, s_trace->blocks, (unsigned int)s_trace->name_size); if(s_check != 0)(void)fprintf(stdout, "name=\"\x1b[1;33m%s\x1b[0m\"\n", s_trace->name); else (void)fprintf(stdout, "name=\"%s\"\n", s_trace->name); if(s_trace->next == ((struct ts_mz_partition *)0))(void)fputs("\n", stdout); } s_trace = s_trace->next; } (void)mz_free_partition_list(s_partition); } if(s_interval > 0)(void)sleep(s_interval); }while(g_mz_detectfs_break == 0); } if(g_mz_detectfs_verify != 0)(void)fputs("\nEnd of detectfs.\n", stdout); return(s_result); } /* vim: set expandtab: */ /* End of source */ |
partition.c
| 코드: |
| /* Copyright (C) Information Equipment co.,LTD All rights reserved. Code by JaeHyuk Cho <mailto:minzkn@infoeq.com> CVSTAG="$Id$" */ #if !defined(__def_detectfs_source_partition_c__) #define __def_detectfs_source_partition_c__ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include "partition.h" #define __def_detectfs_buffer_size__ (4 << 10) size_t (mz_get_word_sep)(const char *s_sep, char **s_sep_string, void *s_data, size_t s_size); struct ts_mz_partition * (mz_new_partition)(void); struct ts_mz_partition * (mz_free_partition)(struct ts_mz_partition *s_partition); struct ts_mz_partition * (mz_parse_proc_partition_line)(const char *s_line); struct ts_mz_partition * (mz_get_partition_list)(const char *s_proc_path); struct ts_mz_partition * (mz_free_partition_list)(struct ts_mz_partition *s_partition); size_t (mz_get_word_sep)(const char *s_sep, char **s_sep_string, void *s_data, size_t s_size) { size_t s_result; const char *s_left, *s_right, *s_sep_ptr; char *s_string = *(s_sep_string); while((*(s_string) == ' ') || (*(s_string) == '\t'))s_string++; s_left = s_right = s_string; while(*(s_string) != '\0') { s_sep_ptr = s_sep; while((*(s_string) != *(s_sep_ptr)) && (*(s_sep_ptr) != '\0'))s_sep_ptr++; if(*(s_string) == *(s_sep_ptr))break; if(*(s_string) != ' ')s_right = ++s_string; else s_string++; } s_result = (size_t)(s_right - s_left); (void)memcpy(s_data, s_left, (s_result > (s_size - ((size_t)1))) ? (s_size - ((size_t)1)) : s_result); *(((char *)s_data) + s_result) = '\0'; *(s_sep_string) = s_string; return(s_result); } struct ts_mz_partition * (mz_new_partition)(void) { struct ts_mz_partition *s_partition = (struct ts_mz_partition *)malloc((size_t)sizeof(struct ts_mz_partition)); if(s_partition != ((struct ts_mz_partition *)0))(void)memset((void *)s_partition, 0, (size_t)sizeof(struct ts_mz_partition)); return(s_partition); } struct ts_mz_partition * (mz_free_partition)(struct ts_mz_partition *s_partition) { if(s_partition != ((struct ts_mz_partition *)0)) { if(s_partition->name != ((char *)0))free((void *)s_partition->name); free((void *)s_partition); } return((struct ts_mz_partition *)0); } struct ts_mz_partition * (mz_parse_proc_partition_line)(const char *s_line) { struct ts_mz_partition *s_new = (struct ts_mz_partition *)0; const char *s_sep_string = s_line; unsigned char s_buffer[ __def_detectfs_buffer_size__ ]; int s_word_count = 0; unsigned int s_major, s_minor; unsigned long long s_blocks; char *s_name; size_t s_size; do { s_size = mz_get_word_sep(" \t", (char **)(&s_sep_string), (void *)(&s_buffer[0]), (size_t)sizeof(s_buffer)); if(*(s_sep_string) != '\0')s_sep_string++; if(s_size <= ((size_t)0))break; if(s_word_count == 0){ /* major */ if(sscanf((char *)(&s_buffer[0]), "%u", &s_major) != 1)break; } else if(s_word_count == 1){ /* minor */ if(sscanf((char *)(&s_buffer[0]), "%u", &s_minor) != 1)break; } else if(s_word_count == 2){ /* blocks */ if(sscanf((char *)(&s_buffer[0]), "%llu", &s_blocks) != 1)break; } else { /* name */ s_name = (char *)malloc(strlen((char *)(&s_buffer[0])) + ((size_t)1)); if(s_name == ((char *)0))break; (void)strcpy(s_name, (char *)(&s_buffer[0])); s_new = mz_new_partition(); if(s_new == ((struct ts_mz_partition *)0))free((void *)s_name); else { s_new->major = s_major; s_new->minor = s_minor; s_new->level[0] = s_minor >> 4; s_new->level[1] = s_minor & 0x0fu; s_new->blocks = s_blocks; s_new->name = s_name; s_new->name_size = s_size; } break; } s_word_count++; }while(*(s_sep_string) != '\0'); return(s_new); } struct ts_mz_partition * (mz_get_partition_list)(const char *s_proc_path) { struct ts_mz_partition *s_partition = (struct ts_mz_partition *)0, *s_last = (struct ts_mz_partition *)0, *s_new; int s_handle = open(s_proc_path, O_RDONLY); unsigned char s_buffer[2][ __def_detectfs_buffer_size__ ]; ssize_t s_read_bytes; const char *s_sep_string = (char *)(&s_buffer[0][0]); if(s_handle != (-1)) { s_read_bytes = read(s_handle, (void *)(&s_buffer[0][0]), (size_t)(sizeof(s_buffer[0]) - 1)); if(s_read_bytes > ((ssize_t)0)) { s_buffer[0][s_read_bytes] = (unsigned char)'\0'; do { (void)mz_get_word_sep("\n\r", (char **)(&s_sep_string), (void *)(&s_buffer[1][0]), (size_t)sizeof(s_buffer[1])); s_new = mz_parse_proc_partition_line((char *)(&s_buffer[1][0])); if(s_new != ((struct ts_mz_partition *)0)) { /* add */ if(s_last != ((struct ts_mz_partition *)0))s_last->next = s_new; else s_partition = s_new; s_last = s_new; } if(*(s_sep_string) != '\0')s_sep_string++; }while(*(s_sep_string) != '\0'); } (void)close(s_handle); } return(s_partition); } struct ts_mz_partition * (mz_free_partition_list)(struct ts_mz_partition *s_partition) { while(s_partition != ((struct ts_mz_partition *)0)){ struct ts_mz_partition *s_prev = s_partition; s_partition = s_partition->next; (void)mz_free_partition(s_prev); } return((struct ts_mz_partition *)0); } #endif /* vim: set expandtab: */ /* End of source */ |
partition.h
| 코드: |
| /* Copyright (C) Information Equipment co.,LTD All rights reserved. Code by JaeHyuk Cho <mailto:minzkn@infoeq.com> CVSTAG="$Id$" */ #if !defined(__def_detectfs_source_partition_h__) #define __def_detectfs_source_partition_h__ struct ts_mz_partition { struct ts_mz_partition *next; unsigned int major, minor, level[2]; unsigned long long blocks; char *name; size_t name_size; }; #if !defined(__def_detectfs_source_partition_c__) extern size_t (mz_get_word_sep)(const char *s_sep, char **s_sep_string, void *s_data, size_t s_size); extern struct ts_mz_partition * (mz_new_partition)(void); extern struct ts_mz_partition * (mz_free_partition)(struct ts_mz_partition *s_partition); extern struct ts_mz_partition * (mz_parse_proc_partition_line)(const char *s_line); extern struct ts_mz_partition * (mz_get_partition_list)(const char *s_proc_path); extern struct ts_mz_partition * (mz_free_partition_list)(struct ts_mz_partition *s_partition); #endif #endif /* vim: set expandtab: */ /* End of source */ |
Makefile
| 코드: |
| # Copyright (C) Information Equipment co.,LTD # All rights reserved. # Code by JaeHyuk Cho <mailto:minzkn@infoeq.com> # CVSTAG="$Id$" CROSS_COMPILE ?=# CC := $(CROSS_COMPILE)gcc# RM := rm -f# STRIP := $(CROSS_COMPILE)strip# THIS_NAME := mzdetectfs# CFLAGS := -Os -pipe -ansi# CFLAGS += -Wall -Werror# CFLAGS += -fomit-frame-pointer# CFLAGS += -I.# LDFLAGS := -s# TARGET := $(THIS_NAME)# OBJECTS := $(THIS_NAME).o# OBJECTS += partition.o# .PHONY: all clean all: $(TARGET) ; $(STRIP) --remove-section=.comment --remove-section=.note $(^) clean: ; $(RM) *.o $(TARGET) $(TARGET): $(OBJECTS) ; $(CC) $(LDFLAGS) -o $(@) $(^) $(OBJECTS): Makefile %.o: %.c ; $(CC) $(CFLAGS) -c -o $(@) $(<) # End of Makefile |


detectfs.tar.bz2

댓글을 달아 주세요