shinke1987.net
雑多な備忘録等のはず。
他のカテゴリ・タブ
目次
PR

lsコマンドもどき。

2017-03-15 2017-03-15
カテゴリ: C

概要

C言語の勉強と遊びを兼ねて。
フォーマット識別子はここを参考にした。
Linux上で動かすことを想定している。

ソースコード

/* 
 * lsコマンドに、ディレクトリか通常ファイルかを判別して 
 * 表示するプログラム。 
 * 引数は1個だけとる。その引数はlsコマンドで通常使われるような、 
 * 表示したいディレクトリのパス。 
 * ディレクトリか通常ファイルかjpgファイルか、を判別できるようにした。 
 * ディレクトリであれば、[DIR]が頭につく。 
 * jpgファイルであれば、[JPG]が頭につく。 
 */ 
  
#include <stdio.h> 
#include <stdlib.h> 
#include <dirent.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
  
/* 
 * jpgファイルかどうかを判別する。 
 * jpgファイルなら1を返す。 
 * jpgファイルでないなら0を返す。 
 * ファイルを開くことに失敗したら、-1を返す。 
 */ 
int chkjpg ( char *path ) { 
  FILE *file; 
  unsigned char buf[3]; 
  int i, size; 
  // マジックナンバーと比較する時に使うカウント用変数。 
  unsigned short int count = 0; 
  // jpgファイルのマジックナンバー(フォーマット識別子) 
  unsigned int jpg_magic[3] = { 255, 216, 255 }; 
  
  // ファイルを開く。 
  file = fopen( path, "rb" ); 
  if ( file == NULL ) { 
    perror( "fopen" ); 
    return -1; 
  } 
  
  size = fread( buf, 1, 3, file ); 
  
/* 
  printf( "** chkjpg " ); 
  for ( i = 0; i < size; i++ ) { 
    printf( "%02x", buf[i] ); 
  } 
  printf( "\n" ); 
  printf( "**chkjpg2 " ); 
  for (i = 0; i < size; i++ ) { 
    printf( "%d", buf[i] ); 
  } 
  printf( "\n" ); 
  printf( "**chkjpg_compare " ); 
  for ( i = 0; i < size; i++ ) { 
    if ( buf[i] == magic[i] ) { 
      printf( "OK!" ); 
    } 
  } 
  printf( "\n" ); 
*/ 
  // マジックナンバーを比較する。正しければcount変数の値が増える。 
  for ( i = 0; i < size; i++ ) { 
    if ( buf[i] == jpg_magic[i] ) { 
      count++; 
    } 
  } 
  
  fclose( file ); 
  if ( count == size ) { 
    return 1; 
  } else {  
    return 0; 
  } 
} 
  
int main ( int argc, char *argv[] ) 
{ 
  // DIR型はdirent.hをincludeすると使えるようになる。 
  // ディレクトリを指し示す。 
  DIR *dir; 
  // ディレクトリの中にあるファイルの情報を保持する。 
  struct dirent *dp; 
  // dirent型よりもより詳しいファイルの情報を保持する。 
  struct stat sb; 
  // Debianでのファイル名の文字数制限は255byteらしい。 
  // NAME_MAXはdirent.hをincludeすると使えるようになる。 
  char path[NAME_MAX * 2]; 
  // 一時的にパスを格納する。最終的に絶対パスが入る。 
  char tmp_path[NAME_MAX * 2]; 
  
  /* 
   * 引数があるかどうかを判断して、無いならカレントディレクトリをpathに保存。 
   * 引数があるなら、その引数をpathに保存。 
   */ 
  if ( argc <= 1 ) { 
    strcpy( path, "." ); 
  } else { 
    strcpy( path, argv[1] ); 
  } 
  
  // ディレクトリを開く。 
  dir = opendir( path ); 
  if ( dir == NULL ) { 
    perror( "opendir" ); 
    // exit関数はstdlib.hで定義されている。 
    exit( EXIT_FAILURE ); 
  } 
  
  // ディレクトリの中のファイルを見ていく。 
  for ( dp = readdir ( dir ); dp != NULL; dp = readdir ( dir ) ) { 
    // stat関数に絶対パスが渡るようにする。 
    strcpy( tmp_path, path ); 
    strcat( tmp_path, "/" ); 
    strcat( tmp_path, dp -> d_name ); 
    if ( stat( tmp_path, &sb ) == -1 ) { 
      // perror( "stat" ); 
      // closedir( dir ); 
      // exit( EXIT_FAILURE ); 
      continue; 
    } 
  
    // ディレクトリか通常ファイルかを判別。 
    if ( S_ISDIR( sb.st_mode ) ) { 
      printf("[DIR]"); 
    } else if ( chkjpg ( tmp_path ) ) { // jpgファイルか通常ファイルかを判別。 
      printf("[JPG]"); 
    } 
  
    // ファイル名を表示。 
    printf( "name : %s\n", dp -> d_name ); 
  } 
  
  closedir( dir ); 
  exit( EXIT_SUCCESS ); 
} 
同一カテゴリの記事