概要
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 );
}