├── .gitignore ├── Makefile ├── README.md ├── TODO.md ├── c_samples ├── find_git_directory.c ├── is_substr.c ├── pack │ ├── .gitignore │ ├── Makefile │ └── parse_pack_file.c ├── parse_git_index.c ├── print_char.c ├── segfault.c ├── zlib.c └── zlib_simple.c ├── cache.h ├── cmd ├── cat_file.c ├── commit.c ├── hash_object.c ├── init.c ├── log.c ├── ls_files.c └── rev_parse.c ├── manualtest ├── 006a74a39f29e88405d5efe16d04b88bdd315614.tree ├── 006b9f78eb6177c5284ba17158f78bf165d7383e.tree ├── 01_cat-file.sh ├── 02bb82bb5e082cf9f359e6e33ae94e304991b00c.blob └── README.md ├── minigit.c ├── minigit.h ├── sha1.c ├── t ├── commit.t ├── hash-object.t ├── hello.txt ├── init.t ├── lib │ └── MyLib.pm ├── objects │ ├── 0067b.commit │ ├── 0067b.commit.txt │ ├── 16a29.commit │ ├── 16a29.commit.txt │ ├── 1e863.tree │ ├── 1e863.tree.txt │ ├── 1to100.blob │ ├── 1to100.txt │ ├── 44495.tree │ ├── 44495.tree.txt │ ├── f135c.tree │ ├── f135c.tree.txt │ └── hello_world.blob ├── rev_parse.t └── test.t ├── time.c ├── zlib.c └── zlib_git ├── .gitignore ├── Makefile ├── README.md ├── compressed ├── bocchan └── helloworld ├── gen └── .empty ├── git_cat_file-p.c ├── t └── 00_test.t ├── txts ├── bocchan.txt └── helloworld.txt └── zlib.c /.gitignore: -------------------------------------------------------------------------------- 1 | minigit 2 | 3 | # ignore binary executable files 4 | a.out 5 | zlib_sample/zlib 6 | zlib_sample/compress_sample/write_loose_object 7 | 8 | minigit.dSYM 9 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for minigit 2 | PROGNAME = minigit 3 | SUBCOMMANDS=cmd/log.c cmd/cat_file.c cmd/commit.c cmd/hash_object.c cmd/init.c cmd/ls_files.c cmd/rev_parse.c 4 | $(PROGNAME) : $(PROGNAME).h $(PROGNAME).c zlib.c sha1.c time.c $(SUBCOMMANDS) 5 | gcc -g3 -Wall -O0 -lz -lssl -lcrypto -o $(PROGNAME) $(PROGNAME).c zlib.c sha1.c time.c $(SUBCOMMANDS) 6 | 7 | test : $(PROGNAME) 8 | prove 9 | clean : 10 | rm $(PROGNAME) 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # minigit - a minimal implementation of git. 2 | 3 | This project is designed for education of git internals. 4 | 5 | ## INSTALLATION 6 | ```sh 7 | git clone git://github.com/DQNEO/minigit.git 8 | cd minigit 9 | make 10 | ``` 11 | ## MOTIVATION 12 | 13 | `git` is a huge software, but the internal concept and data structure are very simple. 14 | 15 | So I thought we can easily re-invent `git` command by the C language. 16 | 17 | 18 | ## Usage 19 | 20 | ### cat-file 21 | 22 | ``` 23 | # same as git 24 | minigit cat-file -t .git/objects/00/0298c2ba808350e498c4b4149b02b42c47cecd 25 | minigit cat-file -s .git/objects/00/0298c2ba808350e498c4b4149b02b42c47cecd 26 | minigit cat-file -p .git/objects/00/0298c2ba808350e498c4b4149b02b42c47cecd 27 | 28 | # you can pass any loose object file 29 | minigit cat-file -t 000298 30 | minigit cat-file -s 000298 31 | minigit cat-file -p 000298 32 | ``` 33 | 34 | objectfile can be a commit, tree , or blob. 35 | 36 | ## log 37 | 38 | ``` 39 | minigit log 40 | ``` 41 | 42 | ## ls-files 43 | ``` 44 | minigit ls-files 45 | minigit ls-files --stage 46 | ``` 47 | 48 | ## Run test 49 | 50 | ``` 51 | make test 52 | or 53 | prove -r t 54 | ``` 55 | 56 | ## How to get arbitrary loose object files 57 | 58 | you can get as many loose objects as you like by `git unpack-objects` :) 59 | 60 | http://qiita.com/DQNEO/items/b6cb03c60b510dd3c934 61 | 62 | # AUTHOR 63 | 64 | DQNEO 65 | 66 | # LICENSE 67 | 68 | This program is free software; you can redistribute it and/or modify 69 | it under the same terms as git itself. 70 | 71 | # SEE ALSO 72 | 73 | https://github.com/git/git 74 | 75 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | ## TODO 2 | * subcommands 3 | * add 4 | * commit (not dummy commit) 5 | * show 6 | * log -1 7 | * core 8 | * detect .git directory wherever current directory is. 9 | * test 10 | * fix test `prove -r t` to work 11 | * source structure 12 | * #include "../minigit.h" がなんかダサイ 13 | -------------------------------------------------------------------------------- /c_samples/find_git_directory.c: -------------------------------------------------------------------------------- 1 | /** 2 | * cwdから親へたどっていって.gitディレクトリを探す 3 | * 4 | * 元のソースでは、 5 | * setup.c:L643-L664 あたり 6 | * getcwdで取得した文字列を/区切りで順番にchdirして調査している。 7 | */ 8 | #include 9 | #include 10 | 11 | #define PATH_MAX 1024 12 | #define X_OK 0 13 | 14 | /** 15 | * @return bool 16 | */ 17 | int is_git_directory(const char *suspect) 18 | { 19 | char path_to_gitdir[PATH_MAX + 1]; 20 | strcpy(path_to_gitdir, suspect); 21 | strcpy(path_to_gitdir + strlen(suspect), "/.git"); 22 | if (access(path_to_gitdir, X_OK)) { 23 | return 0; // false 24 | } 25 | 26 | return 1; // true 27 | } 28 | 29 | 30 | int find_git_root_directory(char* cwd, size_t cwd_size) 31 | { 32 | int offset; 33 | 34 | if (!getcwd(cwd, cwd_size - 1)) { 35 | fprintf(stderr, "Unable to read cwd"); 36 | return 1; 37 | } 38 | offset = strlen(cwd); 39 | 40 | while (offset > 1) { 41 | if (is_git_directory(cwd)) { 42 | printf(".git found: %s/.git\n", cwd); 43 | return 0; 44 | } 45 | 46 | while (offset-- && cwd[offset] != '/') ; 47 | cwd[offset] = '\0'; 48 | } 49 | 50 | return 0; 51 | } 52 | 53 | int main() { 54 | char path[PATH_MAX + 1]; 55 | find_git_root_directory(path, sizeof(path)); 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /c_samples/is_substr.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /** 4 | * test if a string is a substring of another; 5 | * 6 | */ 7 | int is_substr(const char *s,const char *l) 8 | { 9 | while (*s) { 10 | if (*(s++) != *(l++)) { 11 | return 0; 12 | } 13 | } 14 | 15 | return 1; 16 | } 17 | 18 | 19 | int main() 20 | { 21 | char s[] = "qwerty"; 22 | char l[] = "qwertyuiop"; 23 | 24 | printf("%d\n", is_substr(s, l)); 25 | return 0; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /c_samples/pack/.gitignore: -------------------------------------------------------------------------------- 1 | parse_pack_file 2 | -------------------------------------------------------------------------------- /c_samples/pack/Makefile: -------------------------------------------------------------------------------- 1 | PROGNAME = parse_pack_file 2 | 3 | parse_pack_file : $(PROGNAME).c 4 | gcc -Wall -O0 -o $(PROGNAME) $(PROGNAME).c 5 | ./$(PROGNAME) ../../.git/objects/pack/pack-56d55d7a19f23dc120e4c68d5a08823b63557799.pack 6 | -------------------------------------------------------------------------------- /c_samples/pack/parse_pack_file.c: -------------------------------------------------------------------------------- 1 | /** 2 | * parser of git pack file 3 | * spec https://github.com/git/git/blob/master/Documentation/technical/pack-format.txt 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | struct pack_header { 10 | uint32_t hdr_signature; 11 | uint32_t hdr_version; 12 | uint32_t hdr_entries; 13 | }; 14 | 15 | int read_pack_header(FILE *file, struct pack_header *hdr) 16 | { 17 | fread(hdr, sizeof(struct pack_header),1,file); 18 | return 0; 19 | } 20 | 21 | void parse_file(char *filename) 22 | { 23 | FILE *file; 24 | file = fopen(filename, "r"); 25 | 26 | struct pack_header hdr; 27 | 28 | read_pack_header(file, &hdr); 29 | 30 | printf("signature=%d\n", hdr.hdr_signature); // 'PACK' 31 | printf("version=%d\n", ntohl(hdr.hdr_version)); // 2 32 | printf("num=%d\n", ntohl(hdr.hdr_entries)); 33 | fclose(file); 34 | 35 | return; 36 | 37 | } 38 | 39 | int main(int argc, char **argv) 40 | { 41 | char *filename; 42 | printf("[parsing packe file] %s\n", argv[1]); 43 | 44 | filename = argv[1]; 45 | parse_file(filename); 46 | } 47 | -------------------------------------------------------------------------------- /c_samples/parse_git_index.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Parser of .git/index file 3 | * 4 | * This C program parses any .git/index file. 5 | * It workds just the same as "git ls-files --stage" command. 6 | * 7 | * Usage: 8 | * ./parse_git_index path/to/.git/index 9 | * 10 | * ".git/index" is a binary file. 11 | * the content is like below: 12 | * 13 | * $ hexdump -C .git/index | head 14 | * 00000000 44 49 52 43 00 00 00 02 00 00 00 28 52 5b a4 34 |DIRC.......(R[.4| 15 | * 00000010 2c 67 bf 8a 52 5b a4 34 2c 67 bf 8a 00 00 fd 00 |,g..R[.4,g......| 16 | * 00000020 01 ac 17 55 00 00 81 a4 00 00 01 f5 00 00 01 f5 |...U............| 17 | * 00000030 00 00 00 71 95 ba 71 b8 e7 c2 d7 09 65 d9 a5 08 |...q..q.....e...| 18 | * 00000040 6a 9f ab d5 8e 87 d2 59 00 0a 2e 67 69 74 69 67 |j......Y...gitig| 19 | * 00000050 6e 6f 72 65 00 00 00 00 00 00 00 00 52 65 2a 2d |nore........Re*-| 20 | * 21 | */ 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | struct cache_entry { 31 | unsigned int ce_ctime_sec; 32 | unsigned int ce_ctime_nsec; 33 | unsigned int ce_mtime_sec; 34 | unsigned int ce_mtime_nsec; 35 | unsigned int ce_dev; 36 | unsigned int ce_ino; 37 | unsigned int ce_mode; 38 | unsigned int ce_uid; 39 | unsigned int ce_gid; 40 | unsigned int ce_size; 41 | unsigned char sha1[21]; 42 | char namelen; 43 | char name[1]; 44 | }; 45 | 46 | struct index_header { 47 | char dirc[4]; 48 | unsigned int version; 49 | unsigned int entries; 50 | }; 51 | 52 | static inline unsigned int default_swab32(unsigned int val) 53 | { 54 | return (((val & 0xff000000) >> 24) | 55 | ((val & 0x00ff0000) >> 8) | 56 | ((val & 0x0000ff00) << 8) | 57 | ((val & 0x000000ff) << 24)); 58 | } 59 | 60 | static inline unsigned int bswap32(unsigned int x) 61 | { 62 | unsigned int result; 63 | if (__builtin_constant_p(x)) 64 | result = default_swab32(x); 65 | else 66 | __asm__("bswap %0" : "=r" (result) : "0" (x)); 67 | return result; 68 | } 69 | 70 | char *sha1_to_hex(const unsigned char *sha1) 71 | { 72 | static int bufno; 73 | static char hexbuffer[4][50]; 74 | static const char hex[] = "0123456789abcdef"; 75 | char *buffer = hexbuffer[3 & ++bufno], *buf = buffer; 76 | int i; 77 | 78 | for (i = 0; i < 20; i++) { 79 | unsigned int val = *sha1++; 80 | *buf++ = hex[val >> 4]; 81 | *buf++ = hex[val & 0xf]; 82 | } 83 | *buf = '\0'; 84 | 85 | return buffer; 86 | } 87 | 88 | int calc_padding(int n) 89 | { 90 | int floor; 91 | int ret, target; 92 | 93 | floor = (int)((n -2) / 8); 94 | target = (floor + 1) * 8 + 2; 95 | ret = target - n; 96 | 97 | return ret; 98 | } 99 | 100 | int main(int argc, char **argv) 101 | { 102 | char *index_file; 103 | struct stat st; 104 | int fd; 105 | void *map; 106 | struct index_header *hdr; 107 | struct cache_entry *ce; 108 | char *p_next_entry; 109 | int count_entries; 110 | int i; 111 | 112 | if (argc != 2) { 113 | fprintf(stderr, "Usage:prog .git/index\n"); 114 | exit(1); 115 | } 116 | 117 | index_file = argv[1]; 118 | if (stat(index_file, &st) == -1) { 119 | fprintf(stderr, "unable to stat '%s'\n", index_file); 120 | exit(1); 121 | } 122 | 123 | if ((fd = open(index_file, O_RDONLY)) == -1) { 124 | fprintf(stderr, "unable to open file '%s'\n", index_file); 125 | exit(1); 126 | } 127 | 128 | // git original code is here: 129 | // https://github.com/git/git/blob/v1.9.1/read-cache.c#L1455 130 | map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 131 | 132 | hdr = map; 133 | ce = (struct cache_entry *)(hdr + 1); 134 | 135 | /* for debug */ 136 | /* 137 | printf("==== header ===\n"); 138 | printf("signature = %s\n", hdr->dirc); // => "DIRC" 44 49 52 43 139 | printf("version = %d\n", bswap32(hdr->version)); // => 2 140 | printf("entries = %d\n", bswap32(hdr->entries)); // => number of entries 141 | */ 142 | count_entries = bswap32(hdr->entries); 143 | 144 | for (i=0; i < count_entries; i++) { 145 | printf("%o %s 0\t%s\n", 146 | bswap32(ce->ce_mode), 147 | sha1_to_hex(ce->sha1), 148 | ce->name 149 | ); 150 | 151 | p_next_entry = ce->name + ce->namelen + calc_padding(ce->namelen); 152 | ce = (struct cache_entry *)p_next_entry; 153 | } 154 | 155 | close(fd); 156 | return 0; 157 | } 158 | -------------------------------------------------------------------------------- /c_samples/print_char.c: -------------------------------------------------------------------------------- 1 | /** 2 | * print character code in hex digit 3 | */ 4 | #include 5 | 6 | int main() { 7 | int i; 8 | for (i=0x20;i<=0x80;i++) { 9 | printf("%x => %c\n" ,i ,i); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /c_samples/segfault.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | char s[3] = "abc"; 7 | strcpy(s, "123456789012345678901234"); 8 | 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /c_samples/zlib.c: -------------------------------------------------------------------------------- 1 | // Copyright 2010 Susumu Yata 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define ERROR(fmt, ...) \ 11 | error_at_line(-(__LINE__), errno, __FILE__, __LINE__, fmt, ## __VA_ARGS__) 12 | 13 | enum TestMode { 14 | DEFLATE_MODE, // 圧縮モード(デフォルト) 15 | INFLATE_MODE, // 伸長モード 16 | HELP_MODE, // ヘルプ表示 17 | DEFAULT_MODE = DEFLATE_MODE 18 | }; 19 | 20 | enum OutputFormat { 21 | GZIP_FORMAT, // gzip 形式 22 | ZLIB_FORMAT, // zlib 形式(デフォルト) 23 | DEFAULT_FORMAT = ZLIB_FORMAT 24 | }; 25 | 26 | enum IOBufSize { 27 | INPUT_BUF_SIZE = 65536, // 入力に使うバッファのサイズ 28 | OUTPUT_BUF_SIZE = 65536 // 出力に使うバッファのサイズ 29 | }; 30 | 31 | enum TestMode test_mode = DEFAULT_MODE; 32 | enum OutputFormat output_format = DEFAULT_FORMAT; 33 | const char *output_file_name = NULL; 34 | int compression_level = Z_DEFAULT_COMPRESSION; 35 | 36 | Bytef input_buf[INPUT_BUF_SIZE]; 37 | Bytef output_buf[OUTPUT_BUF_SIZE]; 38 | 39 | void ParseOptions(int argc, char *argv[]) { 40 | // getopt_long() で取得するオプションのリストです. 41 | // 2 番目のメンバが 1 のオプションは引数を取ります. 42 | static const struct option long_options[] = { 43 | { "deflate", 0, NULL, 'd' }, // 圧縮モード 44 | { "inflate", 0, NULL, 'i' }, // 伸長モード 45 | { "gzip", 0, NULL, 'g' }, // gzip 形式 46 | { "zlib", 0, NULL, 'z' }, // zlib 形式 47 | { "level", 1, NULL, 'l' }, // 圧縮レベル 48 | { "output", 1, NULL, 'o' }, // 出力ファイル 49 | { "help", 0, NULL, 'h' }, // ヘルプ表示 50 | { NULL, 0, NULL, '\0' } 51 | }; 52 | 53 | // getopt_long() の第 3 引数はオプションのリストを受け取ります. 54 | // 引数を取るオプション文字には ':' が後続しています. 55 | int value; 56 | while ((value = getopt_long(argc, argv, 57 | "digzl:o:h", long_options, NULL)) != -1) { 58 | switch (value) { 59 | case 'd': { 60 | test_mode = DEFLATE_MODE; 61 | break; 62 | } 63 | case 'i': { 64 | test_mode = INFLATE_MODE; 65 | break; 66 | } 67 | case 'g': { 68 | output_format = GZIP_FORMAT; 69 | break; 70 | } 71 | case 'z': { 72 | output_format = ZLIB_FORMAT; 73 | break; 74 | } 75 | case 'l': { 76 | // 圧縮レベルは 0 以上 9 以下です. 77 | char *end_of_value; 78 | long value = strtol(optarg, &end_of_value, 10); 79 | if ((*end_of_value != '\0') || (value < 0) || (value > 9)) { 80 | ERROR("invalid compression level: %s", optarg); 81 | } 82 | compression_level = (int)value; 83 | break; 84 | } 85 | case 'o': { 86 | // 出力ファイルの名前を設定します. 87 | // 指定がなければ標準出力を使います. 88 | output_file_name = optarg; 89 | break; 90 | } 91 | case 'h': { 92 | test_mode = HELP_MODE; 93 | break; 94 | } 95 | default: { 96 | ERROR("invalid option"); 97 | } 98 | } 99 | } 100 | } 101 | 102 | void DeflateInit(z_stream *stream) { 103 | // メモリの確保・解放は zlib に任せます. 104 | stream->zalloc = Z_NULL; 105 | stream->zfree = Z_NULL; 106 | stream->opaque = Z_NULL; 107 | 108 | // deflateInit() では zlib 形式になります.deflateInit2() の第 3 引数を 109 | // 24 以上 31 以下の値にすると gzip 形式になります.deflateInit2() で 110 | // zlib 形式の圧縮をする場合は,第 3 引数を 8 以上 15 以下にします. 111 | // deflateInit() の動作は 15 のときと同じです. 112 | int ret; 113 | switch (output_format) { 114 | case GZIP_FORMAT: { 115 | ret = deflateInit2(stream, compression_level, 116 | Z_DEFLATED, 31, 8, Z_DEFAULT_STRATEGY); 117 | break; 118 | } 119 | case ZLIB_FORMAT: { 120 | ret = deflateInit(stream, compression_level); 121 | break; 122 | } 123 | default: { 124 | ERROR("invalid format: %d", output_format); 125 | } 126 | } 127 | 128 | if (ret != Z_OK) { 129 | // deflateInit(), deflateInit2() はエラーが起きても .msg を更新しません. 130 | // エラーメッセージの取得には zError() を利用することになります. 131 | ERROR("%s", zError(ret)); 132 | } 133 | } 134 | 135 | void DeflateEnd(z_stream *stream) { 136 | int ret = deflateEnd(stream); 137 | if (ret != Z_OK) { 138 | // deflateEnd() はエラーが起きても .msg を更新しません. 139 | // エラーメッセージの取得には zError() を利用することになります. 140 | ERROR("%s", zError(ret)); 141 | } 142 | } 143 | 144 | void Deflate(FILE *input_file, FILE *output_file) { 145 | z_stream stream; 146 | DeflateInit(&stream); 147 | int flush = Z_NO_FLUSH; 148 | int ret = Z_OK; 149 | do { 150 | stream.avail_in = fread(input_buf, 1, sizeof(input_buf), input_file); 151 | if (ferror(input_file) != 0) { 152 | ERROR("failed to read from file"); 153 | } else if (feof(input_file) != 0) { 154 | // 入力が尽きれば deflate() の第 2 引数を Z_FINISH に切り替えます. 155 | flush = Z_FINISH; 156 | } 157 | stream.next_in = input_buf; 158 | do { 159 | // 出力バッファを再設定して圧縮の続きをおこないます. 160 | stream.next_out = output_buf; 161 | stream.avail_out = sizeof(output_buf); 162 | ret = deflate(&stream, flush); 163 | if (ret == Z_STREAM_ERROR) { 164 | ERROR("%s", stream.msg); 165 | } 166 | fwrite(output_buf, sizeof(output_buf) - stream.avail_out, 167 | 1, output_file); 168 | if (ferror(output_file) != 0) { 169 | ERROR("failed to write into file"); 170 | } 171 | } while ((stream.avail_out == 0) && (ret != Z_STREAM_END)); 172 | if (stream.avail_in != 0) { 173 | ERROR("unexpected bytes in input buffer"); 174 | } 175 | } while (flush != Z_FINISH); 176 | if (ret != Z_STREAM_END) { 177 | ERROR("failed to finish deflate"); 178 | } 179 | if (fflush(output_file) != 0) { 180 | ERROR("failed to flush output file"); 181 | } 182 | DeflateEnd(&stream); 183 | } 184 | 185 | void InflateInit(z_stream *stream) { 186 | // メモリの確保・解放は zlib に任せます. 187 | stream->zalloc = Z_NULL; 188 | stream->zfree = Z_NULL; 189 | stream->opaque = Z_NULL; 190 | 191 | // .next_in, .avail_in は inflateInit(), inflateInit2() を呼び出す前に 192 | // 初期化しておく必要があります. 193 | stream->next_in = Z_NULL; 194 | stream->avail_in = 0; 195 | 196 | int ret = inflateInit2(stream, 47); 197 | if (ret != Z_OK) { 198 | // inflateInit(), inflateInit2() はエラーが起きても .msg を更新しません. 199 | // エラーメッセージの取得には zError() を利用することになります. 200 | ERROR("%s", zError(ret)); 201 | } 202 | } 203 | 204 | void InflateEnd(z_stream *stream) { 205 | int ret = inflateEnd(stream); 206 | if (ret != Z_OK) { 207 | // deflateEnd() はエラーが起きても .msg を更新しません. 208 | // エラーメッセージの取得には zError() を利用することになります. 209 | ERROR("%s", zError(ret)); 210 | } 211 | } 212 | 213 | void Inflate(FILE *input_file, FILE *output_file) { 214 | z_stream stream; 215 | InflateInit(&stream); 216 | int ret = Z_OK; 217 | do { 218 | stream.avail_in = fread(input_buf, 1, sizeof(input_buf), input_file); 219 | if (ferror(input_file) != 0) { 220 | ERROR("failed to read from file"); 221 | } 222 | if (stream.avail_in == 0) { 223 | // 入力が既に尽きている状態であれば,意図していないファイルの終端に 224 | // 到達したことになります. 225 | ERROR("unexpected end of file"); 226 | } 227 | stream.next_in = input_buf; 228 | do { 229 | // 出力バッファを再設定して伸長の続きをおこないます. 230 | stream.next_out = output_buf; 231 | stream.avail_out = sizeof(output_buf); 232 | ret = inflate(&stream, Z_NO_FLUSH); 233 | switch (ret) { 234 | case Z_NEED_DICT: { 235 | // 辞書がなければ伸長できないのでエラーにします. 236 | ERROR("%s", zError(Z_DATA_ERROR)); 237 | } 238 | case Z_STREAM_ERROR: 239 | case Z_DATA_ERROR: 240 | case Z_MEM_ERROR: { 241 | ERROR("%s", stream.msg); 242 | } 243 | } 244 | fwrite(output_buf, sizeof(output_buf) - stream.avail_out, 245 | 1, output_file); 246 | if (ferror(output_file) != 0) { 247 | ERROR("failed to write into file"); 248 | } 249 | // 一つのファイルに複数のデータが格納されているかもしれないので, 250 | // 返り値が Z_STREAM_END であっても,入力が残っている状態であれば, 251 | // 内部状態をリセットして伸長を継続します. 252 | if ((ret == Z_STREAM_END) && 253 | ((stream.avail_in != 0) || (feof(input_file) == 0))) { 254 | ret = inflateReset(&stream); 255 | if (ret != Z_OK) { 256 | ERROR("%s", zError(ret)); 257 | } 258 | stream.avail_out = 0; 259 | } 260 | } while ((stream.avail_out == 0) && (ret != Z_STREAM_END)); 261 | } while (ret != Z_STREAM_END); 262 | InflateEnd(&stream); 263 | } 264 | 265 | void Code(FILE *input_file, FILE *output_file) { 266 | switch (test_mode) { 267 | case DEFLATE_MODE: { 268 | Deflate(input_file, output_file); 269 | break; 270 | } 271 | case INFLATE_MODE: { 272 | Inflate(input_file, output_file); 273 | break; 274 | } 275 | default: { 276 | ERROR("invalid mode: %d", test_mode); 277 | } 278 | } 279 | } 280 | 281 | int main(int argc, char *argv[]) { 282 | ParseOptions(argc, argv); 283 | if (test_mode == HELP_MODE) { 284 | printf("Usage: %s [OPTION]... [FILE]...\n" 285 | "Version: zlib-%s\n" 286 | "Options:\n" 287 | " -d, --deflate 圧縮します (default)\n" 288 | " -i, --inflate 伸長します\n" 289 | " -g, --gzip gzip 形式で圧縮します\n" 290 | " -z, --zlib zlib 形式で圧縮します (default)\n" 291 | " -l, --level=[0-9] 圧縮レベルを指定します (default: 6)\n" 292 | " -o, --output=[FILE] 出力ファイルを指定します (default: stdout)\n" 293 | " -h, --help このヘルプを表示します\n", 294 | argv[0], zlibVersion()); 295 | return 0; 296 | } 297 | 298 | FILE *output_file = stdout; 299 | if (output_file_name != NULL) { 300 | output_file = fopen(output_file_name, "wb"); 301 | if (output_file == NULL) { 302 | ERROR("%s", output_file_name); 303 | } 304 | } 305 | 306 | // 入力ファイルの指定がなければ,標準入力を使います. 307 | if (optind >= argc) { 308 | Code(stdin, output_file); 309 | } else { 310 | for (int i = optind; i < argc; ++i) { 311 | const char *input_file_name = argv[i]; 312 | FILE *input_file = fopen(input_file_name, "rb"); 313 | if (input_file == NULL) { 314 | ERROR("%s", input_file_name); 315 | } 316 | 317 | Code(input_file, output_file); 318 | if (fclose(input_file) != 0) { 319 | ERROR("%s", input_file_name); 320 | } 321 | } 322 | } 323 | 324 | if (output_file != stdout) { 325 | if (fclose(output_file) != 0) { 326 | ERROR("%s", output_file_name); 327 | } 328 | } 329 | 330 | return 0; 331 | } 332 | -------------------------------------------------------------------------------- /c_samples/zlib_simple.c: -------------------------------------------------------------------------------- 1 | // Copyright 2010 Susumu Yata 2 | // Usage: gcc zlib_simple.c -std=c99 -lz -o zlib_simple ; ./zlib_simple hello.blob 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define ERROR(fmt, ...) \ 12 | error_at_line(-(__LINE__), errno, __FILE__, __LINE__, fmt, ## __VA_ARGS__) 13 | 14 | struct _TAG_OBJECT_INFO { 15 | char type[10]; 16 | char size[10]; 17 | } ; 18 | 19 | void unpack_header(const char *input_file_name, struct _TAG_OBJECT_INFO *oi) { 20 | 21 | FILE *input_file = fopen(input_file_name, "rb"); 22 | if (input_file == NULL) { 23 | ERROR("%s", input_file_name); 24 | } 25 | 26 | 27 | Bytef input_buf[65536]; 28 | char output_buf[65536]; 29 | char *cp; 30 | z_stream stream; 31 | cp = output_buf; 32 | // メモリの確保・解放は zlib に任せます. 33 | stream.zalloc = Z_NULL; 34 | stream.zfree = Z_NULL; 35 | stream.opaque = Z_NULL; 36 | 37 | // .next_in, .avail_in は inflateInit(), inflateInit2() を呼び出す前に 38 | // 初期化しておく必要があります. 39 | stream.next_in = Z_NULL; 40 | stream.avail_in = 0; 41 | 42 | int retInit = inflateInit(&stream); 43 | if (retInit != Z_OK) { 44 | // inflateInit(), inflateInit2() はエラーが起きても .msg を更新しません. 45 | // エラーメッセージの取得には zError() を利用することになります. 46 | ERROR("%s", zError(retInit)); 47 | } 48 | 49 | int ret = Z_OK; 50 | while (ret != Z_STREAM_END) { 51 | stream.avail_in = fread(input_buf, 1, sizeof(input_buf), input_file); 52 | if (ferror(input_file) != 0) { 53 | ERROR("failed to read from file"); 54 | } 55 | if (stream.avail_in == 0) { 56 | // 入力が既に尽きている状態であれば,意図していないファイルの終端に 57 | // 到達したことになります. 58 | ERROR("unexpected end of file"); 59 | } 60 | stream.next_in = input_buf; 61 | while ((stream.avail_out == 0) && (ret != Z_STREAM_END)) { 62 | stream.next_out = cp; 63 | stream.avail_out = sizeof(output_buf); 64 | ret = inflate(&stream, Z_NO_FLUSH); 65 | if (ret == Z_MEM_ERROR) { 66 | ERROR("%s", stream.msg); 67 | } 68 | 69 | } ; 70 | }; 71 | 72 | int i = 0; 73 | while (*(cp) != ' ') { 74 | oi->type[i++] = *(cp++); 75 | } 76 | oi->type[i] = 0; 77 | 78 | 79 | i = 0; 80 | while (*cp) { 81 | oi->size[i++] = *(cp++); 82 | } 83 | oi->size[i] = 0; 84 | 85 | int retEnd = inflateEnd(&stream); 86 | if (retEnd != Z_OK) { 87 | // deflateEnd() はエラーが起きても .msg を更新しません. 88 | // エラーメッセージの取得には zError() を利用することになります. 89 | ERROR("%s", zError(retEnd)); 90 | } 91 | 92 | if (fclose(input_file) != 0) { 93 | ERROR("%s", input_file_name); 94 | } 95 | 96 | 97 | } 98 | 99 | int main(int argc, char *argv[]) { 100 | 101 | // 入力ファイルの指定がなければ,エラー 102 | if (argc < 2) { 103 | ERROR("no file name input"); 104 | } 105 | 106 | struct _TAG_OBJECT_INFO *object_info; 107 | const char *input_file_name = argv[1]; 108 | 109 | unpack_header(input_file_name, object_info); 110 | printf("type:%s\n", object_info->type); 111 | printf("size:%s\n", object_info->size); 112 | 113 | return 0; 114 | } 115 | -------------------------------------------------------------------------------- /cache.h: -------------------------------------------------------------------------------- 1 | struct cache_entry { 2 | unsigned int ce_ctime_sec; 3 | unsigned int ce_ctime_nsec; 4 | unsigned int ce_mtime_sec; 5 | unsigned int ce_mtime_nsec; 6 | unsigned int ce_dev; 7 | unsigned int ce_ino; 8 | unsigned int ce_mode; 9 | unsigned int ce_uid; 10 | unsigned int ce_gid; 11 | unsigned int ce_size; 12 | unsigned char sha1[21]; 13 | char namelen; 14 | char name[1]; 15 | }; 16 | 17 | struct index_header { 18 | char dirc[4]; 19 | unsigned int version; 20 | unsigned int entries; 21 | }; 22 | -------------------------------------------------------------------------------- /cmd/cat_file.c: -------------------------------------------------------------------------------- 1 | #include "../minigit.h" 2 | 3 | int cmd_cat_file(int argc, char **argv) 4 | { 5 | struct _TAG_OBJECT_INFO oi; 6 | char *filename; 7 | 8 | 9 | oi.header_length = 0; 10 | 11 | char *opt = argv[1]; 12 | char *object_name = argv[2]; 13 | 14 | // statでファイルの存在チェックができる。 15 | // http://d.hatena.ne.jp/dew_false/20070726/p1 16 | struct stat st; 17 | if (stat(object_name, &st) == 0) { 18 | //引数をそのままファイル名として使用(gitにはない機能) 19 | filename = object_name; 20 | } else { 21 | //引数をsha1(の短縮文字列)とみなす 22 | char found_filename[256] = "\0"; 23 | char *sha1_input = object_name; 24 | if (find_file(sha1_input, found_filename) == -1) { 25 | fprintf(stderr, "loose object file not found:%s\n", object_name); 26 | exit(1); 27 | } 28 | // .git/objects/01/2345... を探索すする 29 | // なければエラー終了 30 | //printf("final filename = %s\n", found_filename); 31 | filename = found_filename; 32 | } 33 | 34 | if (strcmp(opt, "-s") == 0) { 35 | // show size 36 | parse_object_header(filename, &oi); 37 | printf("%d\n", oi.size); 38 | } else if (strcmp(opt, "-t") == 0) { 39 | // show type 40 | parse_object_header(filename, &oi); 41 | printf("%s\n", oi.type); 42 | } else if (strcmp(opt, "-p") == 0) { 43 | // pretty print 44 | parse_object_header(filename, &oi); 45 | 46 | if (strcmp(oi.type, "tree") == 0) { 47 | read_object_body(filename, &oi); //ここがバグってるっぽい 48 | pretty_print_tree_object(&oi); 49 | //fwrite(oi.buf + oi.header_length , 1, oi.size, stdout); 50 | } else { 51 | // print blob or commit 52 | read_object_body(filename, &oi); 53 | fwrite(oi.buf + oi.header_length , 1, oi.size, stdout); 54 | } 55 | 56 | } else { 57 | fprintf(stderr, "Unknown flag: %s\n", opt); 58 | exit(1); 59 | } 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /cmd/commit.c: -------------------------------------------------------------------------------- 1 | #include "../minigit.h" 2 | 3 | int cmd_commit(int argc, char *argv[]) 4 | { 5 | /** 6 | * - 対象となるtreeハッシュ値を取得 7 | * - commitオブジェクトを作成 8 | * - commitオブジェクトを保存 9 | * - refs/heads/{$branch} に新コミットハッシュ値を書き込み 10 | */ 11 | 12 | char tree_sha1[41] = "decd3339b94705aefe6229c1b54150dc7f04c389"; 13 | char *message = argv[2]; 14 | 15 | unsigned char new_sha1[21]; 16 | char parent[41] = ""; 17 | char buf[4096]; // FIXME: this may cause buffer overflow 18 | char *author = "DQNEO 1381754277 +0900"; 19 | char *commiter = "DQNEO 1381754277 +0900"; 20 | 21 | _rev_parse("HEAD", parent); 22 | 23 | sprintf(buf, "tree %s\nparent %s\nauthor %s\ncommiter %s\n\n%s\n", 24 | tree_sha1, 25 | parent, 26 | author, 27 | commiter, 28 | message); 29 | size_t obj_size = strlen(buf) + 1; 30 | calc_sha1("commit", buf, obj_size, new_sha1); 31 | 32 | char hdr[1024]; 33 | char *obj_type = "commit"; 34 | sprintf(hdr, "%s %ld", obj_type ,(long) obj_size); 35 | 36 | int hdrlen = strlen(hdr) + 1; 37 | git_write_loose_object(new_sha1, hdr, hdrlen, buf, obj_size,0); 38 | 39 | /* 40 | if (! update_ref(sha1_to_hex(new_sha1))) { 41 | fprintf(stderr, "unable to update_ref by %s\n", new_sha1_string); 42 | exit(1); 43 | } 44 | */ 45 | printf("[master %s] %s\n", sha1_to_hex(new_sha1), message); 46 | return 0; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /cmd/hash_object.c: -------------------------------------------------------------------------------- 1 | #include "../minigit.h" 2 | 3 | int cmd_hash_object(int argc, char *argv[]) 4 | { 5 | char *filename; 6 | int do_write; 7 | if (strcmp(argv[1], "-w") == 0) { 8 | do_write = 1; 9 | filename = argv[2]; 10 | } else { 11 | do_write = 0; 12 | filename = argv[1]; 13 | } 14 | 15 | unsigned char sha1[41]; 16 | struct stat st; 17 | 18 | if (lstat(filename, &st)) { 19 | fprintf(stderr, "unable to lstat %s\n", filename); 20 | } 21 | 22 | unsigned char *buf; 23 | buf = malloc(st.st_size); 24 | 25 | FILE *fp; 26 | fp = fopen(filename, "rb"); 27 | fread(buf, st.st_size, 1, fp); 28 | fclose(fp); 29 | 30 | calc_sha1("blob", buf, st.st_size, sha1); 31 | 32 | if (do_write) { 33 | char hdr[1024]; 34 | char *obj_type = "blob"; 35 | sprintf(hdr, "%s %ld", obj_type ,(long) st.st_size); 36 | 37 | int hdrlen = strlen(hdr) + 1; 38 | git_write_loose_object(sha1, hdr, hdrlen, buf, st.st_size, 0); 39 | //write_loose_object(sha1, hdr, hdrlen, buf, st.st_size); 40 | } 41 | 42 | free(buf); 43 | printf("%s\n", sha1_to_hex(sha1)); 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /cmd/init.c: -------------------------------------------------------------------------------- 1 | #include "../minigit.h" 2 | 3 | int cmd_init(int argc, char *argv[]) 4 | { 5 | mkdir(".git", 0755); 6 | mkdir(".git/objects", 0755); 7 | mkdir(".git/refs", 0755); 8 | 9 | FILE *fp; 10 | if ((fp = fopen(".git/HEAD","w")) == NULL) { 11 | fprintf(stderr, "unable to create .git/HEAD"); 12 | exit(1); 13 | } 14 | 15 | fprintf(fp, "ref: refs/heads/master\n"); 16 | fclose(fp); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /cmd/log.c: -------------------------------------------------------------------------------- 1 | #include "../minigit.h" 2 | 3 | int cmd_log(int argc , char **argv) 4 | { 5 | char rev[256]; 6 | if (argc > 1) { 7 | strcpy(rev, argv[1]); 8 | } else { 9 | // default "HEAD" 10 | strcpy(rev, "HEAD"); 11 | } 12 | 13 | char commit_sha1[256] = {}; 14 | _rev_parse(rev, commit_sha1); 15 | 16 | char parent_sha1[256] = {}; 17 | 18 | while(cat_commit_object(commit_sha1, parent_sha1) != -1){ 19 | strcpy(commit_sha1, parent_sha1); 20 | } 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /cmd/ls_files.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Parser of .git/index file 3 | * 4 | * ".git/index" is a binary file. 5 | * the content is like below: 6 | * 7 | * $ hexdump -C .git/index | head 8 | * 00000000 44 49 52 43 00 00 00 02 00 00 00 28 52 5b a4 34 |DIRC.......(R[.4| 9 | * 00000010 2c 67 bf 8a 52 5b a4 34 2c 67 bf 8a 00 00 fd 00 |,g..R[.4,g......| 10 | * 00000020 01 ac 17 55 00 00 81 a4 00 00 01 f5 00 00 01 f5 |...U............| 11 | * 00000030 00 00 00 71 95 ba 71 b8 e7 c2 d7 09 65 d9 a5 08 |...q..q.....e...| 12 | * 00000040 6a 9f ab d5 8e 87 d2 59 00 0a 2e 67 69 74 69 67 |j......Y...gitig| 13 | * 00000050 6e 6f 72 65 00 00 00 00 00 00 00 00 52 65 2a 2d |nore........Re*-| 14 | * 15 | */ 16 | #include "../minigit.h" 17 | 18 | static inline unsigned int default_swab32(unsigned int val) 19 | { 20 | return (((val & 0xff000000) >> 24) | 21 | ((val & 0x00ff0000) >> 8) | 22 | ((val & 0x0000ff00) << 8) | 23 | ((val & 0x000000ff) << 24)); 24 | } 25 | 26 | static inline unsigned int bswap32(unsigned int x) 27 | { 28 | unsigned int result; 29 | if (__builtin_constant_p(x)) 30 | result = default_swab32(x); 31 | else 32 | __asm__("bswap %0" : "=r" (result) : "0" (x)); 33 | return result; 34 | } 35 | 36 | int calc_padding(int n) 37 | { 38 | int floor; 39 | int ret, target; 40 | 41 | floor = (int)((n -2) / 8); 42 | target = (floor + 1) * 8 + 2; 43 | ret = target - n; 44 | 45 | return ret; 46 | } 47 | 48 | /** 49 | * ls-files --stage 50 | */ 51 | int cmd_ls_files(int argc, char **argv) 52 | { 53 | char index_file_name[PATH_MAX + 1];; 54 | 55 | struct stat st; 56 | int fd; 57 | void *map; 58 | struct index_header *hdr; 59 | struct cache_entry *ce; 60 | char *p_next_entry; 61 | int count_entries; 62 | int i; 63 | int option_stage = 0; 64 | 65 | // --stage or not 66 | if (argc == 2 && strcmp(argv[1], "--stage") == 0) { 67 | option_stage = 1; 68 | } 69 | 70 | find_git_root_directory(index_file_name, sizeof(index_file_name)); 71 | strcpy(index_file_name + strlen(index_file_name), "/.git/index"); 72 | 73 | if (stat(index_file_name, &st) == -1) { 74 | fprintf(stderr, "unable to stat '%s'\n", index_file_name); 75 | exit(1); 76 | } 77 | 78 | if ((fd = open(index_file_name, O_RDONLY)) == -1) { 79 | fprintf(stderr, "unable to open file '%s'\n", index_file_name); 80 | exit(1); 81 | } 82 | 83 | // git original code is here: 84 | // https://github.com/git/git/blob/v1.9.1/read-cache.c#L1455 85 | map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 86 | 87 | hdr = map; 88 | ce = (struct cache_entry *)(hdr + 1); 89 | 90 | count_entries = bswap32(hdr->entries); 91 | 92 | for (i=0; i < count_entries; i++) { 93 | if (option_stage) { 94 | printf("%o %s 0\t%s\n", 95 | bswap32(ce->ce_mode), 96 | sha1_to_hex(ce->sha1), 97 | ce->name 98 | ); 99 | } else { 100 | printf("%s\n", ce->name); 101 | } 102 | 103 | p_next_entry = ce->name + ce->namelen + calc_padding(ce->namelen); 104 | ce = (struct cache_entry *)p_next_entry; 105 | } 106 | 107 | close(fd); 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /cmd/rev_parse.c: -------------------------------------------------------------------------------- 1 | #include "../minigit.h" 2 | 3 | int cmd_rev_parse(int argc, char **argv) 4 | { 5 | if (argc < 2) { 6 | return 0; 7 | } 8 | 9 | char sha1_string[256]; 10 | char rev[256]; 11 | strcpy(rev, argv[1]); 12 | 13 | _rev_parse(rev, sha1_string); 14 | 15 | printf("%s\n", sha1_string); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /manualtest/006a74a39f29e88405d5efe16d04b88bdd315614.tree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DQNEO/minigit/2326c231e8e2824546209115950c199afbe5f53e/manualtest/006a74a39f29e88405d5efe16d04b88bdd315614.tree -------------------------------------------------------------------------------- /manualtest/006b9f78eb6177c5284ba17158f78bf165d7383e.tree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DQNEO/minigit/2326c231e8e2824546209115950c199afbe5f53e/manualtest/006b9f78eb6177c5284ba17158f78bf165d7383e.tree -------------------------------------------------------------------------------- /manualtest/01_cat-file.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # cat-file のテスト 4 | # 5 | # gitとminigitでcat-fileの出力結果が同じであるかをテストする 6 | # 7 | # Usage: 8 | # [thiscommand] /path/to/repo 9 | # 10 | # TODO バイナリファイルだとdiffが一致しないことがあるのが謎 11 | 12 | set -e 13 | 14 | repo_dir=$1 15 | CUR_DIR=$(cd $(dirname $0); pwd) 16 | MINIGIT=$CUR_DIR/../minigit 17 | 18 | if [ $# -eq 0 ] ; then 19 | echo "Usage: $0 /path/to/repo" 20 | exit 1 21 | fi 22 | 23 | function list_objects () { 24 | find .git/objects/[^pi]* -type f | while read line ; do ( echo ${line#.git/objects/} | sed -e s#/##) ; done 25 | } 26 | 27 | function compare_t () { 28 | echo "=== compare cat-file -t ====" 29 | list_objects | while read hash 30 | do 31 | if [ $($MINIGIT cat-file -t $hash) == $(git cat-file -t $hash) ] ; then 32 | echo ok $hash 33 | else 34 | echo ng $hash 35 | exit 1 36 | fi 37 | done 38 | } 39 | 40 | function compare_s () { 41 | echo "=== compare cat-file -s ====" 42 | list_objects | while read hash 43 | do 44 | if [ $($MINIGIT cat-file -s $hash) == $(git cat-file -s $hash) ] ; then 45 | echo ok $hash 46 | else 47 | echo ng $hash 48 | exit 1 49 | fi 50 | done 51 | } 52 | 53 | function compare_p () { 54 | echo "=== compare cat-file -p ====" 55 | list_objects | while read hash 56 | do 57 | if [ "$($MINIGIT cat-file -p $hash)" == "$(git cat-file -p $hash)" ] ; then 58 | echo ok $hash 59 | else 60 | echo ng $hash 61 | exit 1 62 | fi 63 | done 64 | } 65 | 66 | # main 67 | cd $repo_dir 68 | 69 | # minigit cat-file -p はバグがある! 70 | compare_p 71 | compare_s 72 | compare_t 73 | -------------------------------------------------------------------------------- /manualtest/02bb82bb5e082cf9f359e6e33ae94e304991b00c.blob: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DQNEO/minigit/2326c231e8e2824546209115950c199afbe5f53e/manualtest/02bb82bb5e082cf9f359e6e33ae94e304991b00c.blob -------------------------------------------------------------------------------- /manualtest/README.md: -------------------------------------------------------------------------------- 1 | # Manual Test of minigi 2 | 3 | .git/objects を扱うテストを自動化しようとすると、サンプルオブジェクトを準備するのが大変なので、 4 | その仕組みができるまでは(半)手動テストでテストする 5 | 6 | ## cat-fileのテスト 7 | 8 | 任意のGitレポジトリの `find .git/objects/[^pi]* -type f` の結果を、minigit とgit のcat-fileで比較すればテストできる。 9 | 10 | ### cat-file -pのバグ 11 | `minigit cat-file -p manualtest/006b9f78eb6177c5284ba17158f78bf165d7383e.tree` でセグフォる。 (解決済み!) 12 | 13 | `minigit cat-file -p manualtest/02bb82bb5e082cf9f359e6e33ae94e304991b00c.blob` でinflateエラー(解決済み!) 14 | 15 | `./zlib_okumura/zlib -d manualtest/02bb82bb5e082cf9f359e6e33ae94e304991b00c.blob` は動く 16 | 17 | 18 | `./minigit cat-file -p manualtest/006a74a39f29e88405d5efe16d04b88bdd315614.tree`の結果がおかしい 19 | 20 | -------------------------------------------------------------------------------- /minigit.c: -------------------------------------------------------------------------------- 1 | #include "minigit.h" 2 | 3 | /** 4 | * @return bool 5 | */ 6 | int is_git_directory(const char *suspect) 7 | { 8 | char path_to_gitdir[PATH_MAX + 1]; 9 | strcpy(path_to_gitdir, suspect); 10 | strcpy(path_to_gitdir + strlen(suspect), "/.git"); 11 | if (access(path_to_gitdir, X_OK)) { 12 | return 0; // false 13 | } 14 | 15 | return 1; // true 16 | } 17 | 18 | 19 | int find_git_root_directory(char* cwd, size_t cwd_size) 20 | { 21 | int offset; 22 | 23 | if (!getcwd(cwd, cwd_size - 1)) { 24 | fprintf(stderr, "Unable to read cwd"); 25 | return 1; 26 | } 27 | offset = strlen(cwd); 28 | 29 | while (offset > 1) { 30 | if (is_git_directory(cwd)) { 31 | printf(".git found: %s/.git\n", cwd); 32 | return 0; 33 | } 34 | 35 | while (offset-- && cwd[offset] != '/') ; 36 | cwd[offset] = '\0'; 37 | } 38 | 39 | return 0; 40 | } 41 | 42 | void pretty_print_tree_object(object_info *oi) 43 | { 44 | 45 | //ヘッダー部は読み飛ばす 46 | char *cp = oi->buf + oi->header_length; 47 | //ボディのサイズはヘッダに書かれてあるのを参照する 48 | char *end = oi->buf + oi->header_length + oi->size; 49 | 50 | while (cp < end) { 51 | 52 | char mode[6]; 53 | char *filename; 54 | 55 | int j = 0; 56 | 57 | char *obj_type; 58 | 59 | // filemode 60 | // 6桁または5桁。' 'で終端 61 | while (*cp != ' ') { 62 | mode[j++] = *(cp++); 63 | } 64 | mode[j] = 0; 65 | 66 | if (strlen(mode) == 5) { 67 | obj_type = "tree"; 68 | } else { 69 | obj_type = "blob"; 70 | } 71 | 72 | cp++; // skip ' ' 73 | 74 | // filename 75 | // nullで終端 76 | filename = cp; 77 | while(*cp++) { 78 | } 79 | 80 | //sha1 81 | //固定長で20文字 82 | char *sha1_string = sha1_to_hex((unsigned char *)cp); 83 | 84 | cp += 20; 85 | 86 | // pretty print 87 | printf("%06d %s %s\t%s\n", 88 | atoi(mode), 89 | obj_type, 90 | sha1_string, 91 | filename 92 | ); 93 | 94 | continue; 95 | } 96 | 97 | 98 | } 99 | 100 | /** 101 | * test if a string is a substring of another; 102 | * @return bool 103 | */ 104 | int is_substr(const char *s,const char *l) 105 | { 106 | while (*s) { 107 | if (*(s++) != *(l++)) { 108 | return 0; 109 | } 110 | } 111 | 112 | return 1; 113 | } 114 | 115 | void validate_sha1(const char *sha1_input) 116 | { 117 | // no problem if emtpy string 118 | if (*sha1_input == '\0') { 119 | return; 120 | } 121 | //防御的プログラミング!ってこうですか>< 122 | if ( !('0' <= *sha1_input && *sha1_input <= '9' ) && 123 | !('a' <= *sha1_input && *sha1_input <= 'f') ) { 124 | fprintf(stderr, "invalid sha1 :%s\n", sha1_input); 125 | exit(1); 126 | } 127 | } 128 | 129 | /** 130 | * @return 0:OK -1:not found 131 | */ 132 | int find_file(const char *sha1_input, char *matched_filename) 133 | { 134 | int ret = -1; 135 | validate_sha1(sha1_input); 136 | 137 | char sha1_input_firsrt2chars[3]; 138 | const char *sha1_input_from3rd = &sha1_input[2]; 139 | 140 | //printf("3rd = %s\n", sha1_input_from3rd); 141 | sha1_input_firsrt2chars[0] = sha1_input[0]; 142 | sha1_input_firsrt2chars[1] = sha1_input[1]; 143 | sha1_input_firsrt2chars[2] = '\0'; 144 | //printf("sha1 first2 = %s\n", sha1_input_firsrt2chars); 145 | 146 | char dir[256] = ".git/objects/"; 147 | DIR *dp; 148 | struct dirent *entry; 149 | struct stat statbuf; 150 | 151 | strcat(dir, sha1_input_firsrt2chars); 152 | 153 | if(( dp = opendir(dir) ) == NULL ){ 154 | perror(dir); 155 | fprintf(stderr, "sha1_input = %s\n", sha1_input); 156 | exit( EXIT_FAILURE ); 157 | } 158 | 159 | while((entry = readdir(dp)) != NULL){ 160 | stat(entry->d_name, &statbuf); 161 | if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) { 162 | continue; 163 | } else { 164 | //printf("entry->d_name = %s\n", entry->d_name); 165 | 166 | //ユーザ入力のsha1とファイル名を比較して、 167 | //前者が後者の先頭部分一致すればそれが目的のオブジェクトであるとみなす。 168 | if (is_substr(sha1_input_from3rd, entry->d_name)) { 169 | // match! 170 | //printf("match :%s\n", entry->d_name ); 171 | strcpy(matched_filename, dir); 172 | strcat(matched_filename, "/"); 173 | strcat(matched_filename, entry->d_name); 174 | //printf("matched_filename = %s\n", matched_filename); 175 | //filename = matched_filename; 176 | ret = 0; 177 | break; 178 | } 179 | 180 | 181 | } 182 | 183 | } 184 | 185 | closedir(dp); 186 | 187 | return ret; 188 | } 189 | 190 | int _rev_parse(const char *_rev, char *sha1_string) 191 | { 192 | char filename[256] = {}; 193 | const char *dir = ".git/refs/heads/"; 194 | char rev[100]; 195 | //HEADの場合は強引にmasterに変更する 196 | if (strcmp(_rev, "HEAD") == 0) { 197 | strcpy(rev, "master"); 198 | } else { 199 | strcpy(rev, _rev); 200 | } 201 | 202 | //引数が40文字なら、強引にsha1とみなす。 203 | if (strlen(rev) == 40) { 204 | strcpy(sha1_string, rev); 205 | return 0; 206 | } 207 | strcat(filename, dir); 208 | strcat(filename, rev); 209 | 210 | FILE *fp; 211 | 212 | if ((fp = fopen(filename, "r")) == NULL) { 213 | fprintf(stderr, "_rev_parse:Can't open %s\n", filename); 214 | exit(1); 215 | } 216 | 217 | fgets(sha1_string, 41, fp); 218 | fclose(fp); 219 | 220 | return 0; 221 | } 222 | 223 | 224 | 225 | 226 | 227 | void pretty_print_commit_message(char *cp) 228 | { 229 | 230 | int start_of_new_line = 1; 231 | while (*cp) { 232 | 233 | if (start_of_new_line || *(cp -1) == '\n') { 234 | printf(" "); 235 | } 236 | 237 | printf("%c", *cp); 238 | cp++; 239 | start_of_new_line = 0; 240 | } 241 | 242 | } 243 | 244 | void parse_commit_object(object_info *oi, commit *pcmt) 245 | { 246 | //ヘッダー部は読み飛ばす 247 | char *cp = oi->buf + oi->header_length; 248 | //ボディのサイズはヘッダに書かれてあるのを参照する 249 | //char *end = oi->buf + oi->header_length + oi->size; 250 | 251 | char tree_sha1[41]; 252 | char parent_sha1[41]; 253 | char author_name[256]; 254 | char frmted_time[256]; 255 | 256 | /** 257 | * spec of commit object body 258 | * ------- 259 | * tree 260 | * parent 261 | * [parent 262 | * author .... 263 | * committer .... 264 | * 265 | * message 266 | * -------- 267 | */ 268 | 269 | // skip 'tree ' 270 | cp += 5; 271 | int i = 0; 272 | 273 | while (*cp != '\n') { 274 | tree_sha1[i++] = *(cp++); 275 | } 276 | tree_sha1[40] = '\0'; 277 | 278 | cp++; 279 | 280 | // skip 'parent ' 281 | if (*cp == 'p') { 282 | cp += 7; 283 | i = 0; 284 | while (*cp != '\n') { 285 | parent_sha1[i++] = *(cp++); 286 | } 287 | parent_sha1[40] = '\0'; 288 | cp++; // skip '\n' 289 | } else { 290 | memset(parent_sha1, '\0', 41); 291 | } 292 | 293 | validate_sha1(parent_sha1); 294 | //マージコミットの場合はまたparentがある。 295 | 296 | cp += 7; // skip 'author ' 297 | i = 0; 298 | while (*cp != '>') { 299 | author_name[i++] = *(cp++); 300 | } 301 | 302 | author_name[i++] = *(cp++); 303 | author_name[i] = '\0'; 304 | 305 | cp++; //skip ' ' 306 | char str_timestamp[11]; 307 | for (i=0;i<10;i++) { 308 | str_timestamp[i] = *(cp++); 309 | } 310 | str_timestamp[10] = '\0'; 311 | 312 | char timediff[6]; 313 | cp++; //skip ' ' 314 | 315 | for (i=0;i<5;i++) { 316 | timediff[i] = *(cp++); 317 | } 318 | timediff[5] = '\0'; 319 | 320 | while (*(++cp) != '\n') ; 321 | cp+=2; //skip \n and \n 322 | 323 | time_t t; 324 | t = atoi(str_timestamp); 325 | struct tm *tm; 326 | 327 | int tz = atoi(timediff); 328 | 329 | tm = time_to_tm(t, tz); 330 | 331 | // see show_date in date.c#L207 332 | sprintf(frmted_time ,"%.3s %.3s %d %02d:%02d:%02d %d%c%+05d", 333 | weekday_names[tm->tm_wday], 334 | month_names[tm->tm_mon], 335 | tm->tm_mday, 336 | tm->tm_hour, tm->tm_min, tm->tm_sec, 337 | tm->tm_year + 1900, 338 | ' ', 339 | tz 340 | ); 341 | 342 | strcpy(pcmt->tree_sha1, tree_sha1); 343 | strcpy(pcmt->parent_sha1, parent_sha1); 344 | strcpy(pcmt->frmted_time, frmted_time); 345 | strcpy(pcmt->author_name, author_name); 346 | pcmt->message = cp; 347 | } 348 | 349 | int cat_commit_object(const char *sha1_string, char *parent_sha1) 350 | { 351 | struct _TAG_OBJECT_INFO oi; 352 | char buf[OUTBUFSIZ]; 353 | 354 | 355 | oi.header_length = 0; 356 | 357 | //引数をsha1(の短縮文字列)とみなす 358 | char found_filename[256]; 359 | const char *sha1_input = sha1_string; 360 | if (find_file(sha1_input, found_filename) == -1) { 361 | fprintf(stderr, "file not found: %s\n", found_filename); 362 | exit(1); 363 | } 364 | 365 | oi.buf = buf; 366 | parse_object_header(found_filename, &oi); 367 | read_object_body(found_filename, &oi); 368 | 369 | commit cmt; 370 | commit *pcmt = &cmt; 371 | 372 | parse_commit_object(&oi, pcmt); 373 | 374 | // print commit 375 | printf("commit %s\n", sha1_string); 376 | 377 | 378 | strcpy(parent_sha1 , pcmt->parent_sha1); 379 | 380 | printf("Author: %s\n", pcmt->author_name); 381 | printf("Date: %s\n", pcmt->frmted_time); 382 | //printf("Parent: %s\n", pcmt->parent_sha1); 383 | printf("\n"); 384 | pretty_print_commit_message(pcmt->message); 385 | printf("\n"); 386 | 387 | return 0; 388 | } 389 | 390 | 391 | 392 | void usage() { 393 | fprintf(stdout, "Usage: %s []\n" , PROGNAME); 394 | fprintf(stdout, " cat-file: (-s|-t|-p) \n"); 395 | fprintf(stdout, " rev-parse (HEAD|branchanme)\n"); 396 | fprintf(stdout, " log: (HEAD|branchname)\n"); 397 | fprintf(stdout, " ls-files [--stage]\n"); 398 | fprintf(stdout, " hash-object [-w] \n"); 399 | } 400 | 401 | void show_version() { 402 | fprintf(stdout, "%s v0.0.2 by DQNEO\n", PROGNAME); 403 | } 404 | 405 | 406 | int update_ref(const char *new_sha1_string) 407 | { 408 | char *filename = ".git/refs/heads/master"; 409 | FILE *fp; 410 | if ((fp = fopen(filename, "w")) == NULL) { 411 | fprintf(stderr, "unable to open %s\n", filename); 412 | exit(1); 413 | } 414 | 415 | fprintf(fp,"%s\n", new_sha1_string); 416 | fclose(fp); 417 | 418 | return 1; 419 | } 420 | 421 | 422 | int main(int argc, char *argv[]) 423 | { 424 | if (argc == 1) { 425 | usage(); 426 | exit(0); 427 | } 428 | 429 | char *sub_cmd = argv[1]; 430 | argc--; 431 | argv++; 432 | 433 | if (strcmp(sub_cmd, "cat-file") == 0) { 434 | return cmd_cat_file(argc, argv); 435 | } else if (strcmp(sub_cmd, "log") == 0) { 436 | return cmd_log(argc, argv); 437 | } else if (strcmp(sub_cmd, "rev-parse") == 0) { 438 | return cmd_rev_parse(argc, argv); 439 | } else if (strcmp(sub_cmd, "init") == 0) { 440 | return cmd_init(argc, argv); 441 | } else if (strcmp(sub_cmd, "hash-object") == 0) { 442 | return cmd_hash_object(argc, argv); 443 | } else if (strcmp(sub_cmd, "commit") == 0) { 444 | return cmd_commit(argc, argv); 445 | } else if (strcmp(sub_cmd, "ls-files") == 0) { 446 | return cmd_ls_files(argc, argv); 447 | } else if (strcmp(sub_cmd, "--version") == 0) { 448 | show_version(); 449 | exit(0); 450 | } else if (strcmp(sub_cmd, "--help") == 0) { 451 | usage(); 452 | exit(0); 453 | } else { 454 | fprintf(stderr, "%s: '%s' is not a %s command.\n\n", PROGNAME, sub_cmd, PROGNAME); 455 | usage(); 456 | exit(0); 457 | } 458 | 459 | return 0; 460 | } 461 | -------------------------------------------------------------------------------- /minigit.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | // opendir 11 | #include 12 | #include 13 | 14 | // for calculate sha1 15 | #include 16 | 17 | /* zlib sample code */ 18 | /* http://oku.edu.mie-u.ac.jp/~okumura/compression/comptest.c */ 19 | #include 20 | 21 | #ifndef __APPLE__ 22 | #include 23 | #endif /* __APPLE__ */ 24 | #include 25 | 26 | typedef struct _TAG_OBJECT_INFO { 27 | char type[20]; 28 | int size; 29 | int header_length; // ヘッダのバイト長 30 | char *buf; 31 | } object_info; 32 | 33 | typedef struct _TAG_COMMIT { 34 | char tree_sha1[41]; 35 | char parent_sha1[41]; 36 | char author_name[256]; 37 | char frmted_time[256]; 38 | char *message; 39 | } commit; 40 | 41 | #define INBUFSIZ 1024 42 | #define OUTBUFSIZ 1024 43 | 44 | #ifndef PATH_MAX 45 | #define PATH_MAX 1024 46 | #endif 47 | 48 | #define PROGNAME "minigit" 49 | 50 | //borrowed from git 51 | //extern int errno; 52 | typedef struct git_zstream { 53 | z_stream z; 54 | unsigned long avail_in; 55 | unsigned long avail_out; 56 | unsigned long total_in; 57 | unsigned long total_out; 58 | unsigned char *next_in; 59 | unsigned char *next_out; 60 | } git_zstream; 61 | #define git_SHA_CTX SHA_CTX 62 | 63 | void parse_object_header(char in_file_name[], object_info *oi); 64 | void read_object_body(char in_file_name[], object_info *oi); 65 | 66 | char *sha1_to_hex(const unsigned char *sha1); 67 | void calc_sha1(const char *type, const void *body, unsigned long len, unsigned char *sha1); 68 | 69 | struct tm *time_to_tm(unsigned long time, int tz); 70 | 71 | extern const char *weekday_names[]; 72 | extern const char *month_names[]; 73 | 74 | void git_write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen, 75 | const void *buf, unsigned long len, time_t mtime); 76 | 77 | void sha1_file_name(const unsigned char *sha1, char *filename); 78 | 79 | int cmd_cat_file(int argc, char **argv); 80 | int cmd_log(int argc, char **argv); 81 | int cmd_rev_parse(int argc, char **argv); 82 | int cmd_init(int argc, char **argv); 83 | int cmd_commit(int argc, char **argv); 84 | int cmd_hash_object(int argc, char **argv); 85 | int cmd_ls_files(int argc, char **argv); 86 | 87 | int _rev_parse(const char *_rev, char *sha1_string); 88 | int cat_commit_object(const char *sha1_string, char *parent_sha1); 89 | int find_file(const char *sha1_input, char *matched_filename); 90 | void pretty_print_tree_object(object_info *oi); 91 | 92 | #include "cache.h" 93 | 94 | int is_git_directory(const char *suspect); 95 | int find_git_root_directory(char* cwd, size_t cwd_size); 96 | -------------------------------------------------------------------------------- /sha1.c: -------------------------------------------------------------------------------- 1 | #include "minigit.h" 2 | 3 | /** 4 | * get into string sha1 from binary sha1 5 | * 6 | * this function is totally borrowed from hex.c of git :) 7 | */ 8 | char *sha1_to_hex(const unsigned char *sha1) 9 | { 10 | static int bufno; 11 | static char hexbuffer[4][50]; 12 | static const char hex[] = "0123456789abcdef"; 13 | char *buffer = hexbuffer[3 & ++bufno], *buf = buffer; 14 | int i; 15 | 16 | for (i = 0; i < 20; i++) { 17 | unsigned int val = *sha1++; 18 | *buf++ = hex[val >> 4]; 19 | *buf++ = hex[val & 0xf]; 20 | } 21 | *buf = '\0'; 22 | 23 | return buffer; 24 | } 25 | 26 | void calc_sha1(const char *type, const void *body, unsigned long len, unsigned char *sha1) 27 | { 28 | int hdrlen; 29 | char hdr[256]; 30 | SHA_CTX c; 31 | 32 | sprintf(hdr, "%s %ld", type, len); 33 | hdrlen = strlen(hdr) + 1; 34 | 35 | SHA1_Init(&c); 36 | SHA1_Update(&c, hdr, hdrlen); 37 | SHA1_Update(&c, body, len); 38 | SHA1_Final(sha1, &c); 39 | 40 | } 41 | 42 | void sha1_file_name(const unsigned char *sha1, char *filename) 43 | { 44 | const char *objdir = ".git/objects"; 45 | int len; 46 | char *str_sha1 = sha1_to_hex(sha1); 47 | int i; 48 | 49 | len = strlen(objdir); 50 | strcpy(filename, objdir); 51 | filename[len] = '/'; 52 | filename[len+3] = '/'; 53 | 54 | filename[len+1] = str_sha1[0]; 55 | filename[len+2] = str_sha1[1]; 56 | 57 | for (i=2;i<40;i++) { 58 | filename[len+2+i] = str_sha1[i]; 59 | } 60 | filename[len + 42] = '\0'; 61 | } 62 | 63 | void sha1_dir_name(const unsigned char *sha1, char *dirname) 64 | { 65 | const char *objdir = ".git/objects"; 66 | int len; 67 | char *str_sha1 = sha1_to_hex(sha1); 68 | 69 | len = strlen(objdir); 70 | strcpy(dirname, objdir); 71 | dirname[len] = '/'; 72 | dirname[len+1] = str_sha1[0]; 73 | dirname[len+2] = str_sha1[1]; 74 | dirname[len+3] = '\0'; 75 | } 76 | -------------------------------------------------------------------------------- /t/commit.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | use strict; 3 | use warnings; 4 | use autodie; 5 | use Test::More; 6 | 7 | our $PROGNAME = 'minigit'; 8 | 9 | diag('commit'); 10 | 11 | my ($cmd, $ret, $exp, $ret_val); 12 | 13 | my $old_commit_sha1 = `./$PROGNAME rev-parse HEAD`; 14 | ok $old_commit_sha1, "old sha1 " . $old_commit_sha1; 15 | 16 | diag('output echo-backs commit message'); 17 | $cmd = "./$PROGNAME commit -m hoge"; 18 | my $buffer = `$cmd`; 19 | is $?, 0, 'commit exit 0'; 20 | diag($buffer); 21 | #ok $buffer =~ /hoge/, 'output has commit message'; 22 | #ok $buffer =~ /badcafe/, 'output has commit sha1'; 23 | 24 | my $new_commit_sha1 = `./$PROGNAME rev-parse HEAD`; 25 | #is $new_commit_sha1 ,"badcafe890123456789012345678901234567890\n", 'sha1 changed'; 26 | 27 | # recover ref file 28 | #open my $fh, '>', '.git/refs/heads/master'; 29 | #print $fh $old_commit_sha1; 30 | #close $fh; 31 | 32 | done_testing(); 33 | -------------------------------------------------------------------------------- /t/hash-object.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | use strict; 3 | use warnings; 4 | use autodie; 5 | use Test::More; 6 | 7 | our $PROGNAME = 'minigit'; 8 | 9 | diag('hash-object'); 10 | 11 | my ($cmd, $ret, $exp); 12 | 13 | $cmd = "./$PROGNAME hash-object t/hello.txt"; 14 | $ret = `$cmd`; 15 | $exp = "ce013625030ba8dba906f756967f9e9ca394464a\n"; 16 | is $ret, $exp, $cmd; 17 | 18 | diag('hash-object -w'); 19 | my $tmp_filename = "hello_" . time(). '.txt'; 20 | my $content = $tmp_filename . "\n"; 21 | open my $fh , '>', $tmp_filename; 22 | print $fh $content; 23 | close $fh; 24 | 25 | $cmd = "./$PROGNAME hash-object -w $tmp_filename"; 26 | my $sha1 = `$cmd` or die "cannot " . $cmd; 27 | chomp $sha1; 28 | ok $sha1, "sha1 is " . $sha1; 29 | 30 | =begin 31 | $cmd = "./$PROGNAME cat-file -p $sha1"; 32 | $ret = `$cmd` or die "failed " . $cmd; 33 | print "$cmd\n"; 34 | #is $ret, $content, 'verify hash-object -w by cat-file -p'; 35 | =cut 36 | unlink $tmp_filename; 37 | 38 | done_testing(); 39 | -------------------------------------------------------------------------------- /t/hello.txt: -------------------------------------------------------------------------------- 1 | hello 2 | -------------------------------------------------------------------------------- /t/init.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | use strict; 3 | use warnings; 4 | use Test::More; 5 | use FindBin qw($Bin); 6 | use lib "$Bin/lib"; 7 | use MyLib qw(slurp); 8 | our $PROGNAME = 'minigit'; 9 | 10 | diag('cmd init'); 11 | 12 | # prepare 13 | 14 | my $tmp_dir = "/tmp/" . $PROGNAME . "_test"; 15 | system("rm -rf $tmp_dir") if -d $tmp_dir; 16 | 17 | mkdir $tmp_dir 18 | or die "cannot mkdir " . $tmp_dir; 19 | chdir $tmp_dir 20 | or die "cannot chdir " . $tmp_dir; 21 | 22 | my $ret_val = system "minigit init"; 23 | 24 | is $ret_val, 0, "exit value of init"; 25 | 26 | # assure existance of dirs 27 | # .git/objects/ 28 | # .git/refs/ 29 | ok -d $tmp_dir, ".git"; 30 | ok -d $tmp_dir . "/.git/objects", ".git/objects"; 31 | ok -d $tmp_dir . "/.git/refs", ".git/refs"; 32 | 33 | is slurp($tmp_dir . "/.git/HEAD"), "ref: refs/heads/master\n", ".git/HEAD"; 34 | 35 | 36 | # clean 37 | #ok system("rm -rf $tmp_dir") == 0, "clean"; 38 | 39 | done_testing(); 40 | 41 | =pod 42 | git init のテスト 43 | /tmp/下でgit initして各種ディレクトリをセットアップ 44 | 終わったらゴミ掃除 45 | =end 46 | 47 | -------------------------------------------------------------------------------- /t/lib/MyLib.pm: -------------------------------------------------------------------------------- 1 | package MyLib; 2 | use base 'Exporter'; 3 | our @EXPORT_OK = qw/slurp/; 4 | 5 | sub slurp { 6 | my $filename = shift; 7 | local $/; 8 | open my $fh, '<', $filename; 9 | return <$fh>; 10 | } 11 | 12 | 1; 13 | -------------------------------------------------------------------------------- /t/objects/0067b.commit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DQNEO/minigit/2326c231e8e2824546209115950c199afbe5f53e/t/objects/0067b.commit -------------------------------------------------------------------------------- /t/objects/0067b.commit.txt: -------------------------------------------------------------------------------- 1 | tree fef8e12d40dbc12f1250b7aef736728ec88d0b92 2 | parent f4834a87b8f10793cafba950ebbab0be19b70ab5 3 | author DQNEO 1380402413 +0000 4 | committer DQNEO 1380402413 +0000 5 | 6 | refactor 7 | -------------------------------------------------------------------------------- /t/objects/16a29.commit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DQNEO/minigit/2326c231e8e2824546209115950c199afbe5f53e/t/objects/16a29.commit -------------------------------------------------------------------------------- /t/objects/16a29.commit.txt: -------------------------------------------------------------------------------- 1 | tree 5b9f3012a05d3fb532d3ec043a5f46f62dbeecf5 2 | parent 530afd558f48a79b6f743e2daa0660285dda3562 3 | author DQNEO 1380565501 +0000 4 | committer DQNEO 1380565501 +0000 5 | 6 | refactor 7 | -------------------------------------------------------------------------------- /t/objects/1e863.tree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DQNEO/minigit/2326c231e8e2824546209115950c199afbe5f53e/t/objects/1e863.tree -------------------------------------------------------------------------------- /t/objects/1e863.tree.txt: -------------------------------------------------------------------------------- 1 | 100644 blob b50817bbc3c2f19347eb486dbef5fe1dbbac4b8c comptest.c 2 | 100644 blob da7b3fc16375e4b36fe4d426f88ba46b8bf8f104 zlib.c 3 | 100644 blob eb790f2ebfb405d57a6c1656d87af9b0471be2f5 zlib_simple.c 4 | -------------------------------------------------------------------------------- /t/objects/1to100.blob: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DQNEO/minigit/2326c231e8e2824546209115950c199afbe5f53e/t/objects/1to100.blob -------------------------------------------------------------------------------- /t/objects/1to100.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 6 | 6 7 | 7 8 | 8 9 | 9 10 | 10 11 | 11 12 | 12 13 | 13 14 | 14 15 | 15 16 | 16 17 | 17 18 | 18 19 | 19 20 | 20 21 | 21 22 | 22 23 | 23 24 | 24 25 | 25 26 | 26 27 | 27 28 | 28 29 | 29 30 | 30 31 | 31 32 | 32 33 | 33 34 | 34 35 | 35 36 | 36 37 | 37 38 | 38 39 | 39 40 | 40 41 | 41 42 | 42 43 | 43 44 | 44 45 | 45 46 | 46 47 | 47 48 | 48 49 | 49 50 | 50 51 | 51 52 | 52 53 | 53 54 | 54 55 | 55 56 | 56 57 | 57 58 | 58 59 | 59 60 | 60 61 | 61 62 | 62 63 | 63 64 | 64 65 | 65 66 | 66 67 | 67 68 | 68 69 | 69 70 | 70 71 | 71 72 | 72 73 | 73 74 | 74 75 | 75 76 | 76 77 | 77 78 | 78 79 | 79 80 | 80 81 | 81 82 | 82 83 | 83 84 | 84 85 | 85 86 | 86 87 | 87 88 | 88 89 | 89 90 | 90 91 | 91 92 | 92 93 | 93 94 | 94 95 | 95 96 | 96 97 | 97 98 | 98 99 | 99 100 | 100 101 | -------------------------------------------------------------------------------- /t/objects/44495.tree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DQNEO/minigit/2326c231e8e2824546209115950c199afbe5f53e/t/objects/44495.tree -------------------------------------------------------------------------------- /t/objects/44495.tree.txt: -------------------------------------------------------------------------------- 1 | 100755 blob e0c5c17c3c8e77b16915c64044df78df8f199acb 01_test.t 2 | 040000 tree 50f638389031dc69e5b6896c52390f51b167a237 objects 3 | -------------------------------------------------------------------------------- /t/objects/f135c.tree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DQNEO/minigit/2326c231e8e2824546209115950c199afbe5f53e/t/objects/f135c.tree -------------------------------------------------------------------------------- /t/objects/f135c.tree.txt: -------------------------------------------------------------------------------- 1 | 100644 blob 474cd9cf068d847849aff68bb22b6751ee4a81ac .gitignore 2 | 100644 blob 6f6b508e9dce41c2c91affe5bd1171745b354441 Makefile 3 | 100644 blob d61906f2845121e65e6d8259899d927accb8ddcb README.md 4 | 040000 tree 1e863fa3a6e77eae1e483df763319af889132264 c_samples 5 | 100644 blob f1d47fe1c0919c10d128469cb11553b1798132f5 minigit.c 6 | 100644 blob 726db2ccd618a481a2f5bf265fc0b3756fbea5cc print_char.c 7 | 040000 tree 44495bebe937b416f930f689391972f4e8405914 t 8 | -------------------------------------------------------------------------------- /t/objects/hello_world.blob: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DQNEO/minigit/2326c231e8e2824546209115950c199afbe5f53e/t/objects/hello_world.blob -------------------------------------------------------------------------------- /t/rev_parse.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | use strict; 3 | use warnings; 4 | use Test::More; 5 | 6 | our $PROGNAME = 'minigit'; 7 | diag('rev-parse'); 8 | 9 | my ($cmd, $ret, $exp); 10 | 11 | my @commands = ( 12 | 'rev-parse', 13 | 'rev-parse HEAD', 14 | ); 15 | 16 | for my $cmd (@commands) { 17 | $ret = `$PROGNAME $cmd`; 18 | $exp = `git $cmd`; 19 | is $ret, $exp, $cmd; 20 | } 21 | 22 | done_testing(); 23 | -------------------------------------------------------------------------------- /t/test.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | use strict; 3 | use warnings; 4 | use autodie; 5 | use Test::More; 6 | use FindBin qw($Bin); 7 | use lib "$Bin/lib"; 8 | use MyLib qw(slurp); 9 | # test blob object 10 | diag('blob object'); 11 | 12 | my ($ret, $exp, $cmd); 13 | 14 | diag 'cat-file -s'; 15 | $ret = `./minigit cat-file -s t/objects/hello_world.blob`; 16 | $exp = "12\n"; 17 | is $ret, $exp; 18 | 19 | $ret = `./minigit cat-file -s t/objects/f135c.tree`; 20 | $exp = "252\n"; 21 | is $ret, $exp; 22 | 23 | diag 'cat-file -t'; 24 | $ret = `./minigit cat-file -t t/objects/hello_world.blob`; 25 | $exp = "blob\n"; 26 | is $ret, $exp; 27 | 28 | $ret = `./minigit cat-file -t t/objects/f135c.tree`; 29 | $exp = "tree\n"; 30 | is $ret, $exp; 31 | 32 | # cat-file-p 33 | $ret = `./minigit cat-file -p t/objects/hello_world.blob`; 34 | $exp = "hello world 35 | "; 36 | 37 | is $ret, $exp; 38 | 39 | # test tree object 40 | diag('cat tree object'); 41 | 42 | my @sha1_list = ('1e863', '44495', 'f135c'); 43 | 44 | for my $sha1_short (@sha1_list) { 45 | $ret = `./minigit cat-file -p t/objects/$sha1_short.tree`; 46 | 47 | $exp = slurp("t/objects/$sha1_short.tree.txt"); 48 | is $ret, $exp, 'tree ' . $sha1_short; 49 | } 50 | 51 | diag('test commit object'); 52 | 53 | my @commits = ('0067b', '16a29'); 54 | 55 | for my $commit (@commits) { 56 | $ret = `./minigit cat-file -p t/objects/$commit.commit`; 57 | $ret =~ s/gmail/example/g; 58 | 59 | $exp = slurp("t/objects/$commit.commit.txt"); 60 | is $ret, $exp, 'commit ' . $commit; 61 | } 62 | 63 | done_testing(); 64 | 65 | 66 | 67 | =pod 68 | diag('test log HEAD'); 69 | $ret = `./minigit log HEAD`; 70 | $exp = "sha1=badcafe\n"; 71 | 72 | is $ret , $exp, 'log HEAD'; 73 | 74 | diag('test log'); 75 | $ret = `./minigit log`; 76 | $exp = "sha1=badcafe\n"; 77 | 78 | is $ret , $exp, 'log'; 79 | =end 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /time.c: -------------------------------------------------------------------------------- 1 | #include "minigit.h" 2 | 3 | const char *weekday_names[] = { 4 | "Sunday", "Mondays", "Tuesdays", "Wednesdays", "Thursdays", "Fridays", "Saturdays" 5 | }; 6 | 7 | const char *month_names[] = { 8 | "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" 9 | }; 10 | 11 | /** 12 | * git:date.cのtime_to_tmおよびgm_time_tから借用 13 | */ 14 | struct tm *time_to_tm(unsigned long time, int tz) 15 | { 16 | int minutes; 17 | 18 | minutes = tz < 0 ? -tz : tz; 19 | minutes = (minutes / 100)*60 + (minutes % 100); 20 | minutes = tz < 0 ? -minutes : minutes; 21 | time_t t = (time_t) time + minutes * 60; 22 | return gmtime(&t); 23 | } 24 | -------------------------------------------------------------------------------- /zlib.c: -------------------------------------------------------------------------------- 1 | #include "minigit.h" 2 | /** 3 | * parsing object 4 | */ 5 | void read_object_body(char in_file_name[], object_info *oi) 6 | { 7 | FILE *fin; 8 | 9 | if ((fin = fopen(in_file_name, "r")) == NULL) { 10 | fprintf(stderr, "Can't open %s\n", in_file_name); 11 | exit(1); 12 | } 13 | 14 | z_stream z; 15 | char inbuf[INBUFSIZ]; 16 | int status; 17 | 18 | z.zalloc = Z_NULL; 19 | z.zfree = Z_NULL; 20 | z.opaque = Z_NULL; 21 | 22 | size_t outbfsiz = oi->header_length + oi->size; 23 | oi->buf = malloc(outbfsiz); 24 | 25 | z.next_in = Z_NULL; 26 | z.avail_in = 0; 27 | if (inflateInit(&z) != Z_OK) { 28 | fprintf(stderr, "inflateInit: %s\n", (z.msg) ? z.msg : "???"); 29 | exit(1); 30 | } 31 | 32 | z.next_out = (Bytef *)oi->buf; /* 出力ポインタ */ 33 | z.avail_out = outbfsiz; /* 出力バッファ残量 */ 34 | status = Z_OK; 35 | 36 | while (status != Z_STREAM_END) { 37 | if (z.avail_in == 0) { /* 入力残量がゼロになれば */ 38 | z.next_in = (Bytef *)inbuf; /* 入力ポインタを元に戻す */ 39 | z.avail_in = fread(inbuf, 1, INBUFSIZ, fin); /* データを読む */ 40 | } 41 | status = inflate(&z, Z_NO_FLUSH); 42 | if (status == Z_STREAM_END) break; 43 | if (status != Z_OK) { 44 | fprintf(stderr, "inflate: %s\n", (z.msg) ? z.msg : "???"); 45 | exit(1); 46 | } 47 | if (z.avail_out == 0) { 48 | /* 出力バッファが尽きればループを抜ける */ 49 | break; 50 | } 51 | } 52 | 53 | /* 後始末 */ 54 | if (inflateEnd(&z) != Z_OK) { 55 | fprintf(stderr, "inflateEnd: %s\n", (z.msg) ? z.msg : "???"); 56 | exit(1); 57 | } 58 | 59 | fclose(fin); 60 | } 61 | 62 | 63 | void parse_header(char *header, object_info *oi) 64 | { 65 | int i = 0; 66 | char size[20]; 67 | 68 | while (*(header) != ' ') { 69 | oi->type[i++] = *(header++); 70 | oi->header_length++; 71 | } 72 | oi->type[i] = 0; 73 | oi->header_length++; 74 | 75 | header++; // skip ' ' 76 | oi->header_length++; 77 | 78 | i = 0; 79 | while (*header) { 80 | size[i++] = *(header++); 81 | oi->header_length++; 82 | } 83 | size[i] = 0; 84 | oi->size = atoi(size); 85 | } 86 | 87 | 88 | 89 | void parse_object_header(char in_file_name[], object_info *oi) 90 | { 91 | int status; 92 | 93 | z_stream z; /* ライブラリとやりとりするための構造体 */ 94 | 95 | char inbuf[INBUFSIZ]; /* 入力バッファ */ 96 | char header[OUTBUFSIZ]; 97 | 98 | FILE *fin; /* 入力・出力ファイル */ 99 | 100 | if ((fin = fopen(in_file_name, "r")) == NULL) { 101 | fprintf(stderr, "Can't open %s\n", in_file_name); 102 | exit(1); 103 | } 104 | 105 | 106 | /* すべてのメモリ管理をライブラリに任せる */ 107 | z.zalloc = Z_NULL; 108 | z.zfree = Z_NULL; 109 | z.opaque = Z_NULL; 110 | 111 | /* 初期化 */ 112 | z.next_in = Z_NULL; 113 | z.avail_in = 0; 114 | if (inflateInit(&z) != Z_OK) { 115 | fprintf(stderr, "inflateInit: %s\n", (z.msg) ? z.msg : "???"); 116 | exit(1); 117 | } 118 | 119 | z.next_out = (Bytef *) header; 120 | z.avail_out = sizeof(header); 121 | status = Z_OK; 122 | 123 | if (z.avail_in == 0) { /* 入力残量がゼロになれば */ 124 | z.next_in = (Bytef *) inbuf; /* 入力ポインタを元に戻す */ 125 | z.avail_in = fread(inbuf, 1, INBUFSIZ, fin); /* データを読む */ 126 | } 127 | 128 | /* 展開 */ 129 | status = inflate(&z, Z_NO_FLUSH); 130 | if (status != Z_STREAM_END && status != Z_OK) { 131 | fprintf(stderr, "inflate: %s\n", (z.msg) ? z.msg : "???"); 132 | exit(1); 133 | } 134 | 135 | /* 後始末 */ 136 | if (inflateEnd(&z) != Z_OK) { 137 | fprintf(stderr, "inflateEnd: %s\n", (z.msg) ? z.msg : "???"); 138 | exit(1); 139 | } 140 | 141 | fclose(fin); 142 | 143 | parse_header(header, oi); 144 | } 145 | 146 | 147 | /** 148 | * writing object 149 | */ 150 | #define ZLIB_BUF_MAX ((uInt) 1024 * 1024 * 1024) /* 1GB */ 151 | 152 | static inline uInt zlib_buf_cap(unsigned long len) 153 | { 154 | return (ZLIB_BUF_MAX < len) ? ZLIB_BUF_MAX : len; 155 | } 156 | 157 | static void zlib_pre_call(git_zstream *s) 158 | { 159 | s->z.next_in = s->next_in; 160 | s->z.next_out = s->next_out; 161 | s->z.total_in = s->total_in; 162 | s->z.total_out = s->total_out; 163 | s->z.avail_in = zlib_buf_cap(s->avail_in); 164 | s->z.avail_out = zlib_buf_cap(s->avail_out); 165 | } 166 | 167 | static void zlib_post_call(git_zstream *s) 168 | { 169 | unsigned long bytes_consumed; 170 | unsigned long bytes_produced; 171 | 172 | bytes_consumed = s->z.next_in - s->next_in; 173 | bytes_produced = s->z.next_out - s->next_out; 174 | if (s->z.total_out != s->total_out + bytes_produced) { 175 | printf("BUG: total_out mismatch"); 176 | exit(1); 177 | } 178 | if (s->z.total_in != s->total_in + bytes_consumed) { 179 | printf("BUG: total_in mismatch"); 180 | exit(1); 181 | } 182 | s->total_out = s->z.total_out; 183 | s->total_in = s->z.total_in; 184 | s->next_in = s->z.next_in; 185 | s->next_out = s->z.next_out; 186 | s->avail_in -= bytes_consumed; 187 | s->avail_out -= bytes_produced; 188 | } 189 | 190 | static const char *zerr_to_string(int status) 191 | { 192 | switch (status) { 193 | case Z_MEM_ERROR: 194 | return "out of memory"; 195 | case Z_VERSION_ERROR: 196 | return "wrong version"; 197 | case Z_NEED_DICT: 198 | return "needs dictionary"; 199 | case Z_DATA_ERROR: 200 | return "data stream error"; 201 | case Z_STREAM_ERROR: 202 | return "stream consistency error"; 203 | default: 204 | return "unknown error"; 205 | } 206 | } 207 | 208 | 209 | void git_deflate_init(git_zstream *strm, int level) 210 | { 211 | int status; 212 | 213 | zlib_pre_call(strm); 214 | status = deflateInit(&strm->z, level); 215 | zlib_post_call(strm); 216 | if (status == Z_OK) 217 | return; 218 | printf("deflateInit: %s (%s)", zerr_to_string(status), 219 | strm->z.msg ? strm->z.msg : "no message"); 220 | exit(1); 221 | } 222 | #define MAX_IO_SIZE (8*1024*1024) 223 | 224 | ssize_t xwrite(int fd, const void *buf, size_t len) 225 | { 226 | ssize_t nr; 227 | if (len > MAX_IO_SIZE) 228 | len = MAX_IO_SIZE; 229 | while (1) { 230 | nr = write(fd, buf, len); 231 | if ((nr < 0) ) 232 | continue; 233 | return nr; 234 | } 235 | } 236 | 237 | 238 | ssize_t write_in_full(int fd, const void *buf, size_t count) 239 | { 240 | const char *p = buf; 241 | ssize_t total = 0; 242 | 243 | while (count > 0) { 244 | ssize_t written = xwrite(fd, p, count); 245 | if (written < 0) 246 | return -1; 247 | if (!written) { 248 | // errno = 777; 249 | return -1; 250 | } 251 | count -= written; 252 | p += written; 253 | total += written; 254 | } 255 | 256 | return total; 257 | } 258 | 259 | static int write_buffer(int fd, const void *buf, size_t len) 260 | { 261 | if (write_in_full(fd, buf, len) < 0) 262 | exit(1); 263 | return 0; 264 | } 265 | 266 | int git_deflate(git_zstream *strm, int flush) 267 | { 268 | int status; 269 | 270 | for (;;) { 271 | zlib_pre_call(strm); 272 | 273 | /* Never say Z_FINISH unless we are feeding everything */ 274 | status = deflate(&strm->z, 275 | (strm->z.avail_in != strm->avail_in) 276 | ? 0 : flush); 277 | if (status == Z_MEM_ERROR) { 278 | printf("deflate: out of memory"); 279 | exit(1); 280 | } 281 | zlib_post_call(strm); 282 | 283 | /* 284 | * Let zlib work another round, while we can still 285 | * make progress. 286 | */ 287 | if ((strm->avail_out && !strm->z.avail_out) && 288 | (status == Z_OK || status == Z_BUF_ERROR)) 289 | continue; 290 | break; 291 | } 292 | 293 | switch (status) { 294 | /* Z_BUF_ERROR: normal, needs more space in the output buffer */ 295 | case Z_BUF_ERROR: 296 | case Z_OK: 297 | case Z_STREAM_END: 298 | return status; 299 | default: 300 | break; 301 | } 302 | printf("deflate: %s (%s)", zerr_to_string(status), 303 | strm->z.msg ? strm->z.msg : "no message"); 304 | return status; 305 | } 306 | 307 | int git_deflate_end_gently(git_zstream *strm) 308 | { 309 | int status; 310 | 311 | zlib_pre_call(strm); 312 | status = deflateEnd(&strm->z); 313 | zlib_post_call(strm); 314 | return status; 315 | } 316 | 317 | int zlib_compression_level = Z_BEST_SPEED; 318 | void git_write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen, 319 | const void *buf, unsigned long len, time_t mtime) 320 | { 321 | int fd, ret; 322 | unsigned char compressed[4096]; 323 | git_zstream stream; 324 | 325 | char filename[256]; 326 | 327 | sha1_file_name(sha1, filename); 328 | FILE *fp; 329 | fp = fopen("/tmp/git_tmpfile", "wb"); 330 | fd = fileno(fp); 331 | 332 | /* Set it up */ 333 | memset(&stream, 0, sizeof(stream)); 334 | git_deflate_init(&stream, zlib_compression_level); 335 | stream.next_out = compressed; 336 | stream.avail_out = sizeof(compressed); 337 | 338 | /* First header.. */ 339 | stream.next_in = (unsigned char *)hdr; 340 | stream.avail_in = hdrlen; 341 | while (git_deflate(&stream, 0) == Z_OK) 342 | ; /* nothing */ 343 | 344 | 345 | /* Then the data itself.. */ 346 | stream.next_in = (void *)buf; 347 | stream.avail_in = len; 348 | do { 349 | ret = git_deflate(&stream, Z_FINISH); 350 | 351 | if (write_buffer(fd, compressed, stream.next_out - compressed) < 0) 352 | printf("unable to write sha1 file"); 353 | stream.next_out = compressed; 354 | stream.avail_out = sizeof(compressed); 355 | } while (ret == Z_OK); 356 | 357 | if (ret != Z_STREAM_END) 358 | printf("unable to deflate new object %s (%d)", sha1_to_hex(sha1), ret); 359 | ret = git_deflate_end_gently(&stream); 360 | if (ret != Z_OK) 361 | printf("deflateEnd on object %s failed (%d)", sha1_to_hex(sha1), ret); 362 | 363 | 364 | fclose(fp); 365 | 366 | rename("/tmp/git_tmpfile", filename); 367 | return ; 368 | } 369 | -------------------------------------------------------------------------------- /zlib_git/.gitignore: -------------------------------------------------------------------------------- 1 | zlib.dSYM 2 | zlib 3 | /gen/ 4 | git_cat_file-p 5 | git_cat_file-p.dSYM/ 6 | -------------------------------------------------------------------------------- /zlib_git/Makefile: -------------------------------------------------------------------------------- 1 | zlib: zlib.c 2 | gcc -g -Wall -O0 -std=c99 -lz -o zlib zlib.c 3 | 4 | clean: 5 | rm zlib 6 | 7 | test: clean zlib 8 | ./zlib -c txts/helloworld.txt gen/helloworld && diff gen/helloworld compressed/helloworld && echo ok 9 | ./zlib -c txts/bocchan.txt gen/bocchan && diff gen/bocchan compressed/bocchan && echo ok 10 | 11 | git_cat_file-p: git_cat_file-p.c 12 | gcc -g -Wall -O0 -std=c99 -lz -o git_cat_file-p git_cat_file-p.c 13 | -------------------------------------------------------------------------------- /zlib_git/README.md: -------------------------------------------------------------------------------- 1 | # このディレクトリは何か? 2 | 3 | 下記の問題を解くための最小限の実装を試みる実験です。 4 | 5 | https://github.com/DQNEO/GitInternals/tree/master/git_objects 6 | -------------------------------------------------------------------------------- /zlib_git/compressed/bocchan: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DQNEO/minigit/2326c231e8e2824546209115950c199afbe5f53e/zlib_git/compressed/bocchan -------------------------------------------------------------------------------- /zlib_git/compressed/helloworld: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DQNEO/minigit/2326c231e8e2824546209115950c199afbe5f53e/zlib_git/compressed/helloworld -------------------------------------------------------------------------------- /zlib_git/gen/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DQNEO/minigit/2326c231e8e2824546209115950c199afbe5f53e/zlib_git/gen/.empty -------------------------------------------------------------------------------- /zlib_git/git_cat_file-p.c: -------------------------------------------------------------------------------- 1 | /** 2 | * git cat-file -p 相当のことをするコマンド 3 | * 4 | * original from http://oku.edu.mie-u.ac.jp/~okumura/compression/comptest.c 5 | * licensed under http://creativecommons.org/licenses/by/4.0/ 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define INBUFSIZ 1024 13 | #define OUTBUFSIZ 1024 14 | 15 | int _write_skipping_header(char *outbuf, size_t size, size_t n ,FILE *fout) 16 | { 17 | static int is_header = 1; 18 | int tmp_n = n; 19 | if (is_header) { 20 | while (*outbuf) {outbuf++; tmp_n--;} 21 | fwrite(outbuf, size, tmp_n, fout); 22 | is_header = 0; 23 | return n; 24 | } 25 | return fwrite(outbuf, size, n, fout); 26 | } 27 | 28 | void _decompress(FILE *fin, FILE *fout) 29 | { 30 | z_stream z; 31 | char inbuf[INBUFSIZ]; 32 | char outbuf[OUTBUFSIZ]; 33 | int count, status; 34 | 35 | z.zalloc = Z_NULL; 36 | z.zfree = Z_NULL; 37 | z.opaque = Z_NULL; 38 | 39 | z.next_in = Z_NULL; 40 | z.avail_in = 0; 41 | if (inflateInit(&z) != Z_OK) { 42 | fprintf(stderr, "inflateInit: %s\n", (z.msg) ? z.msg : "???"); 43 | exit(1); 44 | } 45 | 46 | z.next_out = (Bytef *)outbuf; 47 | z.avail_out = OUTBUFSIZ; 48 | status = Z_OK; 49 | 50 | while (status != Z_STREAM_END) { 51 | if (z.avail_in == 0) { 52 | z.next_in = (Bytef *)inbuf; 53 | z.avail_in = fread(inbuf, 1, INBUFSIZ, fin); 54 | } 55 | status = inflate(&z, Z_NO_FLUSH); 56 | if (status == Z_STREAM_END) break; 57 | if (status != Z_OK) { 58 | fprintf(stderr, "inflate: %s\n", (z.msg) ? z.msg : "???"); 59 | exit(1); 60 | } 61 | if (z.avail_out == 0) { 62 | if (_write_skipping_header(outbuf, 1, OUTBUFSIZ, fout) != OUTBUFSIZ) { 63 | fprintf(stderr, "Write error\n"); 64 | exit(1); 65 | } 66 | z.next_out = (Bytef *)outbuf; 67 | z.avail_out = OUTBUFSIZ; 68 | } 69 | } 70 | 71 | if ((count = OUTBUFSIZ - z.avail_out) != 0) { 72 | if (_write_skipping_header(outbuf, 1, count, fout) != count) { 73 | fprintf(stderr, "Write error\n"); 74 | exit(1); 75 | } 76 | } 77 | 78 | if (inflateEnd(&z) != Z_OK) { 79 | fprintf(stderr, "inflateEnd: %s\n", (z.msg) ? z.msg : "???"); 80 | exit(1); 81 | } 82 | } 83 | 84 | void usage() 85 | { 86 | fprintf(stderr, "Usage:\n"); 87 | fprintf(stderr, " git_cat_file-p blob_file\n"); 88 | } 89 | 90 | int main(int argc, char *argv[]) 91 | { 92 | FILE *fin; 93 | 94 | if (argc == 1) { 95 | usage(); 96 | exit(0); 97 | } 98 | 99 | if ((fin = fopen(argv[1], "r")) == NULL) { 100 | fprintf(stderr, "Can't open %s\n", argv[1]); 101 | exit(1); 102 | } 103 | 104 | _decompress(fin, stdout); 105 | return 0; 106 | } 107 | -------------------------------------------------------------------------------- /zlib_git/t/00_test.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | # 3 | # zlibによる圧縮・展開が可逆的であることを確認するテスト 4 | # 5 | use strict; 6 | use warnings; 7 | use autodie; 8 | use Test::More; 9 | 10 | # プログラム名 11 | our $PROG = 'zlib'; 12 | 13 | # テスト対象テキストファイル 14 | my @files = ('hello', 'bocchan'); 15 | 16 | for my $file (@files) { 17 | my $text_file = $file . '.txt'; 18 | my $compressed_file = $file . '.zlib'; 19 | # ゴミ掃除 20 | unlink $compressed_file if -e $compressed_file; 21 | 22 | # 圧縮 23 | `./$PROG -c $text_file $compressed_file`; 24 | 25 | # 展開して、元のテキストファイルと同一かを確認 26 | is `./$PROG -d $compressed_file /dev/stdout`, `cat $text_file`, 'compare'; 27 | 28 | # ゴミ掃除 29 | unlink $compressed_file if -e $compressed_file; 30 | } 31 | 32 | done_testing; 33 | -------------------------------------------------------------------------------- /zlib_git/txts/bocchan.txt: -------------------------------------------------------------------------------- 1 | 坊っちゃん 2 | 夏目漱石 3 | 4 | 5 |  親譲《おやゆず》りの無鉄砲《むてっぽう》で小供の時から損ばかりしている。小学校に居る時分学校の二階から飛び降りて一週間ほど腰《こし》を抜《ぬ》かした事がある。なぜそんな無闇《むやみ》をしたと聞く人があるかも知れぬ。別段深い理由でもない。新築の二階から首を出していたら、同級生の一人が冗談《じょうだん》に、いくら威張《いば》っても、そこから飛び降りる事は出来まい。弱虫やーい。と囃《はや》したからである。小使《こづかい》に負ぶさって帰って来た時、おやじが大きな眼《め》をして二階ぐらいから飛び降りて腰を抜かす奴《やつ》があるかと云《い》ったから、この次は抜かさずに飛んで見せますと答えた。 6 |  親類のものから西洋製のナイフを貰《もら》って奇麗《きれい》な刃《は》を日に翳《かざ》して、友達《ともだち》に見せていたら、一人が光る事は光るが切れそうもないと云った。切れぬ事があるか、何でも切ってみせると受け合った。そんなら君の指を切ってみろと注文したから、何だ指ぐらいこの通りだと右の手の親指の甲《こう》をはすに切り込《こ》んだ。幸《さいわい》ナイフが小さいのと、親指の骨が堅《かた》かったので、今だに親指は手に付いている。しかし創痕《きずあと》は死ぬまで消えぬ。 7 |  庭を東へ二十歩に行き尽《つく》すと、南上がりにいささかばかりの菜園があって、真中《まんなか》に栗《くり》の木が一本立っている。これは命より大事な栗だ。実の熟する時分は起き抜けに背戸《せど》を出て落ちた奴を拾ってきて、学校で食う。菜園の西側が山城屋《やましろや》という質屋の庭続きで、この質屋に勘太郎《かんたろう》という十三四の倅《せがれ》が居た。勘太郎は無論弱虫である。弱虫の癖《くせ》に四つ目垣を乗りこえて、栗を盗《ぬす》みにくる。ある日の夕方|折戸《おりど》の蔭《かげ》に隠《かく》れて、とうとう勘太郎を捕《つら》まえてやった。その時勘太郎は逃《に》げ路《みち》を失って、一生懸命《いっしょうけんめい》に飛びかかってきた。向《むこ》うは二つばかり年上である。弱虫だが力は強い。鉢《はち》の開いた頭を、こっちの胸へ宛《あ》ててぐいぐい押《お》した拍子《ひょうし》に、勘太郎の頭がすべって、おれの袷《あわせ》の袖《そで》の中にはいった。邪魔《じゃま》になって手が使えぬから、無暗に手を振《ふ》ったら、袖の中にある勘太郎の頭が、右左へぐらぐら靡《なび》いた。しまいに苦しがって袖の中から、おれの二の腕《うで》へ食い付いた。痛かったから勘太郎を垣根へ押しつけておいて、足搦《あしがら》をかけて向うへ倒《たお》してやった。山城屋の地面は菜園より六尺がた低い。勘太郎は四つ目垣を半分|崩《くず》して、自分の領分へ真逆様《まっさかさま》に落ちて、ぐうと云った。勘太郎が落ちるときに、おれの袷の片袖がもげて、急に手が自由になった。その晩母が山城屋に詫《わ》びに行ったついでに袷の片袖も取り返して来た。 8 |  この外いたずらは大分やった。大工の兼公《かねこう》と肴屋《さかなや》の角《かく》をつれて、茂作《もさく》の人参畠《にんじんばたけ》をあらした事がある。人参の芽が出揃《でそろ》わぬ処《ところ》へ藁《わら》が一面に敷《し》いてあったから、その上で三人が半日|相撲《すもう》をとりつづけに取ったら、人参がみんな踏《ふ》みつぶされてしまった。古川《ふるかわ》の持っている田圃《たんぼ》の井戸《いど》を埋《う》めて尻《しり》を持ち込まれた事もある。太い孟宗《もうそう》の節を抜いて、深く埋めた中から水が湧《わ》き出て、そこいらの稲《いね》にみずがかかる仕掛《しかけ》であった。その時分はどんな仕掛か知らぬから、石や棒《ぼう》ちぎれをぎゅうぎゅう井戸の中へ挿《さ》し込んで、水が出なくなったのを見届けて、うちへ帰って飯を食っていたら、古川が真赤《まっか》になって怒鳴《どな》り込んで来た。たしか罰金《ばっきん》を出して済んだようである。 9 |  おやじはちっともおれを可愛《かわい》がってくれなかった。母は兄ばかり贔屓《ひいき》にしていた。この兄はやに色が白くって、芝居《しばい》の真似《まね》をして女形《おんながた》になるのが好きだった。おれを見る度にこいつはどうせ碌《ろく》なものにはならないと、おやじが云った。乱暴で乱暴で行く先が案じられると母が云った。なるほど碌なものにはならない。ご覧の通りの始末である。行く先が案じられたのも無理はない。ただ懲役《ちょうえき》に行かないで生きているばかりである。 10 |  母が病気で死ぬ二三日《にさんち》前台所で宙返りをしてへっついの角で肋骨《あばらぼね》を撲《う》って大いに痛かった。母が大層|怒《おこ》って、お前のようなものの顔は見たくないと云うから、親類へ泊《とま》りに行っていた。するととうとう死んだと云う報知《しらせ》が来た。そう早く死ぬとは思わなかった。そんな大病なら、もう少し大人《おとな》しくすればよかったと思って帰って来た。そうしたら例の兄がおれを親不孝だ、おれのために、おっかさんが早く死んだんだと云った。口惜《くや》しかったから、兄の横っ面を張って大変|叱《しか》られた。 11 |  母が死んでからは、おやじと兄と三人で暮《くら》していた。おやじは何にもせぬ男で、人の顔さえ見れば貴様は駄目《だめ》だ駄目だと口癖のように云っていた。何が駄目なんだか今に分らない。妙《みょう》なおやじがあったもんだ。兄は実業家になるとか云ってしきりに英語を勉強していた。元来女のような性分で、ずるいから、仲がよくなかった。十日に一遍《いっぺん》ぐらいの割で喧嘩《けんか》をしていた。ある時|将棋《しょうぎ》をさしたら卑怯《ひきょう》な待駒《まちごま》をして、人が困ると嬉《うれ》しそうに冷やかした。あんまり腹が立ったから、手に在った飛車を眉間《みけん》へ擲《たた》きつけてやった。眉間が割れて少々血が出た。兄がおやじに言付《いつ》けた。おやじがおれを勘当《かんどう》すると言い出した。 12 |  その時はもう仕方がないと観念して先方の云う通り勘当されるつもりでいたら、十年来召し使っている清《きよ》という下女が、泣きながらおやじに詫《あや》まって、ようやくおやじの怒《いか》りが解けた。それにもかかわらずあまりおやじを怖《こわ》いとは思わなかった。かえってこの清と云う下女に気の毒であった。この下女はもと由緒《ゆいしょ》のあるものだったそうだが、瓦解《がかい》のときに零落《れいらく》して、つい奉公《ほうこう》までするようになったのだと聞いている。だから婆《ばあ》さんである。この婆さんがどういう因縁《いんえん》か、おれを非常に可愛がってくれた。不思議なものである。母も死ぬ三日前に愛想《あいそ》をつかした——おやじも年中持て余している——町内では乱暴者の悪太郎と爪弾《つまはじ》きをする——このおれを無暗に珍重《ちんちょう》してくれた。おれは到底《とうてい》人に好かれる性《たち》でないとあきらめていたから、他人から木の端《はし》のように取り扱《あつか》われるのは何とも思わない、かえってこの清のようにちやほやしてくれるのを不審《ふしん》に考えた。清は時々台所で人の居ない時に「あなたは真《ま》っ直《すぐ》でよいご気性だ」と賞《ほ》める事が時々あった。しかしおれには清の云う意味が分からなかった。好《い》い気性なら清以外のものも、もう少し善くしてくれるだろうと思った。清がこんな事を云う度におれはお世辞は嫌《きら》いだと答えるのが常であった。すると婆さんはそれだから好いご気性ですと云っては、嬉しそうにおれの顔を眺《なが》めている。自分の力でおれを製造して誇《ほこ》ってるように見える。少々気味がわるかった。 13 |  母が死んでから清はいよいよおれを可愛がった。時々は小供心になぜあんなに可愛がるのかと不審に思った。つまらない、廃《よ》せばいいのにと思った。気の毒だと思った。それでも清は可愛がる。折々は自分の小遣《こづか》いで金鍔《きんつば》や紅梅焼《こうばいやき》を買ってくれる。寒い夜などはひそかに蕎麦粉《そばこ》を仕入れておいて、いつの間にか寝《ね》ている枕元《まくらもと》へ蕎麦湯を持って来てくれる。時には鍋焼饂飩《なべやきうどん》さえ買ってくれた。ただ食い物ばかりではない。靴足袋《くつたび》ももらった。鉛筆《えんぴつ》も貰った、帳面も貰った。これはずっと後の事であるが金を三円ばかり貸してくれた事さえある。何も貸せと云った訳ではない。向うで部屋へ持って来てお小遣いがなくてお困りでしょう、お使いなさいと云ってくれたんだ。おれは無論入らないと云ったが、是非使えと云うから、借りておいた。実は大変嬉しかった。その三円を蝦蟇口《がまぐち》へ入れて、懐《ふところ》へ入れたなり便所へ行ったら、すぽりと後架《こうか》の中へ落《おと》してしまった。仕方がないから、のそのそ出てきて実はこれこれだと清に話したところが、清は早速竹の棒を捜《さが》して来て、取って上げますと云った。しばらくすると井戸端《いどばた》でざあざあ音がするから、出てみたら竹の先へ蝦蟇口の紐《ひも》を引き懸《か》けたのを水で洗っていた。それから口をあけて壱円札《いちえんさつ》を改めたら茶色になって模様が消えかかっていた。清は火鉢で乾《かわ》かして、これでいいでしょうと出した。ちょっとかいでみて臭《くさ》いやと云ったら、それじゃお出しなさい、取り換《か》えて来て上げますからと、どこでどう胡魔化《ごまか》したか札の代りに銀貨を三円持って来た。この三円は何に使ったか忘れてしまった。今に返すよと云ったぎり、返さない。今となっては十倍にして返してやりたくても返せない。 14 |  清が物をくれる時には必ずおやじも兄も居ない時に限る。おれは何が嫌いだと云って人に隠れて自分だけ得をするほど嫌いな事はない。兄とは無論仲がよくないけれども、兄に隠して清から菓子《かし》や色鉛筆を貰いたくはない。なぜ、おれ一人にくれて、兄さんには遣《や》らないのかと清に聞く事がある。すると清は澄《すま》したものでお兄様《あにいさま》はお父様《とうさま》が買ってお上げなさるから構いませんと云う。これは不公平である。おやじは頑固《がんこ》だけれども、そんな依怙贔負《えこひいき》はせぬ男だ。しかし清の眼から見るとそう見えるのだろう。全く愛に溺《おぼ》れていたに違《ちが》いない。元は身分のあるものでも教育のない婆さんだから仕方がない。単にこればかりではない。贔負目は恐ろしいものだ。清はおれをもって将来立身出世して立派なものになると思い込んでいた。その癖勉強をする兄は色ばかり白くって、とても役には立たないと一人できめてしまった。こんな婆さんに逢《あ》っては叶《かな》わない。自分の好きなものは必ずえらい人物になって、嫌いなひとはきっと落ち振れるものと信じている。おれはその時から別段何になると云う了見《りょうけん》もなかった。しかし清がなるなると云うものだから、やっぱり何かに成れるんだろうと思っていた。今から考えると馬鹿馬鹿《ばかばか》しい。ある時などは清にどんなものになるだろうと聞いてみた事がある。ところが清にも別段の考えもなかったようだ。ただ手車《てぐるま》へ乗って、立派な玄関《げんかん》のある家をこしらえるに相違《そうい》ないと云った。 15 |  それから清はおれがうちでも持って独立したら、一所《いっしょ》になる気でいた。どうか置いて下さいと何遍も繰《く》り返して頼んだ。おれも何だかうちが持てるような気がして、うん置いてやると返事だけはしておいた。ところがこの女はなかなか想像の強い女で、あなたはどこがお好き、麹町《こうじまち》ですか麻布《あざぶ》ですか、お庭へぶらんこをおこしらえ遊ばせ、西洋間は一つでたくさんですなどと勝手な計画を独りで並《なら》べていた。その時は家なんか欲しくも何ともなかった。西洋館も日本建《にほんだて》も全く不用であったから、そんなものは欲しくないと、いつでも清に答えた。すると、あなたは欲がすくなくって、心が奇麗だと云ってまた賞めた。清は何と云っても賞めてくれる。 16 |  母が死んでから五六年の間はこの状態で暮していた。おやじには叱られる。兄とは喧嘩をする。清には菓子を貰う、時々賞められる。別に望みもない。これでたくさんだと思っていた。ほかの小供も一概《いちがい》にこんなものだろうと思っていた。ただ清が何かにつけて、あなたはお可哀想《かわいそう》だ、不仕合《ふしあわせ》だと無暗に云うものだから、それじゃ可哀想で不仕合せなんだろうと思った。その外に苦になる事は少しもなかった。ただおやじが小遣いをくれないには閉口した。 17 |  母が死んでから六年目の正月におやじも卒中で亡くなった。その年の四月におれはある私立の中学校を卒業する。六月に兄は商業学校を卒業した。兄は何とか会社の九州の支店に口があって行《ゆ》かなければならん。おれは東京でまだ学問をしなければならない。兄は家を売って財産を片付けて任地へ出立《しゅったつ》すると云い出した。おれはどうでもするがよかろうと返事をした。どうせ兄の厄介《やっかい》になる気はない。世話をしてくれるにしたところで、喧嘩をするから、向うでも何とか云い出すに極《きま》っている。なまじい保護を受ければこそ、こんな兄に頭を下げなければならない。牛乳配達をしても食ってられると覚悟《かくご》をした。兄はそれから道具屋を呼んで来て、先祖代々の瓦落多《がらくた》を二束三文《にそくさんもん》に売った。家屋敷《いえやしき》はある人の周旋《しゅうせん》である金満家に譲った。この方は大分金になったようだが、詳《くわ》しい事は一向知らぬ。おれは一ヶ月以前から、しばらく前途の方向のつくまで神田の小川町《おがわまち》へ下宿していた。清は十何年居たうちが人手に渡《わた》るのを大いに残念がったが、自分のものでないから、仕様がなかった。あなたがもう少し年をとっていらっしゃれば、ここがご相続が出来ますものをとしきりに口説いていた。もう少し年をとって相続が出来るものなら、今でも相続が出来るはずだ。婆さんは何《なんに》も知らないから年さえ取れば兄の家がもらえると信じている。 18 |  兄とおれはかように分れたが、困ったのは清の行く先である。兄は無論連れて行ける身分でなし、清も兄の尻にくっ付いて九州|下《くんだ》りまで出掛ける気は毛頭なし、と云ってこの時のおれは四畳半《よじょうはん》の安下宿に籠《こも》って、それすらもいざとなれば直ちに引き払《はら》わねばならぬ始末だ。どうする事も出来ん。清に聞いてみた。どこかへ奉公でもする気かねと云ったらあなたがおうちを持って、奥《おく》さまをお貰いになるまでは、仕方がないから、甥《おい》の厄介になりましょうとようやく決心した返事をした。この甥は裁判所の書記でまず今日には差支《さしつか》えなく暮していたから、今までも清に来るなら来いと二三度勧めたのだが、清はたとい下女奉公はしても年来住み馴《な》れた家《うち》の方がいいと云って応じなかった。しかし今の場合知らぬ屋敷へ奉公易《ほうこうが》えをして入らぬ気兼《きがね》を仕直すより、甥の厄介になる方がましだと思ったのだろう。それにしても早くうちを持ての、妻《さい》を貰えの、来て世話をするのと云う。親身《しんみ》の甥よりも他人のおれの方が好きなのだろう。 19 |  九州へ立つ二日前兄が下宿へ来て金を六百円出してこれを資本にして商買《しょうばい》をするなり、学資にして勉強をするなり、どうでも随意《ずいい》に使うがいい、その代りあとは構わないと云った。兄にしては感心なやり方だ、何の六百円ぐらい貰わんでも困りはせんと思ったが、例に似ぬ淡泊《たんばく》な処置が気に入ったから、礼を云って貰っておいた。兄はそれから五十円出してこれをついでに清に渡してくれと云ったから、異議なく引き受けた。二日立って新橋の停車場《ていしゃば》で分れたぎり兄にはその後一遍も逢わない。 20 |  おれは六百円の使用法について寝ながら考えた。商買をしたって面倒《めんど》くさくって旨《うま》く出来るものじゃなし、ことに六百円の金で商買らしい商買がやれる訳でもなかろう。よしやれるとしても、今のようじゃ人の前へ出て教育を受けたと威張れないからつまり損になるばかりだ。資本などはどうでもいいから、これを学資にして勉強してやろう。六百円を三に割って一年に二百円ずつ使えば三年間は勉強が出来る。三年間一生懸命にやれば何か出来る。それからどこの学校へはいろうと考えたが、学問は生来《しょうらい》どれもこれも好きでない。ことに語学とか文学とか云うものは真平《まっぴら》ご免《めん》だ。新体詩などと来ては二十行あるうちで一行も分らない。どうせ嫌いなものなら何をやっても同じ事だと思ったが、幸い物理学校の前を通り掛《かか》ったら生徒募集の広告が出ていたから、何も縁だと思って規則書をもらってすぐ入学の手続きをしてしまった。今考えるとこれも親譲りの無鉄砲から起《おこ》った失策だ。 21 |  三年間まあ人並《ひとなみ》に勉強はしたが別段たちのいい方でもないから、席順はいつでも下から勘定《かんじょう》する方が便利であった。しかし不思議なもので、三年立ったらとうとう卒業してしまった。自分でも可笑《おか》しいと思ったが苦情を云う訳もないから大人しく卒業しておいた。 22 |  卒業してから八日目に校長が呼びに来たから、何か用だろうと思って、出掛けて行ったら、四国辺のある中学校で数学の教師が入る。月給は四十円だが、行ってはどうだという相談である。おれは三年間学問はしたが実を云うと教師になる気も、田舎《いなか》へ行く考えも何もなかった。もっとも教師以外に何をしようと云うあてもなかったから、この相談を受けた時、行きましょうと即席《そくせき》に返事をした。これも親譲りの無鉄砲が祟《たた》ったのである。 23 |  引き受けた以上は赴任《ふにん》せねばならぬ。この三年間は四畳半に蟄居《ちっきょ》して小言はただの一度も聞いた事がない。喧嘩もせずに済んだ。おれの生涯のうちでは比較的《ひかくてき》呑気《のんき》な時節であった。しかしこうなると四畳半も引き払わなければならん。生れてから東京以外に踏み出したのは、同級生と一所に鎌倉《かまくら》へ遠足した時ばかりである。今度は鎌倉どころではない。大変な遠くへ行かねばならぬ。地図で見ると海浜で針の先ほど小さく見える。どうせ碌な所ではあるまい。どんな町で、どんな人が住んでるか分らん。分らんでも困らない。心配にはならぬ。ただ行くばかりである。もっとも少々面倒臭い。 24 |  家を畳《たた》んでからも清の所へは折々行った。清の甥というのは存外結構な人である。おれが行《ゆ》くたびに、居《お》りさえすれば、何くれと款待《もて》なしてくれた。清はおれを前へ置いて、いろいろおれの自慢《じまん》を甥に聞かせた。今に学校を卒業すると麹町辺へ屋敷を買って役所へ通うのだなどと吹聴《ふいちょう》した事もある。独りで極《き》めて一人《ひとり》で喋舌《しゃべ》るから、こっちは困《こ》まって顔を赤くした。それも一度や二度ではない。折々おれが小さい時寝小便をした事まで持ち出すには閉口した。甥は何と思って清の自慢を聞いていたか分らぬ。ただ清は昔風《むかしふう》の女だから、自分とおれの関係を封建《ほうけん》時代の主従《しゅじゅう》のように考えていた。自分の主人なら甥のためにも主人に相違ないと合点《がてん》したものらしい。甥こそいい面《つら》の皮だ。 25 |  いよいよ約束が極まって、もう立つと云う三日前に清を尋《たず》ねたら、北向きの三畳に風邪《かぜ》を引いて寝ていた。おれの来たのを見て起き直るが早いか、坊《ぼ》っちゃんいつ家《うち》をお持ちなさいますと聞いた。卒業さえすれば金が自然とポッケットの中に湧いて来ると思っている。そんなにえらい人をつらまえて、まだ坊っちゃんと呼ぶのはいよいよ馬鹿気ている。おれは単簡に当分うちは持たない。田舎へ行くんだと云ったら、非常に失望した容子《ようす》で、胡麻塩《ごましお》の鬢《びん》の乱れをしきりに撫《な》でた。あまり気の毒だから「行《ゆ》く事は行くがじき帰る。来年の夏休みにはきっと帰る」と慰《なぐさ》めてやった。それでも妙な顔をしているから「何を見やげに買って来てやろう、何が欲しい」と聞いてみたら「越後《えちご》の笹飴《ささあめ》が食べたい」と云った。越後の笹飴なんて聞いた事もない。第一方角が違う。「おれの行く田舎には笹飴はなさそうだ」と云って聞かしたら「そんなら、どっちの見当です」と聞き返した。「西の方だよ」と云うと「箱根《はこね》のさきですか手前ですか」と問う。随分持てあました。 26 |  出立の日には朝から来て、いろいろ世話をやいた。来る途中《とちゅう》小間物屋で買って来た歯磨《はみがき》と楊子《ようじ》と手拭《てぬぐい》をズックの革鞄《かばん》に入れてくれた。そんな物は入らないと云ってもなかなか承知しない。車を並べて停車場へ着いて、プラットフォームの上へ出た時、車へ乗り込んだおれの顔をじっと見て「もうお別れになるかも知れません。随分ご機嫌《きげん》よう」と小さな声で云った。目に涙《なみだ》が一杯《いっぱい》たまっている。おれは泣かなかった。しかしもう少しで泣くところであった。汽車がよっぽど動き出してから、もう大丈夫《だいしょうぶ》だろうと思って、窓から首を出して、振り向いたら、やっぱり立っていた。何だか大変小さく見えた。 27 | 28 | [#5字下げ]二[#「二」は中見出し] 29 | 30 |  ぶうと云《い》って汽船がとまると、艀《はしけ》が岸を離《はな》れて、漕《こ》ぎ寄せて来た。船頭は真《ま》っ裸《ぱだか》に赤ふんどしをしめている。野蛮《やばん》な所だ。もっともこの熱さでは着物はきられまい。日が強いので水がやに光る。見つめていても眼《め》がくらむ。事務員に聞いてみるとおれはここへ降りるのだそうだ。見るところでは大森《おおもり》ぐらいな漁村だ。人を馬鹿《ばか》にしていらあ、こんな所に我慢《がまん》が出来るものかと思ったが仕方がない。威勢《いせい》よく一番に飛び込んだ。続《つ》づいて五六人は乗ったろう。外に大きな箱《はこ》を四つばかり積み込んで赤ふんは岸へ漕ぎ戻《もど》して来た。陸《おか》へ着いた時も、いの一番に飛び上がって、いきなり、磯《いそ》に立っていた鼻たれ小僧《こぞう》をつらまえて中学校はどこだと聞いた。小僧はぼんやりして、知らんがの、と云った。気の利かぬ田舎《いなか》ものだ。猫《ねこ》の額ほどな町内の癖《くせ》に、中学校のありかも知らぬ奴《やつ》があるものか。ところへ妙《みょう》な筒《つつ》っぽうを着た男がきて、こっちへ来いと云うから、尾《つ》いて行ったら、港屋とか云う宿屋へ連れて来た。やな女が声を揃《そろ》えてお上がりなさいと云うので、上がるのがいやになった。門口へ立ったなり中学校を教えろと云ったら、中学校はこれから汽車で二里ばかり行かなくっちゃいけないと聞いて、なお上がるのがいやになった。おれは、筒っぽうを着た男から、おれの革鞄《かばん》を二つ引きたくって、のそのそあるき出した。宿屋のものは変な顔をしていた。 31 |  停車場はすぐ知れた。切符《きっぷ》も訳なく買った。乗り込んでみるとマッチ箱のような汽車だ。ごろごろと五分ばかり動いたと思ったら、もう降りなければならない。道理で切符が安いと思った。たった三銭である。それから車を傭《やと》って、中学校へ来たら、もう放課後で誰《だれ》も居ない。宿直はちょっと用達《ようたし》に出たと小使《こづかい》が教えた。随分《ずいぶん》気楽な宿直がいるものだ。校長でも尋《たず》ねようかと思ったが、草臥《くたび》れたから、車に乗って宿屋へ連れて行けと車夫に云い付けた。車夫は威勢よく山城屋《やましろや》と云ううちへ横付けにした。山城屋とは質屋の勘太郎《かんたろう》の屋号と同じだからちょっと面白く思った。 32 |  何だか二階の楷子段《はしごだん》の下の暗い部屋へ案内した。熱くって居られやしない。こんな部屋はいやだと云ったらあいにくみんな塞《ふさ》がっておりますからと云いながら革鞄を抛《ほう》り出したまま出て行った。仕方がないから部屋の中へはいって汗《あせ》をかいて我慢《がまん》していた。やがて湯に入れと云うから、ざぶりと飛び込んで、すぐ上がった。帰りがけに覗《のぞ》いてみると涼《すず》しそうな部屋がたくさん空いている。失敬な奴だ。嘘《うそ》をつきゃあがった。それから下女が膳《ぜん》を持って来た。部屋は熱《あ》つかったが、飯は下宿のよりも大分|旨《うま》かった。給仕をしながら下女がどちらからおいでになりましたと聞くから、東京から来たと答えた。すると東京はよい所でございましょうと云ったから当《あた》り前だと答えてやった。膳を下げた下女が台所へいった時分、大きな笑い声が聞《きこ》えた。くだらないから、すぐ寝《ね》たが、なかなか寝られない。熱いばかりではない。騒々《そうぞう》しい。下宿の五倍ぐらいやかましい。うとうとしたら清《きよ》の夢《ゆめ》を見た。清が越後《えちご》の笹飴《ささあめ》を笹ぐるみ、むしゃむしゃ食っている。笹は毒だからよしたらよかろうと云うと、いえこの笹がお薬でございますと云《い》って旨そうに食っている。おれがあきれ返って大きな口を開いてハハハハと笑ったら眼が覚めた。下女が雨戸を明けている。相変らず空の底が突《つ》き抜《ぬ》けたような天気だ。 33 |  道中《どうちゅう》をしたら茶代をやるものだと聞いていた。茶代をやらないと粗末《そまつ》に取り扱われると聞いていた。こんな、狭《せま》くて暗い部屋へ押《お》し込めるのも茶代をやらないせいだろう。見すぼらしい服装《なり》をして、ズックの革鞄と毛繻子《けじゅす》の蝙蝠傘《こうもり》を提げてるからだろう。田舎者の癖に人を見括《みくび》ったな。一番茶代をやって驚《おどろ》かしてやろう。おれはこれでも学資のあまりを三十円ほど懐《ふところ》に入れて東京を出て来たのだ。汽車と汽船の切符代と雑費を差し引いて、まだ十四円ほどある。みんなやったってこれからは月給を貰《もら》うんだから構わない。田舎者はしみったれだから五円もやれば驚《おど》ろいて眼を廻《まわ》すに極《きま》っている。どうするか見ろと済《すま》して顔を洗って、部屋へ帰って待ってると、夕べの下女が膳を持って来た。盆《ぼん》を持って給仕をしながら、やににやにや笑ってる。失敬な奴だ。顔のなかをお祭りでも通りゃしまいし。これでもこの下女の面《つら》よりよっぽど上等だ。飯を済ましてからにしようと思っていたが、癪《しゃく》に障《さわ》ったから、中途《ちゅうと》で五円|札《さつ》を一|枚《まい》出して、あとでこれを帳場へ持って行けと云ったら、下女は変な顔をしていた。それから飯を済ましてすぐ学校へ出懸《でか》けた。靴《くつ》は磨《みが》いてなかった。 34 |  学校は昨日《きのう》車で乗りつけたから、大概《たいがい》の見当は分っている。四つ角を二三度曲がったらすぐ門の前へ出た。門から玄関《げんかん》までは御影石《みかげいし》で敷《し》きつめてある。きのうこの敷石の上を車でがらがらと通った時は、無暗《むやみ》に仰山《ぎょうさん》な音がするので少し弱った。途中から小倉《こくら》の制服を着た生徒にたくさん逢《あ》ったが、みんなこの門をはいって行く。中にはおれより背が高くって強そうなのが居る。あんな奴を教えるのかと思ったら何だか気味が悪《わ》るくなった。名刺《めいし》を出したら校長室へ通した。校長は薄髯《うすひげ》のある、色の黒い、目の大きな狸《たぬき》のような男である。やにもったいぶっていた。まあ精出して勉強してくれと云って、恭《うやうや》しく大きな印の捺《おさ》った、辞令を渡《わた》した。この辞令は東京へ帰るとき丸めて海の中へ抛り込《こ》んでしまった。校長は今に職員に紹介《しょうかい》してやるから、一々その人にこの辞令を見せるんだと云って聞かした。余計な手数だ。そんな面倒《めんどう》な事をするよりこの辞令を三日間職員室へ張り付ける方がましだ。 35 |  教員が控所《ひかえじょ》へ揃《そろ》うには一時間目の喇叭《らっぱ》が鳴らなくてはならぬ。大分時間がある。校長は時計を出して見て、追々《おいおい》ゆるりと話すつもりだが、まず大体の事を呑《の》み込んでおいてもらおうと云って、それから教育の精神について長いお談義を聞かした。おれは無論いい加減に聞いていたが、途中からこれは飛んだ所へ来たと思った。校長の云うようにはとても出来ない。おれみたような無鉄砲《むてっぽう》なものをつらまえて、生徒の模範《もはん》になれの、一校の師表《しひょう》と仰《あお》がれなくてはいかんの、学問以外に個人の徳化を及《およ》ぼさなくては教育者になれないの、と無暗に法外な注文をする。そんなえらい人が月給四十円で遥々《はるばる》こんな田舎へくるもんか。人間は大概似たもんだ。腹が立てば喧嘩《けんか》の一つぐらいは誰でもするだろうと思ってたが、この様子じゃめったに口も聞けない、散歩も出来ない。そんなむずかしい役なら雇《やと》う前にこれこれだと話すがいい。おれは嘘《うそ》をつくのが嫌《きら》いだから、仕方がない、だまされて来たのだとあきらめて、思い切りよく、ここで断《こと》わって帰っちまおうと思った。宿屋へ五円やったから財布《さいふ》の中には九円なにがししかない。九円じゃ東京までは帰れない。茶代なんかやらなければよかった。惜《お》しい事をした。しかし九円だって、どうかならない事はない。旅費は足りなくっても嘘をつくよりましだと思って、到底《とうてい》あなたのおっしゃる通りにゃ、出来ません、この辞令は返しますと云ったら、校長は狸のような眼をぱちつかせておれの顔を見ていた。やがて、今のはただ希望である、あなたが希望通り出来ないのはよく知っているから心配しなくってもいいと云いながら笑った。そのくらいよく知ってるなら、始めから威嚇《おどさ》さなければいいのに。 36 |  そう、こうする内に喇叭が鳴った。教場の方が急にがやがやする。もう教員も控所へ揃いましたろうと云うから、校長に尾いて教員控所へはいった。広い細長い部屋の周囲に机を並《なら》べてみんな腰《こし》をかけている。おれがはいったのを見て、みんな申し合せたようにおれの顔を見た。見世物じゃあるまいし。それから申し付けられた通り一人一人《ひとりびとり》の前へ行って辞令を出して挨拶《あいさつ》をした。大概《たいがい》は椅子《いす》を離れて腰をかがめるばかりであったが、念の入ったのは差し出した辞令を受け取って一応拝見をしてそれを恭《うやうや》しく返却《へんきゃく》した。まるで宮芝居の真似《まね》だ。十五人目に体操《たいそう》の教師へと廻って来た時には、同じ事を何返もやるので少々じれったくなった。向《むこ》うは一度で済む。こっちは同じ所作《しょさ》を十五返繰り返している。少しはひとの了見《りょうけん》も察してみるがいい。 37 |  挨拶をしたうちに教頭のなにがしと云うのが居た。これは文学士だそうだ。文学士と云えば大学の卒業生だからえらい人なんだろう。妙《みょう》に女のような優しい声を出す人だった。もっとも驚いたのはこの暑いのにフランネルの襯衣《しゃつ》を着ている。いくらか薄《うす》い地には相違《そうい》なくっても暑いには極ってる。文学士だけにご苦労千万な服装《なり》をしたもんだ。しかもそれが赤シャツだから人を馬鹿《ばか》にしている。あとから聞いたらこの男は年が年中赤シャツを着るんだそうだ。妙な病気があった者だ。当人の説明では赤は身体《からだ》に薬になるから、衛生のためにわざわざ誂《あつ》らえるんだそうだが、入らざる心配だ。そんならついでに着物も袴《はかま》も赤にすればいい。それから英語の教師に古賀《こが》とか云う大変顔色の悪《わ》るい男が居た。大概顔の蒼《あお》い人は瘠《や》せてるもんだがこの男は蒼くふくれている。昔《むかし》小学校へ行く時分、浅井《あさい》の民《たみ》さんと云う子が同級生にあったが、この浅井のおやじがやはり、こんな色つやだった。浅井は百姓《ひゃくしょう》だから、百姓になるとあんな顔になるかと清に聞いてみたら、そうじゃありません、あの人はうらなりの唐茄子《とうなす》ばかり食べるから、蒼くふくれるんですと教えてくれた。それ以来蒼くふくれた人を見れば必ずうらなりの唐茄子を食った酬《むく》いだと思う。この英語の教師もうらなりばかり食ってるに違《ちが》いない。もっともうらなりとは何の事か今もって知らない。清に聞いてみた事はあるが、清は笑って答えなかった。大方清も知らないんだろう。それからおれと同じ数学の教師に堀田《ほった》というのが居た。これは逞《たくま》しい毬栗坊主《いがぐりぼうず》で、叡山《えいざん》の悪僧《あくそう》と云うべき面構《つらがまえ》である。人が叮寧《ていねい》に辞令を見せたら見向きもせず、やあ君が新任の人か、ちと遊びに来給《きたま》えアハハハと云った。何がアハハハだ。そんな礼儀《れいぎ》を心得ぬ奴の所へ誰が遊びに行くものか。おれはこの時からこの坊主に山嵐《やまあらし》という渾名《あだな》をつけてやった。漢学の先生はさすがに堅《かた》いものだ。昨日お着きで、さぞお疲れで、それでもう授業をお始めで、大分ご励精《れいせい》で、——とのべつに弁じたのは愛嬌《あいきょう》のあるお爺《じい》さんだ。画学の教師は全く芸人風だ。べらべらした透綾《すきや》の羽織を着て、扇子《せんす》をぱちつかせて、お国はどちらでげす、え? 東京? そりゃ嬉《うれ》しい、お仲間が出来て……私《わたし》もこれで江戸《えど》っ子ですと云った。こんなのが江戸っ子なら江戸には生れたくないもんだと心中に考えた。そのほか一人一人についてこんな事を書けばいくらでもある。しかし際限がないからやめる。 38 |  挨拶が一通り済んだら、校長が今日はもう引き取ってもいい、もっとも授業上の事は数学の主任と打ち合せをしておいて、明後日《あさって》から課業を始めてくれと云った。数学の主任は誰かと聞いてみたら例の山嵐であった。忌々《いまいま》しい、こいつの下に働くのかおやおやと失望した。山嵐は「おい君どこに宿《とま》ってるか、山城屋か、うん、今に行って相談する」と云い残して白墨《はくぼく》を持って教場へ出て行った。主任の癖に向うから来て相談するなんて不見識な男だ。しかし呼び付けるよりは感心だ。 39 |  それから学校の門を出て、すぐ宿へ帰ろうと思ったが、帰ったって仕方がないから、少し町を散歩してやろうと思って、無暗に足の向く方をあるき散らした。県庁も見た。古い前世紀の建築である。兵営も見た。麻布《あざぶ》の聯隊《れんたい》より立派でない。大通りも見た。神楽坂《かぐらざか》を半分に狭くしたぐらいな道幅《みちはば》で町並《まちなみ》はあれより落ちる。二十五万石の城下だって高の知れたものだ。こんな所に住んでご城下だなどと威張《いば》ってる人間は可哀想《かわいそう》なものだと考えながらくると、いつしか山城屋の前に出た。広いようでも狭いものだ。これで大抵《たいてい》は見尽《みつく》したのだろう。帰って飯でも食おうと門口をはいった。帳場に坐《すわ》っていたかみさんが、おれの顔を見ると急に飛び出してきてお帰り……と板の間へ頭をつけた。靴《くつ》を脱《ぬ》いで上がると、お座敷《ざしき》があきましたからと下女が二階へ案内をした。十五|畳《じょう》の表二階で大きな床《とこ》の間《ま》がついている。おれは生れてからまだこんな立派な座敷へはいった事はない。この後いつはいれるか分らないから、洋服を脱いで浴衣《ゆかた》一枚になって座敷の真中《まんなか》へ大の字に寝てみた。いい心持ちである。 40 |  昼飯を食ってから早速清へ手紙をかいてやった。おれは文章がまずい上に字を知らないから手紙を書くのが大嫌《だいきら》いだ。またやる所もない。しかし清は心配しているだろう。難船して死にやしないかなどと思っちゃ困るから、奮発《ふんぱつ》して長いのを書いてやった。その文句はこうである。 41 | 「きのう着いた。つまらん所だ。十五畳の座敷に寝ている。宿屋へ茶代を五円やった。かみさんが頭を板の間へすりつけた。夕べは寝られなかった。清が笹飴を笹ごと食う夢を見た。来年の夏は帰る。今日学校へ行ってみんなにあだなをつけてやった。校長は狸、教頭は赤シャツ、英語の教師はうらなり、数学は山嵐、画学はのだいこ。今にいろいろな事を書いてやる。さようなら」 42 |  手紙をかいてしまったら、いい心持ちになって眠気《ねむけ》がさしたから、最前のように座敷の真中へのびのびと大の字に寝た。今度は夢も何も見ないでぐっすり寝た。この部屋かいと大きな声がするので目が覚めたら、山嵐がはいって来た。最前は失敬、君の受持ちは……と人が起き上がるや否や談判を開かれたので大いに狼狽《ろうばい》した。受持ちを聞いてみると別段むずかしい事もなさそうだから承知した。このくらいの事なら、明後日は愚《おろか》、明日《あした》から始めろと云ったって驚ろかない。授業上の打ち合せが済んだら、君はいつまでこんな宿屋に居るつもりでもあるまい、僕《ぼく》がいい下宿を周旋《しゅうせん》してやるから移りたまえ。外のものでは承知しないが僕が話せばすぐ出来る。早い方がいいから、今日見て、あす移って、あさってから学校へ行けば極りがいいと一人で呑み込んでいる。なるほど十五畳敷にいつまで居る訳にも行くまい。月給をみんな宿料《しゅくりょう》に払《はら》っても追っつかないかもしれぬ。五円の茶代を奮発《ふんぱつ》してすぐ移るのはちと残念だが、どうせ移る者なら、早く引き越《こ》して落ち付く方が便利だから、そこのところはよろしく山嵐に頼《たの》む事にした。すると山嵐はともかくもいっしょに来てみろと云うから、行った。町はずれの岡の中腹にある家で至極|閑静《かんせい》だ。主人は骨董《こっとう》を売買するいか銀と云う男で、女房《にょうぼう》は亭主《ていしゅ》よりも四つばかり年嵩《としかさ》の女だ。中学校に居た時ウィッチと云う言葉を習った事があるがこの女房はまさにウィッチに似ている。ウィッチだって人の女房だから構わない。とうとう明日から引き移る事にした。帰りに山嵐は通町《とおりちょう》で氷水を一|杯《ぱい》奢《おご》った。学校で逢った時はやに横風《おうふう》な失敬な奴だと思ったが、こんなにいろいろ世話をしてくれるところを見ると、わるい男でもなさそうだ。ただおれと同じようにせっかちで肝癪持《かんしゃくもち》らしい。あとで聞いたらこの男が一番生徒に人望があるのだそうだ。 43 | 44 | [#5字下げ]三[#「三」は中見出し] 45 | 46 |  いよいよ学校へ出た。初めて教場へはいって高い所へ乗った時は、何だか変だった。講釈をしながら、おれでも先生が勤まるのかと思った。生徒はやかましい。時々|図抜《ずぬ》けた大きな声で先生と云《い》う。先生には応《こた》えた。今まで物理学校で毎日先生先生と呼びつけていたが、先生と呼ぶのと、呼ばれるのは雲泥《うんでい》の差だ。何だか足の裏がむずむずする。おれは卑怯《ひきょう》な人間ではない。臆病《おくびょう》な男でもないが、惜《お》しい事に胆力《たんりょく》が欠けている。先生と大きな声をされると、腹の減った時に丸の内で午砲《どん》を聞いたような気がする。最初の一時間は何だかいい加減にやってしまった。しかし別段困った質問も掛《か》けられずに済んだ。控所《ひかえじょ》へ帰って来たら、山嵐がどうだいと聞いた。うんと単簡に返事をしたら山嵐は安心したらしかった。 47 |  二時間目に白墨《はくぼく》を持って控所を出た時には何だか敵地へ乗り込《こ》むような気がした。教場へ出ると今度の組は前より大きな奴《やつ》ばかりである。おれは江戸《えど》っ子で華奢《きゃしゃ》に小作りに出来ているから、どうも高い所へ上がっても押《お》しが利かない。喧嘩《けんか》なら相撲取《すもうとり》とでもやってみせるが、こんな大僧《おおぞう》を四十人も前へ並《なら》べて、ただ一|枚《まい》の舌をたたいて恐縮《きょうしゅく》させる手際はない。しかしこんな田舎者《いなかもの》に弱身を見せると癖《くせ》になると思ったから、なるべく大きな声をして、少々巻き舌で講釈してやった。最初のうちは、生徒も烟《けむ》に捲《ま》かれてぼんやりしていたから、それ見ろとますます得意になって、べらんめい調を用いてたら、一番前の列の真中《まんなか》に居た、一番強そうな奴が、いきなり起立して先生と云う。そら来たと思いながら、何だと聞いたら、「あまり早くて分からんけれ、もちっと、ゆるゆる遣《や》って、おくれんかな、もし」と云った。おくれんかな[#「おくれんかな」に傍点]、もし[#「もし」に傍点]は生温《なまぬ》るい言葉だ。早過ぎるなら、ゆっくり云ってやるが、おれは江戸っ子だから君等《きみら》の言葉は使えない、分《わか》らなければ、分るまで待ってるがいいと答えてやった。この調子で二時間目は思ったより、うまく行った。ただ帰りがけに生徒の一人がちょっとこの問題を解釈をしておくれんかな、もし、と出来そうもない幾何《きか》の問題を持って逼《せま》ったには冷汗《ひやあせ》を流した。仕方がないから何だか分らない、この次教えてやると急いで引き揚《あ》げたら、生徒がわあと囃《はや》した。その中に出来ん出来んと云う声が聞《きこ》える。箆棒《べらぼう》め、先生だって、出来ないのは当り前だ。出来ないのを出来ないと云うのに不思議があるもんか。そんなものが出来るくらいなら四十円でこんな田舎へくるもんかと控所へ帰って来た。今度はどうだとまた山嵐が聞いた。うんと云ったが、うんだけでは気が済まなかったから、この学校の生徒は分らずやだなと云ってやった。山嵐は妙《みょう》な顔をしていた。 48 |  三時間目も、四時間目も昼過ぎの一時間も大同小異であった。最初の日に出た級は、いずれも少々ずつ失敗した。教師ははたで見るほど楽じゃないと思った。授業はひと通り済んだが、まだ帰れない、三時までぽつ然《ねん》として待ってなくてはならん。三時になると、受持級の生徒が自分の教室を掃除《そうじ》して報知《しらせ》にくるから検分をするんだそうだ。それから、出席簿《しゅっせきぼ》を一応調べてようやくお暇《ひま》が出る。いくら月給で買われた身体《からだ》だって、あいた時間まで学校へ縛《しば》りつけて机と睨《にら》めっくらをさせるなんて法があるものか。しかしほかの連中はみんな大人《おとな》しくご規則通りやってるから新参のおればかり、だだを捏《こ》ねるのもよろしくないと思って我慢《がまん》していた。帰りがけに、君何でもかんでも三時|過《すぎ》まで学校にいさせるのは愚《おろか》だぜと山嵐に訴えたら、山嵐はそうさアハハハと笑ったが、あとから真面目《まじめ》になって、君あまり学校の不平を云うと、いかんぜ。云うなら僕《ぼく》だけに話せ、随分《ずいぶん》妙な人も居るからなと忠告がましい事を云った。四つ角で分れたから詳《くわ》しい事は聞くひまがなかった。 49 |  それからうちへ帰ってくると、宿の亭主《ていしゅ》がお茶を入れましょうと云ってやって来る。お茶を入れると云うからご馳走《ちそう》をするのかと思うと、おれの茶を遠慮《えんりょ》なく入れて自分が飲むのだ。この様子では留守中《るすちゅう》も勝手にお茶を入れましょうを一人《ひとり》で履行《りこう》しているかも知れない。亭主が云うには手前は書画骨董《しょがこっとう》がすきで、とうとうこんな商買を内々で始めるようになりました。あなたもお見受け申すところ大分ご風流でいらっしゃるらしい。ちと道楽にお始めなすってはいかがですと、飛んでもない勧誘《かんゆう》をやる。二年前ある人の使《つかい》に帝国《ていこく》ホテルへ行った時は錠前《じょうまえ》直しと間違《まちが》えられた事がある。ケットを被《かぶ》って、鎌倉《かまくら》の大仏を見物した時は車屋から親方と云われた。その外|今日《こんにち》まで見損《みそくな》われた事は随分あるが、まだおれをつらまえて大分ご風流でいらっしゃると云ったものはない。大抵《たいてい》はなりや様子でも分る。風流人なんていうものは、画《え》を見ても、頭巾《ずきん》を被《かぶ》るか短冊《たんざく》を持ってるものだ。このおれを風流人だなどと真面目に云うのはただの曲者《くせもの》じゃない。おれはそんな呑気《のんき》な隠居《いんきょ》のやるような事は嫌《きら》いだと云ったら、亭主はへへへへと笑いながら、いえ始めから好きなものは、どなたもございませんが、いったんこの道にはいるとなかなか出られませんと一人で茶を注いで妙な手付《てつき》をして飲んでいる。実はゆうべ茶を買ってくれと頼《たの》んでおいたのだが、こんな苦い濃《こ》い茶はいやだ。一|杯《ぱい》飲むと胃に答えるような気がする。今度からもっと苦くないのを買ってくれと云ったら、かしこまりましたとまた一杯しぼって飲んだ。人の茶だと思って無暗《むやみ》に飲む奴《やつ》だ。主人が引き下がってから、明日の下読《したよみ》をしてすぐ寝《ね》てしまった。 50 |  それから毎日毎日学校へ出ては規則通り働く、毎日毎日帰って来ると主人がお茶を入れましょうと出てくる。一週間ばかりしたら学校の様子もひと通りは飲み込めたし、宿の夫婦の人物も大概《たいがい》は分った。ほかの教師に聞いてみると辞令を受けて一週間から一ヶ月ぐらいの間は自分の評判がいいだろうか、悪《わ》るいだろうか非常に気に掛《か》かるそうであるが、おれは一向そんな感じはなかった。教場で折々しくじるとその時だけはやな心持ちだが三十分ばかり立つと奇麗《きれい》に消えてしまう。おれは何事によらず長く心配しようと思っても心配が出来ない男だ。教場のしくじりが生徒にどんな影響《えいきょう》を与《あた》えて、その影響が校長や教頭にどんな反応を呈《てい》するかまるで無頓着《むとんじゃく》であった。おれは前に云う通りあまり度胸の据《すわ》った男ではないのだが、思い切りはすこぶるいい人間である。この学校がいけなければすぐどっかへ行《ゆ》く覚悟《かくご》でいたから、狸《たぬき》も赤シャツも、ちっとも恐《おそろ》しくはなかった。まして教場の小僧《こぞう》共なんかには愛嬌《あいきょう》もお世辞も使う気になれなかった。学校はそれでいいのだが下宿の方はそうはいかなかった。亭主が茶を飲みに来るだけなら我慢もするが、いろいろな者を持ってくる。始めに持って来たのは何でも印材で、十《とお》ばかり並《なら》べておいて、みんなで三円なら安い物だお買いなさいと云う。田舎巡《いなかまわ》りのヘボ絵師じゃあるまいし、そんなものは入らないと云ったら、今度は華山《かざん》とか何とか云う男の花鳥の掛物《かけもの》をもって来た。自分で床《とこ》の間《ま》へかけて、いい出来じゃありませんかと云うから、そうかなと好加減《いいかげん》に挨拶《あいさつ》をすると、華山には二人《ふたり》ある、一人は何とか華山で、一人は何とか華山ですが、この幅《ふく》はその何とか華山の方だと、くだらない講釈をしたあとで、どうです、あなたなら十五円にしておきます。お買いなさいと催促《さいそく》をする。金がないと断わると、金なんか、いつでもようございますとなかなか頑固《がんこ》だ。金があつても買わないんだと、その時は追っ払《ぱら》っちまった。その次には鬼瓦《おにがわら》ぐらいな大硯《おおすずり》を担ぎ込んだ。これは端渓《たんけい》です、端渓ですと二|遍《へん》も三遍も端渓がるから、面白半分に端渓た何だいと聞いたら、すぐ講釈を始め出した。端渓には上層中層下層とあって、今時のものはみんな上層ですが、これはたしかに中層です、この眼《がん》をご覧なさい。眼が三つあるのは珍《めず》らしい。溌墨《はつぼく》の具合も至極よろしい、試してご覧なさいと、おれの前へ大きな硯を突《つ》きつける。いくらだと聞くと、持主が支那《しな》から持って帰って来て是非売りたいと云いますから、お安くして三十円にしておきましょうと云う。この男は馬鹿《ばか》に相違《そうい》ない。学校の方はどうかこうか無事に勤まりそうだが、こう骨董責《こっとうぜめ》に逢《あ》ってはとても長く続きそうにない。 51 |  そのうち学校もいやになった。  ある日の晩|大町《おおまち》と云う所を散歩していたら郵便局の隣《とな》りに蕎麦《そば》とかいて、下に東京と注を加えた看板があった。おれは蕎麦が大好きである。東京に居《お》った時でも蕎麦屋の前を通って薬味の香《にお》いをかぐと、どうしても暖簾《のれん》がくぐりたくなった。今日までは数学と骨董で蕎麦を忘れていたが、こうして看板を見ると素通りが出来なくなる。ついでだから一杯食って行こうと思って上がり込んだ。見ると看板ほどでもない。東京と断《こと》わる以上はもう少し奇麗にしそうなものだが、東京を知らないのか、金がないのか、滅法《めっぽう》きたない。畳《たたみ》は色が変ってお負けに砂でざらざらしている。壁《かべ》は煤《すす》で真黒《まっくろ》だ。天井《てんじょう》はランプの油烟《ゆえん》で燻《くす》ぼってるのみか、低くって、思わず首を縮めるくらいだ。ただ麗々と蕎麦の名前をかいて張り付けたねだん付けだけは全く新しい。何でも古いうちを買って二三日《にさんち》前から開業したに違《ちが》いなかろう。ねだん付の第一号に天麩羅《てんぷら》とある。おい天麩羅を持ってこいと大きな声を出した。するとこの時まで隅《すみ》の方に三人かたまって、何かつるつる、ちゅうちゅう食ってた連中《れんじゅう》が、ひとしくおれの方を見た。部屋《へや》が暗いので、ちょっと気がつかなかったが顔を合せると、みんな学校の生徒である。先方で挨拶《あいさつ》をしたから、おれも挨拶をした。その晩は久《ひさ》し振《ぶり》に蕎麦を食ったので、旨《うま》かったから天麩羅を四杯|平《たいら》げた。 52 |  翌日何の気もなく教場へはいると、黒板一杯ぐらいな大きな字で、天麩羅先生とかいてある。おれの顔を見てみんなわあと笑った。おれは馬鹿馬鹿しいから、天麩羅を食っちゃ可笑《おか》しいかと聞いた。すると生徒の一人《ひとり》が、しかし四杯は過ぎるぞな、もし、と云った。四杯食おうが五杯食おうがおれの銭でおれが食うのに文句があるもんかと、さっさと講義を済まして控所へ帰って来た。十分立って次の教場へ出ると一つ天麩羅四杯なり。但《ただ》し笑うべからず。と黒板にかいてある。さっきは別に腹も立たなかったが今度は癪《しゃく》に障《さわ》った。冗談《じょうだん》も度を過ごせばいたずらだ。焼餅《やきもち》の黒焦《くろこげ》のようなもので誰《だれ》も賞《ほ》め手はない。田舎者はこの呼吸が分からないからどこまで押《お》して行っても構わないと云う了見《りょうけん》だろう。一時間あるくと見物する町もないような狭《せま》い都に住んで、外に何にも芸がないから、天麩羅事件を日露《にちろ》戦争のように触《ふ》れちらかすんだろう。憐《あわ》れな奴等《やつら》だ。小供の時から、こんなに教育されるから、いやにひねっこびた、植木鉢《うえきばち》の楓《かえで》みたような小人《しょうじん》が出来るんだ。無邪気《むじゃき》ならいっしょに笑ってもいいが、こりゃなんだ。小供の癖《くせ》に乙《おつ》に毒気を持ってる。おれはだまって、天麩羅を消して、こんないたずらが面白いか、卑怯《ひきょう》な冗談だ。君等は卑怯と云う意味を知ってるか、と云ったら、自分がした事を笑われて怒《おこ》るのが卑怯じゃろうがな、もしと答えた奴がある。やな奴だ。わざわざ東京から、こんな奴を教えに来たのかと思ったら情なくなった。余計な減らず口を利かないで勉強しろと云って、授業を始めてしまった。それから次の教場へ出たら天麩羅を食うと減らず口が利きたくなるものなりと書いてある。どうも始末に終えない。あんまり腹が立ったから、そんな生意気な奴は教えないと云ってすたすた帰って来てやった。生徒は休みになって喜んだそうだ。こうなると学校より骨董の方がまだましだ。 53 |  天麩羅蕎麦もうちへ帰って、一晩寝たらそんなに肝癪《かんしゃく》に障らなくなった。学校へ出てみると、生徒も出ている。何だか訳が分らない。それから三日ばかりは無事であったが、四日目の晩に住田《すみた》と云う所へ行って団子《だんご》を食った。この住田と云う所は温泉のある町で城下から汽車だと十分ばかり、歩いて三十分で行かれる、料理屋も温泉宿も、公園もある上に遊廓《ゆうかく》がある。おれのはいった団子屋は遊廓の入口にあって、大変うまいという評判だから、温泉に行った帰りがけにちょっと食ってみた。今度は生徒にも逢わなかったから、誰《だれ》も知るまいと思って、翌日学校へ行って、一時間目の教場へはいると団子二|皿《さら》七銭と書いてある。実際おれは二皿食って七銭|払《はら》った。どうも厄介《やっかい》な奴等だ。二時間目にもきっと何かあると思うと遊廓の団子旨い旨いと書いてある。あきれ返った奴等だ。団子がそれで済んだと思ったら今度は赤手拭《あかてぬぐい》と云うのが評判になった。何の事だと思ったら、つまらない来歴だ。おれはここへ来てから、毎日住田の温泉へ行く事に極《き》めている。ほかの所は何を見ても東京の足元にも及《およ》ばないが温泉だけは立派なものだ。せっかく来た者だから毎日はいってやろうという気で、晩飯前に運動かたがた出掛《でかけ》る。ところが行くときは必ず西洋手拭の大きな奴をぶら下げて行く。この手拭が湯に染《そま》った上へ、赤い縞《しま》が流れ出したのでちょっと見ると紅色《べにいろ》に見える。おれはこの手拭を行きも帰りも、汽車に乗ってもあるいても、常にぶら下げている。それで生徒がおれの事を赤手拭赤手拭と云うんだそうだ。どうも狭い土地に住んでるとうるさいものだ。まだある。温泉は三階の新築で上等は浴衣《ゆかた》をかして、流しをつけて八銭で済む。その上に女が天目《てんもく》へ茶を載《の》せて出す。おれはいつでも上等へはいった。すると四十円の月給で毎日上等へはいるのは贅沢《ぜいたく》だと云い出した。余計なお世話だ。まだある。湯壺《ゆつぼ》は花崗石《みかげいし》を畳《たた》み上げて、十五|畳敷《じょうじき》ぐらいの広さに仕切ってある。大抵《たいてい》は十三四人|漬《つか》ってるがたまには誰も居ない事がある。深さは立って乳の辺まであるから、運動のために、湯の中を泳ぐのはなかなか愉快《ゆかい》だ。おれは人の居ないのを見済《みすま》しては十五畳の湯壺を泳ぎ巡《まわ》って喜んでいた。ところがある日三階から威勢《いせい》よく下りて今日も泳げるかなとざくろ口を覗《のぞ》いてみると、大きな札へ黒々と湯の中で泳ぐべからずとかいて貼《は》りつけてある。湯の中で泳ぐものは、あまりあるまいから、この貼札《はりふだ》はおれのために特別に新調したのかも知れない。おれはそれから泳ぐのは断念した。泳ぐのは断念したが、学校へ出てみると、例の通り黒板に湯の中で泳ぐべからずと書いてあるには驚《おど》ろいた。何だか生徒全体がおれ一人を探偵《たんてい》しているように思われた。くさくさした。生徒が何を云ったって、やろうと思った事をやめるようなおれではないが、何でこんな狭苦しい鼻の先がつかえるような所へ来たのかと思うと情なくなった。それでうちへ帰ると相変らず骨董責である。 54 | 55 | [#5字下げ]四[#「四」は中見出し] 56 | 57 |  学校には宿直があって、職員が代る代るこれをつとめる。但《ただ》し狸《たぬき》と赤シャツは例外である。何でこの両人が当然の義務を免《まぬ》かれるのかと聞いてみたら、奏任待遇《そうにんたいぐう》だからと云う。面白くもない。月給はたくさんとる、時間は少ない、それで宿直を逃《の》がれるなんて不公平があるものか。勝手な規則をこしらえて、それが当《あた》り前《まえ》だというような顔をしている。よくまああんなにずうずうしく出来るものだ。これについては大分不平であるが、山嵐《やまあらし》の説によると、いくら一人《ひとり》で不平を並《なら》べたって通るものじゃないそうだ。一人だって二人《ふたり》だって正しい事なら通りそうなものだ。山嵐は might is right という英語を引いて説諭《せつゆ》を加えたが、何だか要領を得ないから、聞き返してみたら強者の権利と云う意味だそうだ。強者の権利ぐらいなら昔《むかし》から知っている。今さら山嵐から講釈をきかなくってもいい。強者の権利と宿直とは別問題だ。狸や赤シャツが強者だなんて、誰《だれ》が承知するものか。議論は議論としてこの宿直がいよいよおれの番に廻《まわ》って来た。一体|疳性《かんしょう》だから夜具《やぐ》蒲団《ふとん》などは自分のものへ楽に寝ないと寝たような心持ちがしない。小供の時から、友達のうちへ泊《とま》った事はほとんどないくらいだ。友達のうちでさえ厭《いや》なら学校の宿直はなおさら厭だ。厭だけれども、これが四十円のうちへ籠《こも》っているなら仕方がない。我慢《がまん》して勤めてやろう。 58 |  教師も生徒も帰ってしまったあとで、一人ぽかんとしているのは随分《ずいぶん》間が抜《ぬ》けたものだ。宿直部屋は教場の裏手にある寄宿舎の西はずれの一室だ。ちょっとはいってみたが、西日をまともに受けて、苦しくって居たたまれない。田舎《いなか》だけあって秋がきても、気長に暑いもんだ。生徒の賄《まかない》を取りよせて晩飯を済ましたが、まずいには恐《おそ》れ入《い》った。よくあんなものを食って、あれだけに暴れられたもんだ。それで晩飯を急いで四時半に片付けてしまうんだから豪傑《ごうけつ》に違《ちが》いない。飯は食ったが、まだ日が暮《く》れないから寝《ね》る訳に行かない。ちょっと温泉に行きたくなった。宿直をして、外へ出るのはいい事だか、悪《わ》るい事だかしらないが、こうつくねんとして重禁錮《じゅうきんこ》同様な憂目《うきめ》に逢《あ》うのは我慢の出来るもんじゃない。始めて学校へ来た時当直の人はと聞いたら、ちょっと用達《ようたし》に出たと小使《こづかい》が答えたのを妙《みょう》だと思ったが、自分に番が廻《まわ》ってみると思い当る。出る方が正しいのだ。おれは小使にちょっと出てくると云ったら、何かご用ですかと聞くから、用じゃない、温泉へはいるんだと答えて、さっさと出掛《でか》けた。赤手拭《あかてぬぐい》は宿へ忘れて来たのが残念だが今日は先方で借りるとしよう。 59 |  それからかなりゆるりと、出たりはいったりして、ようやく日暮方《ひぐれがた》になったから、汽車へ乗って古町《こまち》の停車場《ていしゃば》まで来て下りた。学校まではこれから四丁だ。訳はないとあるき出すと、向うから狸が来た。狸はこれからこの汽車で温泉へ行こうと云う計画なんだろう。すたすた急ぎ足にやってきたが、擦《す》れ違《ちが》った時おれの顔を見たから、ちょっと挨拶《あいさつ》をした。すると狸はあなたは今日は宿直ではなかったですかねえ[#「なかったですかねえ」に傍点]と真面目《まじめ》くさって聞いた。なかったですかねえもないもんだ。二時間前おれに向って今夜は始めての宿直ですね。ご苦労さま。と礼を云ったじゃないか。校長なんかになるといやに曲りくねった言葉を使うもんだ。おれは腹が立ったから、ええ宿直です。宿直ですから、これから帰って泊る事はたしかに泊りますと云い捨てて済ましてあるき出した。竪町《たてまち》の四つ角までくると今度は山嵐《やまあらし》に出っ喰《く》わした。どうも狭《せま》い所だ。出てあるきさえすれば必ず誰かに逢う。「おい君は宿直じゃないか」と聞くから「うん、宿直だ」と答えたら、「宿直が無暗《むやみ》に出てあるくなんて、不都合《ふつごう》じゃないか」と云った。「ちっとも不都合なもんか、出てあるかない方が不都合だ」と威張《いば》ってみせた。「君のずぼらにも困るな、校長か教頭に出逢うと面倒《めんどう》だぜ」と山嵐に似合わない事を云うから「校長にはたった今逢った。暑い時には散歩でもしないと宿直も骨でしょうと校長が、おれの散歩をほめたよ」と云って、面倒|臭《くさ》いから、さっさと学校へ帰って来た。 60 |  それから日はすぐくれる。くれてから二時間ばかりは小使を宿直部屋へ呼んで話をしたが、それも飽《あ》きたから、寝られないまでも床《とこ》へはいろうと思って、寝巻に着換《きが》えて、蚊帳《かや》を捲《ま》くって、赤い毛布《けっと》を跳《は》ねのけて、とんと尻持《しりもち》を突《つ》いて、仰向《あおむ》けになった。おれが寝るときにとんと尻持をつくのは小供の時からの癖《くせ》だ。わるい癖だと云って小川町《おがわまち》の下宿に居た時分、二階下に居た法律学校の書生が苦情を持ち込《こ》んだ事がある。法律の書生なんてものは弱い癖に、やに口が達者なもので、愚《ぐ》な事を長たらしく述べ立てるから、寝る時にどんどん音がするのはおれの尻がわるいのじゃない。下宿の建築が粗末《そまつ》なんだ。掛《か》ケ合うなら下宿へ掛ケ合えと凹《へこ》ましてやった。この宿直部屋は二階じゃないから、いくら、どしんと倒《たお》れても構わない。なるべく勢《いきおい》よく倒れないと寝たような心持ちがしない。ああ愉快だと足をうんと延ばすと、何だか両足へ飛び付いた。ざらざらして蚤《のみ》のようでもないからこいつあと驚《おど》ろいて、足を二三度|毛布《けっと》の中で振《ふ》ってみた。するとざらざらと当ったものが、急に殖《ふ》え出して脛《すね》が五六カ所、股《もも》が二三カ所、尻の下でぐちゃりと踏《ふ》み潰《つぶ》したのが一つ、臍《へそ》の所まで飛び上がったのが一つ——いよいよ驚ろいた。早速《さっそく》起き上《あが》って、毛布《けっと》をぱっと後ろへ抛《ほう》ると、蒲団の中から、バッタが五六十飛び出した。正体の知れない時は多少気味が悪《わ》るかったが、バッタと相場が極《き》まってみたら急に腹が立った。バッタの癖に人を驚ろかしやがって、どうするか見ろと、いきなり括《くく》り枕《まくら》を取って、二三度|擲《たた》きつけたが、相手が小さ過ぎるから勢よく抛《な》げつける割に利目《ききめ》がない。仕方がないから、また布団の上へ坐《すわ》って、煤掃《すすはき》の時に蓙《ござ》を丸めて畳《たたみ》を叩《たた》くように、そこら近辺を無暗にたたいた。バッタが驚ろいた上に、枕の勢で飛び上がるものだから、おれの肩《かた》だの、頭だの鼻の先だのへくっ付いたり、ぶつかったりする。顔へ付いた奴《やつ》は枕で叩く訳に行かないから、手で攫《つか》んで、一生懸命に擲きつける。忌々《いまいま》しい事に、いくら力を出しても、ぶつかる先が蚊帳だから、ふわりと動くだけで少しも手答がない。バッタは擲きつけられたまま蚊帳へつらまっている。死にもどうもしない。ようやくの事に三十分ばかりでバッタは退治《たいじ》た。箒《ほうき》を持って来てバッタの死骸《しがい》を掃き出した。小使が来て何ですかと云うから、何ですかもあるもんか、バッタを床の中に飼《か》っとく奴がどこの国にある。間抜《まぬけ》め。と叱《しか》ったら、私は存じませんと弁解をした。存じませんで済むかと箒を椽側《えんがわ》へ抛《ほう》り出したら、小使は恐る恐る箒を担いで帰って行った。 61 |  おれは早速寄宿生を三人ばかり総代に呼び出した。すると六人出て来た。六人だろうが十人だろうが構うものか。寝巻のまま腕《うで》まくりをして談判を始めた。 62 | 「なんでバッタなんか、おれの床の中へ入れた」 63 | 「バッタた何ぞな」と真先《まっさき》の一人がいった。やに落ち付いていやがる。この学校じゃ校長ばかりじゃない、生徒まで曲りくねった言葉を使うんだろう。 64 | 「バッタを知らないのか、知らなけりゃ見せてやろう」と云ったが、生憎《あいにく》掃き出してしまって一|匹《ぴき》も居ない。また小使を呼んで、「さっきのバッタを持ってこい」と云ったら、「もう掃溜《はきだめ》へ棄《す》ててしまいましたが、拾って参りましょうか」と聞いた。「うんすぐ拾って来い」と云うと小使は急いで馳《か》け出したが、やがて半紙の上へ十匹ばかり載《の》せて来て「どうもお気の毒ですが、生憎夜でこれだけしか見当りません。あしたになりましたらもっと拾って参ります」と云う。小使まで馬鹿《ばか》だ。おれはバッタの一つを生徒に見せて「バッタたこれだ、大きなずう体をして、バッタを知らないた、何の事だ」と云うと、一番左の方に居た顔の丸い奴が「そりゃ、イナゴぞな、もし」と生意気におれを遣《や》り込《こ》めた。「篦棒《べらぼう》め、イナゴもバッタも同じもんだ。第一先生を捕《つら》まえてなもし[#「なもし」に傍点]た何だ。菜飯《なめし》は田楽《でんがく》の時より外に食うもんじゃない」とあべこべに遣り込めてやったら「なもしと菜飯とは違うぞな、もし」と云った。いつまで行ってもなもし[#「なもし」に傍点]を使う奴だ。 65 | 「イナゴでもバッタでも、何でおれの床の中へ入れたんだ。おれがいつ、バッタを入れてくれと頼《たの》んだ」 66 | 「誰も入れやせんがな」 67 | 「入れないものが、どうして床の中に居るんだ」 68 | 「イナゴは温《ぬく》い所が好きじゃけれ、大方一人でおはいりたのじゃあろ」 69 | 「馬鹿あ云え。バッタが一人でおはいりになるなんて——バッタにおはいりになられてたまるもんか。——さあなぜこんないたずらをしたか、云え」 70 | 「云えてて、入れんものを説明しようがないがな」 71 |  けちな奴等《やつら》だ。自分で自分のした事が云えないくらいなら、てんでしないがいい。証拠《しょうこ》さえ挙がらなければ、しらを切るつもりで図太く構えていやがる。おれだって中学に居た時分は少しはいたずらもしたもんだ。しかしだれがしたと聞かれた時に、尻込みをするような卑怯《ひきょう》な事はただの一度もなかった。したものはしたので、しないものはしないに極《きま》ってる。おれなんぞは、いくら、いたずらをしたって潔白なものだ。嘘を吐《つ》いて罰《ばつ》を逃《に》げるくらいなら、始めからいたずらなんかやるものか。いたずらと罰はつきもんだ。罰があるからいたずらも心持ちよく出来る。いたずらだけで罰はご免蒙《めんこうむ》るなんて下劣《げれつ》な根性がどこの国に流行《はや》ると思ってるんだ。金は借りるが、返す事はご免だと云う連中はみんな、こんな奴等が卒業してやる仕事に相違《そうい》ない。全体中学校へ何しにはいってるんだ。学校へはいって、嘘を吐いて、胡魔化《ごまか》して、陰《かげ》でこせこせ生意気な悪いたずらをして、そうして大きな面で卒業すれば教育を受けたもんだと癇違《かんちが》いをしていやがる。話せない雑兵《ぞうひょう》だ。 72 |  おれはこんな腐《くさ》った了見《りょうけん》の奴等と談判するのは胸糞《むなくそ》が悪《わ》るいから、「そんなに云われなきゃ、聞かなくっていい。中学校へはいって、上品も下品も区別が出来ないのは気の毒なものだ」と云って六人を逐《お》っ放《ぱな》してやった。おれは言葉や様子こそあまり上品じゃないが、心はこいつらよりも遥《はる》かに上品なつもりだ。六人は悠々《ゆうゆう》と引き揚《あ》げた。上部《うわべ》だけは教師のおれよりよっぽどえらく見える。実は落ち付いているだけなお悪るい。おれには到底《とうてい》これほどの度胸はない。 73 |  それからまた床へはいって横になったら、さっきの騒動《そうどう》で蚊帳の中はぶんぶん唸《うな》っている。手燭《てしょく》をつけて一匹ずつ焼くなんて面倒な事は出来ないから、釣手《つりて》をはずして、長く畳《たた》んでおいて部屋の中で横竪《よこたて》十文字に振《ふる》ったら、環《かん》が飛んで手の甲《こう》をいやというほど撲《ぶ》った。三度目に床へはいった時は少々落ち付いたがなかなか寝られない。時計を見ると十時半だ。考えてみると厄介な所へ来たもんだ。一体中学の先生なんて、どこへ行っても、こんなものを相手にするなら気の毒なものだ。よく先生が品切れにならない。よっぽど辛防《しんぼう》強い朴念仁《ぼくねんじん》がなるんだろう。おれには到底やり切れない。それを思うと清《きよ》なんてのは見上げたものだ。教育もない身分もない婆《ばあ》さんだが、人間としてはすこぶる尊《たっ》とい。今まではあんなに世話になって別段|難有《ありがた》いとも思わなかったが、こうして、一人で遠国へ来てみると、始めてあの親切がわかる。越後《えちご》の笹飴《ささあめ》が食いたければ、わざわざ越後まで買いに行って食わしてやっても、食わせるだけの価値は充分《じゅうぶん》ある。清はおれの事を欲がなくって、真直《まっすぐ》な気性だと云って、ほめるが、ほめられるおれよりも、ほめる本人の方が立派な人間だ。何だか清に逢いたくなった。 74 |  清の事を考えながら、のつそつしていると、突然《とつぜん》おれの頭の上で、数で云ったら三四十人もあろうか、二階が落っこちるほどどん、どん、どんと拍子《ひょうし》を取って床板を踏みならす音がした。すると足音に比例した大きな鬨《とき》の声が起《おこ》った。おれは何事が持ち上がったのかと驚ろいて飛び起きた。飛び起きる途端《とたん》に、ははあさっきの意趣返《いしゅがえ》しに生徒があばれるのだなと気がついた。手前のわるい事は悪るかったと言ってしまわないうちは罪は消えないもんだ。わるい事は、手前達に覚《おぼえ》があるだろう。本来なら寝てから後悔《こうかい》してあしたの朝でもあやまりに来るのが本筋だ。たとい、あやまらないまでも恐れ入って、静粛《せいしゅく》に寝ているべきだ。それを何だこの騒《さわ》ぎは。寄宿舎を建てて豚《ぶた》でも飼っておきあしまいし。気狂《きちが》いじみた真似《まね》も大抵《たいてい》にするがいい。どうするか見ろと、寝巻のまま宿直部屋を飛び出して、楷子段《はしごだん》を三股半《みまたはん》に二階まで躍《おど》り上がった。すると不思議な事に、今まで頭の上で、たしかにどたばた暴れていたのが、急に静まり返って、人声どころか足音もしなくなった。これは妙だ。ランプはすでに消してあるから、暗くてどこに何が居るか判然と分《わか》らないが、人気《ひとけ》のあるとないとは様子でも知れる。長く東から西へ貫《つらぬ》いた廊下《ろうか》には鼠《ねずみ》一|匹《ぴき》も隠《かく》れていない。廊下のはずれから月がさして、遥か向うが際どく明るい。どうも変だ、おれは小供の時から、よく夢《ゆめ》を見る癖があって、夢中《むちゅう》に跳ね起きて、わからぬ寝言を云って、人に笑われた事がよくある。十六七の時ダイヤモンドを拾った夢を見た晩なぞは、むくりと立ち上がって、そばに居た兄に、今のダイヤモンドはどうしたと、非常な勢《いきおい》で尋《たず》ねたくらいだ。その時は三日ばかりうち中《じゅう》の笑い草になって大いに弱った。ことによると今のも夢かも知れない。しかしたしかにあばれたに違いないがと、廊下の真中《まんなか》で考え込んでいると、月のさしている向うのはずれで、一二三わあと、三四十人の声がかたまって響《ひび》いたかと思う間もなく、前のように拍子を取って、一同が床板《ゆかいた》を踏み鳴らした。それ見ろ夢じゃないやっぱり事実だ。静かにしろ、夜なかだぞ、とこっちも負けんくらいな声を出して、廊下を向うへ馳《か》けだした。おれの通る路《みち》は暗い、ただはずれに見える月あかりが目標《めじるし》だ。おれが馳け出して二間も来たかと思うと、廊下の真中で、堅《かた》い大きなものに向脛《むこうずね》をぶつけて、あ痛い[#「あ痛い」に傍点]が頭へひびく間に、身体はすとんと前へ抛《ほう》り出された。こん畜生《ちきしょう》と起き上がってみたが、馳けられない。気はせくが、足だけは云う事を利かない。じれったいから、一本足で飛んで来たら、もう足音も人声も静まり返って、森《しん》としている。いくら人間が卑怯だって、こんなに卑怯に出来るものじゃない。まるで豚だ。こうなれば隠れている奴を引きずり出して、あやまらせてやるまではひかないぞと、心を極《き》めて寝室《しんしつ》の一つを開けて中を検査しようと思ったが開かない。錠《じょう》をかけてあるのか、机か何か積んで立て懸《か》けてあるのか、押《お》しても、押しても決して開かない。今度は向う合せの北側の室《へや》を試みた。開かない事はやっぱり同然である。おれが戸を開けて中に居る奴を引っ捕《つ》らまえてやろうと、焦慮《いらっ》てると、また東のはずれで鬨の声と足拍子が始まった。この野郎《やろう》申し合せて、東西相応じておれを馬鹿にする気だな、とは思ったがさてどうしていいか分らない。正直に白状してしまうが、おれは勇気のある割合に智慧《ちえ》が足りない。こんな時にはどうしていいかさっぱりわからない。わからないけれども、決して負けるつもりはない。このままに済ましてはおれの顔にかかわる。江戸《えど》っ子は意気地《いくじ》がないと云われるのは残念だ。宿直をして鼻垂《はなった》れ小僧《こぞう》にからかわれて、手のつけようがなくって、仕方がないから泣き寝入りにしたと思われちゃ一生の名折れだ。これでも元は旗本《はたもと》だ。旗本の元は清和源氏《せいわげんじ》で、多田《ただ》の満仲《まんじゅう》の後裔《こうえい》だ。こんな土百姓《どびゃくしょう》とは生まれからして違うんだ。ただ智慧のないところが惜しいだけだ。どうしていいか分らないのが困るだけだ。困ったって負けるものか。正直だから、どうしていいか分らないんだ。世の中に正直が勝たないで、外に勝つものがあるか、考えてみろ。今夜中に勝てなければ、あした勝つ。あした勝てなければ、あさって勝つ。あさって勝てなければ、下宿から弁当を取り寄せて勝つまでここに居る。おれはこう決心をしたから、廊下の真中へあぐらをかいて夜のあけるのを待っていた。蚊がぶんぶん来たけれども何ともなかった。さっき、ぶつけた向脛を撫《な》でてみると、何だかぬらぬらする。血が出るんだろう。血なんか出たければ勝手に出るがいい。そのうち最前からの疲《つか》れが出て、ついうとうと寝てしまった。何だか騒がしいので、眼《め》が覚めた時はえっ糞《くそ》しまったと飛び上がった。おれの坐《すわ》ってた右側にある戸が半分あいて、生徒が二人、おれの前に立っている。おれは正気に返って、はっと思う途端に、おれの鼻の先にある生徒の足を引《ひ》っ攫《つか》んで、力任せにぐいと引いたら、そいつは、どたりと仰向《あおむけ》に倒れた。ざまを見ろ。残る一人がちょっと狼狽《ろうばい》したところを、飛びかかって、肩を抑《おさ》えて二三度こづき廻したら、あっけに取られて、眼をぱちぱちさせた。さあおれの部屋まで来いと引っ立てると、弱虫だと見えて、一も二もなく尾《つ》いて来た。夜《よ》はとうにあけている。 75 |  おれが宿直部屋へ連れてきた奴を詰問《きつもん》し始めると、豚は、打《ぶ》っても擲いても豚だから、ただ知らんがなで、どこまでも通す了見と見えて、けっして白状しない。そのうち一人来る、二人来る、だんだん二階から宿直部屋へ集まってくる。見るとみんな眠《ねむ》そうに瞼《まぶた》をはらしている。けちな奴等だ。一晩ぐらい寝ないで、そんな面をして男と云われるか。面でも洗って議論に来いと云ってやったが、誰も面を洗いに行かない。 76 |  おれは五十人あまりを相手に約一時間ばかり押問答《おしもんどう》をしていると、ひょっくり狸がやって来た。あとから聞いたら、小使が学校に騒動がありますって、わざわざ知らせに行ったのだそうだ。これしきの事に、校長を呼ぶなんて意気地がなさ過ぎる。それだから中学校の小使なんぞをしてるんだ。 77 |  校長はひと通りおれの説明を聞いた。生徒の言草《いいぐさ》もちょっと聞いた。追って処分するまでは、今まで通り学校へ出ろ。早く顔を洗って、朝飯を食わないと時間に間に合わないから、早くしろと云って寄宿生をみんな放免《ほうめん》した。手温《てぬ》るい事だ。おれなら即席《そくせき》に寄宿生をことごとく退校してしまう。こんな悠長《ゆうちょう》な事をするから生徒が宿直員を馬鹿にするんだ。その上おれに向って、あなたもさぞご心配でお疲れでしょう、今日はご授業に及《およ》ばんと云うから、おれはこう答えた。「いえ、ちっとも心配じゃありません。こんな事が毎晩あっても、命のある間は心配にゃなりません。授業はやります、一晩ぐらい寝なくって、授業が出来ないくらいなら、頂戴《ちょうだい》した月給を学校の方へ割戻《わりもど》します」校長は何と思ったものか、しばらくおれの顔を見つめていたが、しかし顔が大分はれていますよと注意した。なるほど何だか少々重たい気がする。その上べた一面|痒《かゆ》い。蚊がよっぽと刺《さ》したに相違ない。おれは顔中ぼりぼり掻《か》きながら、顔はいくら膨《は》れたって、口はたしかにきけますから、授業には差し支《つか》えませんと答えた。校長は笑いながら、大分元気ですねと賞《ほ》めた。実を云うと賞めたんじゃあるまい、ひやかしたんだろう。 78 | 79 | [#5字下げ]五[#「五」は中見出し] 80 | 81 |  君|釣《つ》りに行きませんかと赤シャツがおれに聞いた。赤シャツは気味の悪《わ》るいように優しい声を出す男である。まるで男だか女だか分《わか》りゃしない。男なら男らしい声を出すもんだ。ことに大学卒業生じゃないか。物理学校でさえおれくらいな声が出るのに、文学士がこれじゃ見っともない。 82 |  おれはそうですなあと少し進まない返事をしたら、君釣をした事がありますかと失敬な事を聞く。あんまりないが、子供の時、小梅《こうめ》の釣堀《つりぼり》で鮒《ふな》を三|匹《びき》釣った事がある。それから神楽坂《かぐらざか》の毘沙門《びしゃもん》の縁日《えんにち》で八寸ばかりの鯉《こい》を針で引っかけて、しめたと思ったら、ぽちゃりと落としてしまったがこれは今考えても惜《お》しいと云《い》ったら、赤シャツは顋《あご》を前の方へ突《つ》き出してホホホホと笑った。何もそう気取って笑わなくっても、よさそうな者だ。「それじゃ、まだ釣りの味は分らんですな。お望みならちと伝授しましょう」とすこぶる得意である。だれがご伝授をうけるものか。一体釣や猟《りょう》をする連中はみんな不人情な人間ばかりだ。不人情でなくって、殺生《せっしょう》をして喜ぶ訳がない。魚だって、鳥だって殺されるより生きてる方が楽に極《き》まってる。釣や猟をしなくっちゃ活計《かっけい》がたたないなら格別だが、何不足なく暮《くら》している上に、生き物を殺さなくっちゃ寝られないなんて贅沢《ぜいたく》な話だ。こう思ったが向《むこ》うは文学士だけに口が達者だから、議論じゃ叶《かな》わないと思って、だまってた。すると先生このおれを降参させたと疳違《かんちが》いして、早速伝授しましょう。おひまなら、今日どうです、いっしょに行っちゃ。吉川《よしかわ》君と二人《ふたり》ぎりじゃ、淋《さむ》しいから、来たまえとしきりに勧める。吉川君というのは画学の教師で例の野だいこの事だ。この野だは、どういう了見《りょうけん》だか、赤シャツのうちへ朝夕|出入《でいり》して、どこへでも随行《ずいこう》して行《ゆ》く。まるで同輩《どうはい》じゃない。主従《しゅうじゅう》みたようだ。赤シャツの行く所なら、野だは必ず行くに極《きま》っているんだから、今さら驚《おど》ろきもしないが、二人で行けば済むところを、なんで無愛想《ぶあいそ》のおれへ口を掛《か》けたんだろう。大方|高慢《こうまん》ちきな釣道楽で、自分の釣るところをおれに見せびらかすつもりかなんかで誘《さそ》ったに違いない。そんな事で見せびらかされるおれじゃない。鮪《まぐろ》の二匹や三匹釣ったって、びくともするもんか。おれだって人間だ、いくら下手《へた》だって糸さえ卸《おろ》しゃ、何かかかるだろう、ここでおれが行かないと、赤シャツの事だから、下手だから行かないんだ、嫌《きら》いだから行かないんじゃないと邪推《じゃすい》するに相違《そうい》ない。おれはこう考えたから、行きましょうと答えた。それから、学校をしまって、一応うちへ帰って、支度《したく》を整えて、停車場で赤シャツと野だを待ち合せて浜《はま》へ行った。船頭は一人《ひとり》で、船《ふね》は細長い東京辺では見た事もない恰好《かっこう》である。さっきから船中|見渡《みわた》すが釣竿《つりざお》が一本も見えない。釣竿なしで釣が出来るものか、どうする了見だろうと、野だに聞くと、沖釣《おきづり》には竿は用いません、糸だけでげすと顋を撫《な》でて黒人《くろうと》じみた事を云った。こう遣《や》り込《こ》められるくらいならだまっていればよかった。 83 |  船頭はゆっくりゆっくり漕《こ》いでいるが熟練は恐《おそろ》しいもので、見返《みか》えると、浜が小さく見えるくらいもう出ている。高柏寺《こうはくじ》の五重の塔《とう》が森の上へ抜《ぬ》け出して針のように尖《とん》がってる。向側《むこうがわ》を見ると青嶋《あおしま》が浮いている。これは人の住まない島だそうだ。よく見ると石と松《まつ》ばかりだ。なるほど石と松ばかりじゃ住めっこない。赤シャツは、しきりに眺望《ちょうぼう》していい景色だと云ってる。野だは絶景でげすと云ってる。絶景だか何だか知らないが、いい心持ちには相違ない。ひろびろとした海の上で、潮風に吹《ふ》かれるのは薬だと思った。いやに腹が減る。「あの松を見たまえ、幹が真直《まっすぐ》で、上が傘《かさ》のように開いてターナーの画にありそうだね」と赤シャツが野だに云うと、野だは「全くターナーですね。どうもあの曲り具合ったらありませんね。ターナーそっくりですよ」と心得顔である。ターナーとは何の事だか知らないが、聞かないでも困らない事だから黙《だま》っていた。舟は島を右に見てぐるりと廻《まわ》った。波は全くない。これで海だとは受け取りにくいほど平《たいら》だ。赤シャツのお陰《かげ》ではなはだ愉快《ゆかい》だ。出来る事なら、あの島の上へ上がってみたいと思ったから、あの岩のある所へは舟はつけられないんですかと聞いてみた。つけられん事もないですが、釣をするには、あまり岸じゃいけないですと赤シャツが異議を申し立てた。おれは黙ってた。すると野だがどうです教頭、これからあの島をターナー島と名づけようじゃありませんかと余計な発議《ほつぎ》をした。赤シャツはそいつは面白い、吾々《われわれ》はこれからそう云おうと賛成した。この吾々のうちにおれもはいってるなら迷惑《めいわく》だ。おれには青嶋でたくさんだ。あの岩の上に、どうです、ラフハエルのマドンナを置いちゃ。いい画が出来ますぜと野だが云うと、マドンナの話はよそうじゃないかホホホホと赤シャツが気味の悪るい笑い方をした。なに誰も居ないから大丈夫《だいじょうぶ》ですと、ちょっとおれの方を見たが、わざと顔をそむけてにやにやと笑った。おれは何だかやな心持ちがした。マドンナだろうが、小旦那《こだんな》だろうが、おれの関係した事でないから、勝手に立たせるがよかろうが、人に分らない事を言って分らないから聞いたって構やしませんてえような風をする。下品な仕草だ。これで当人は私《わたし》も江戸《えど》っ子でげすなどと云ってる。マドンナと云うのは何でも赤シャツの馴染《なじみ》の芸者の渾名《あだな》か何かに違いないと思った。なじみの芸者を無人島の松の木の下に立たして眺《なが》めていれば世話はない。それを野だが油絵にでもかいて展覧会へ出したらよかろう。 84 |  ここいらがいいだろうと船頭は船をとめて、錨《いかり》を卸した。幾尋《いくひろ》あるかねと赤シャツが聞くと、六尋《むひろ》ぐらいだと云う。六尋ぐらいじゃ鯛《たい》はむずかしいなと、赤シャツは糸を海へなげ込んだ。大将鯛を釣る気と見える、豪胆《ごうたん》なものだ。野だは、なに教頭のお手際じゃかかりますよ。それになぎですからとお世辞を云いながら、これも糸を繰《く》り出して投げ入れる。何だか先に錘《おもり》のような鉛《なまり》がぶら下がってるだけだ。浮《うき》がない。浮がなくって釣をするのは寒暖計なしで熱度をはかるようなものだ。おれには到底《とうてい》出来ないと見ていると、さあ君もやりたまえ糸はありますかと聞く。糸はあまるほどあるが、浮がありませんと云ったら、浮がなくっちゃ釣が出来ないのは素人《しろうと》ですよ。こうしてね、糸が水底《みずそこ》へついた時分に、船縁《ふなべり》の所で人指しゆびで呼吸をはかるんです、食うとすぐ手に答える。——そらきた、と先生急に糸をたぐり始めるから、何かかかったと思ったら何にもかからない、餌《え》がなくなってたばかりだ。いい気味《きび》だ。教頭、残念な事をしましたね、今のはたしかに大ものに違いなかったんですが、どうも教頭のお手際でさえ逃《に》げられちゃ、今日は油断ができませんよ。しかし逃げられても何ですね。浮と睨《にら》めくらをしている連中よりはましですね。ちょうど歯どめがなくっちゃ自転車へ乗れないのと同程度ですからねと野だは妙《みよう》な事ばかり喋舌《しゃべ》る。よっぽど撲《なぐ》りつけてやろうかと思った。おれだって人間だ、教頭ひとりで借り切った海じゃあるまいし。広い所だ。鰹《かつお》の一匹ぐらい義理にだって、かかってくれるだろうと、どぼんと錘と糸を抛《ほう》り込んでいい加減に指の先であやつっていた。 85 |  しばらくすると、何だかぴくぴくと糸にあたるものがある。おれは考えた。こいつは魚に相違ない。生きてるものでなくっちゃ、こうぴくつく訳がない。しめた、釣れたとぐいぐい手繰《たぐ》り寄せた。おや釣れましたかね、後世|恐《おそ》るべしだと野だがひやかすうち、糸はもう大概手繰り込んでただ五尺ばかりほどしか、水に浸《つ》いておらん。船縁から覗《のぞ》いてみたら、金魚のような縞《しま》のある魚が糸にくっついて、右左へ漾《ただよ》いながら、手に応じて浮き上がってくる。面白い。水際から上げるとき、ぽちゃりと跳《は》ねたから、おれの顔は潮水だらけになった。ようやくつらまえて、針をとろうとするがなかなか取れない。捕《つら》まえた手はぬるぬるする。大いに気味がわるい。面倒だから糸を振《ふ》って胴《どう》の間《ま》へ擲《たた》きつけたら、すぐ死んでしまった。赤シャツと野だは驚ろいて見ている。おれは海の中で手をざぶざぶと洗って、鼻の先へあてがってみた。まだ腥臭《なまぐさ》い。もう懲《こ》り懲《ご》りだ。何が釣れたって魚は握《にぎ》りたくない。魚も握られたくなかろう。そうそう糸を捲いてしまった。 86 |  一番槍《いちばんやり》はお手柄《てがら》だがゴルキじゃ、と野だがまた生意気を云うと、ゴルキと云うと露西亜《ロシア》の文学者みたような名だねと赤シャツが洒落《しゃれ》た。そうですね、まるで露西亜の文学者ですねと野だはすぐ賛成しやがる。ゴルキが露西亜の文学者で、丸木が芝《しば》の写真師で、米のなる木が命の親だろう。一体この赤シャツはわるい癖《くせ》だ。誰《だれ》を捕《つら》まえても片仮名の唐人《とうじん》の名を並べたがる。人にはそれぞれ専門があったものだ。おれのような数学の教師にゴルキだか車力《しゃりき》だか見当がつくものか、少しは遠慮《えんりょ》するがいい。云《い》うならフランクリンの自伝だとかプッシング、ツー、ゼ、フロントだとか、おれでも知ってる名を使うがいい。赤シャツは時々帝国文学とかいう真赤《まっか》な雑誌を学校へ持って来て難有《ありがた》そうに読んでいる。山嵐《やまあらし》に聞いてみたら、赤シャツの片仮名はみんなあの雑誌から出るんだそうだ。帝国文学も罪な雑誌だ。 87 |  それから赤シャツと野だは一生懸命《いっしょうけんめい》に釣っていたが、約一時間ばかりのうちに二人《ふたり》で十五六上げた。可笑《おか》しい事に釣れるのも、釣れるのも、みんなゴルキばかりだ。鯛なんて薬にしたくってもありゃしない。今日は露西亜文学の大当りだと赤シャツが野だに話している。あなたの手腕《しゅわん》でゴルキなんですから、私《わたし》なんぞがゴルキなのは仕方がありません。当り前ですなと野だが答えている。船頭に聞くとこの小魚は骨が多くって、まずくって、とても食えないんだそうだ。ただ肥料《こやし》には出来るそうだ。赤シャツと野だは一生懸命に肥料を釣っているんだ。気の毒の至りだ。おれは一|匹《ぴき》で懲《こ》りたから、胴の間へ仰向《あおむ》けになって、さっきから大空を眺めていた。釣をするよりこの方がよっぽど洒落《しゃれ》ている。 88 |  すると二人は小声で何か話し始めた。おれにはよく聞《きこ》えない、また聞きたくもない。おれは空を見ながら清《きよ》の事を考えている。金があって、清をつれて、こんな奇麗《きれい》な所へ遊びに来たらさぞ愉快だろう。いくら景色がよくっても野だなどといっしょじゃつまらない。清は皺苦茶《しわくちゃ》だらけの婆さんだが、どんな所へ連れて出たって恥《は》ずかしい心持ちはしない。野だのようなのは、馬車に乗ろうが、船に乗ろうが、凌雲閣《りょううんかく》へのろうが、到底寄り付けたものじゃない。おれが教頭で、赤シャツがおれだったら、やっぱりおれにへけつけお世辞を使って赤シャツを冷《ひや》かすに違いない。江戸っ子は軽薄《けいはく》だと云うがなるほどこんなものが田舎巡《いなかまわ》りをして、私《わたし》は江戸っ子でげすと繰り返していたら、軽薄は江戸っ子で、江戸っ子は軽薄の事だと田舎者が思うに極まってる。こんな事を考えていると、何だか二人がくすくす笑い出した。笑い声の間に何か云うが途切《とぎ》れ途切れでとんと要領を得ない。 89 | 「え? どうだか……」「……全くです……知らないんですから……罪ですね」「まさか……」「バッタを……本当ですよ」 90 |  おれは外の言葉には耳を傾《かたむ》けなかったが、バッタと云う野だの語《ことば》を聴《き》いた時は、思わずきっとなった。野だは何のためかバッタと云う言葉だけことさら力を入れて、明瞭《めいりょう》におれの耳にはいるようにして、そのあとをわざとぼかしてしまった。おれは動かないでやはり聞いていた。 91 | 「また例の堀田《ほった》が……」「そうかも知れない……」「天麩羅《てんぷら》……ハハハハハ」「……煽動《せんどう》して……」「団子《だんご》も?」 92 |  言葉はかように途切れ途切れであるけれども、バッタだの天麩羅だの、団子だのというところをもって推し測ってみると、何でもおれのことについて内所話《ないしょばな》しをしているに相違ない。話すならもっと大きな声で話すがいい、また内所話をするくらいなら、おれなんか誘わなければいい。いけ好かない連中だ。バッタだろうが雪踏《せった》だろうが、非はおれにある事じゃない。校長がひとまずあずけろと云ったから、狸《たぬき》の顔にめんじてただ今のところは控《ひか》えているんだ。野だの癖に入らぬ批評をしやがる。毛筆《けふで》でもしゃぶって引っ込んでるがいい。おれの事は、遅《おそ》かれ早かれ、おれ一人で片付けてみせるから、差支《さしつか》えはないが、また例の堀田が[#「また例の堀田が」に傍点]とか煽動して[#「煽動して」に傍点]とか云う文句が気にかかる。堀田がおれを煽動して騒動《そうどう》を大きくしたと云う意味なのか、あるいは堀田が生徒を煽動しておれをいじめたと云うのか方角がわからない。青空を見ていると、日の光がだんだん弱って来て、少しはひやりとする風が吹き出した。線香《せんこう》の烟《けむり》のような雲が、透《す》き徹《とお》る底の上を静かに伸《の》して行ったと思ったら、いつしか底の奥《おく》に流れ込んで、うすくもやを掛《か》けたようになった。 93 |  もう帰ろうかと赤シャツが思い出したように云うと、ええちょうど時分ですね。今夜はマドンナの君にお逢《あ》いですかと野だが云う。赤シャツは馬鹿《ばか》あ云っちゃいけない、間違いになると、船縁に身を倚《も》たした奴《やつ》を、少し起き直る。エヘヘヘヘ大丈夫ですよ。聞いたって……と野だが振り返った時、おれは皿《さら》のような眼《め》を野だの頭の上へまともに浴びせ掛けてやった。野だはまぼしそうに引っ繰り返って、や、こいつは降参だと首を縮めて、頭を掻《か》いた。何という猪口才《ちょこざい》だろう。 94 |  船は静かな海を岸へ漕《こ》ぎ戻《もど》る。君|釣《つり》はあまり好きでないと見えますねと赤シャツが聞くから、ええ寝《ね》ていて空を見る方がいいですと答えて、吸いかけた巻烟草《まきたばこ》を海の中へたたき込んだら、ジュと音がして艪《ろ》の足で掻き分けられた浪《なみ》の上を揺《ゆ》られながら漾《ただよ》っていった。「君が来たんで生徒も大いに喜んでいるから、奮発《ふんぱつ》してやってくれたまえ」と今度は釣にはまるで縁故《えんこ》もない事を云い出した。「あんまり喜んでもいないでしょう」「いえ、お世辞じゃない。全く喜んでいるんです、ね、吉川君」「喜んでるどころじゃない。大騒《おおさわ》ぎです」と野だはにやにやと笑った。こいつの云う事は一々|癪《しゃく》に障《さわ》るから妙だ。「しかし君注意しないと、険呑《けんのん》ですよ」と赤シャツが云うから「どうせ険呑です。こうなりゃ険呑は覚悟《かくご》です」と云ってやった。実際おれは免職《めんしょく》になるか、寄宿生をことごとくあやまらせるか、どっちか一つにする了見でいた。「そう云っちゃ、取りつきどころもないが——実は僕も教頭として君のためを思うから云うんだが、わるく取っちゃ困る」「教頭は全く君に好意を持ってるんですよ。僕も及《およ》ばずながら、同じ江戸っ子だから、なるべく長くご在校を願って、お互《たがい》に力になろうと思って、これでも蔭ながら尽力《じんりょく》しているんですよ」と野だが人間|並《なみ》の事を云った。野だのお世話になるくらいなら首を縊《くく》って死んじまわあ。 95 | 「それでね、生徒は君の来たのを大変|歓迎《かんげい》しているんだが、そこにはいろいろな事情があってね。君も腹の立つ事もあるだろうが、ここが我慢《がまん》だと思って、辛防《しんぼう》してくれたまえ。決して君のためにならないような事はしないから」 96 | 「いろいろの事情た、どんな事情です」 97 | 「それが少し込み入ってるんだが、まあだんだん分りますよ。僕《ぼく》が話さないでも自然と分って来るです、ね吉川君」 98 | 「ええなかなか込み入ってますからね。一朝一夕にゃ到底分りません。しかしだんだん分ります、僕が話さないでも自然と分って来るです」と野だは赤シャツと同じような事を云う。 99 | 「そんな面倒《めんどう》な事情なら聞かなくてもいいんですが、あなたの方から話し出したから伺《うかが》うんです」 100 | 「そりゃごもっともだ。こっちで口を切って、あとをつけないのは無責任ですね。それじゃこれだけの事を云っておきましょう。あなたは失礼ながら、まだ学校を卒業したてで、教師は始めての、経験である。ところが学校というものはなかなか情実のあるもので、そう書生流に淡泊《たんぱく》には行《ゆ》かないですからね」 101 | 「淡泊に行かなければ、どんな風に行くんです」 102 | 「さあ君はそう率直だから、まだ経験に乏《とぼ》しいと云うんですがね……」 103 | 「どうせ経験には乏しいはずです。履歴書《りれきしょ》にもかいときましたが二十三年四ヶ月ですから」 104 | 「さ、そこで思わぬ辺から乗ぜられる事があるんです」 105 | 「正直にしていれば誰《だれ》が乗じたって怖《こわ》くはないです」 106 | 「無論怖くはない、怖くはないが、乗ぜられる。現に君の前任者がやられたんだから、気を付けないといけないと云うんです」 107 |  野だが大人《おとな》しくなったなと気が付いて、ふり向いて見ると、いつしか艫《とも》の方で船頭と釣の話をしている。野だが居ないんでよっぽど話しよくなった。 108 | 「僕の前任者が、誰《だ》れに乗ぜられたんです」 109 | 「だれと指すと、その人の名誉に関係するから云えない。また判然と証拠《しょうこ》のない事だから云うとこっちの落度になる。とにかく、せっかく君が来たもんだから、ここで失敗しちゃ僕等《ぼくら》も君を呼んだ甲斐《かい》がない。どうか気を付けてくれたまえ」 110 | 「気を付けろったって、これより気の付けようはありません。わるい事をしなけりゃ好《い》いんでしょう」 111 |  赤シャツはホホホホと笑った。別段おれは笑われるような事を云った覚えはない。今日《こんにち》ただ今に至るまでこれでいいと堅《かた》く信じている。考えてみると世間の大部分の人はわるくなる事を奨励《しょうれい》しているように思う。わるくならなければ社会に成功はしないものと信じているらしい。たまに正直な純粋《じゅんすい》な人を見ると、坊《ぼ》っちゃんだの小僧《こぞう》だのと難癖《なんくせ》をつけて軽蔑《けいべつ》する。それじゃ小学校や中学校で嘘《うそ》をつくな、正直にしろと倫理《りんり》の先生が教えない方がいい。いっそ思い切って学校で嘘をつく法とか、人を信じない術とか、人を乗せる策を教授する方が、世のためにも当人のためにもなるだろう。赤シャツがホホホホと笑ったのは、おれの単純なのを笑ったのだ。単純や真率が笑われる世の中じゃ仕様がない。清はこんな時に決して笑った事はない。大いに感心して聞いたもんだ。清の方が赤シャツよりよっぽど上等だ。 112 | 「無論|悪《わ》るい事をしなければ好いんですが、自分だけ悪るい事をしなくっても、人の悪るいのが分らなくっちゃ、やっぱりひどい目に逢うでしょう。世の中には磊落《らいらく》なように見えても、淡泊なように見えても、親切に下宿の世話なんかしてくれても、めったに油断の出来ないのがありますから……。大分寒くなった。もう秋ですね、浜の方は靄《もや》でセピヤ色になった。いい景色だ。おい、吉川君どうだい、あの浜の景色は……」と大きな声を出して野だを呼んだ。なあるほどこりゃ奇絶《きぜつ》ですね。時間があると写生するんだが、惜《お》しいですね、このままにしておくのはと野だは大いにたたく。 113 |  港屋の二階に灯が一つついて、汽車の笛《ふえ》がヒューと鳴るとき、おれの乗っていた舟は磯《いそ》の砂へざぐりと、舳《へさき》をつき込んで動かなくなった。お早うお帰りと、かみさんが、浜に立って赤シャツに挨拶《あいさつ》する。おれは船端《ふなばた》から、やっと掛声《かけごえ》をして磯へ飛び下りた。 114 | 115 | [#5字下げ]六[#「六」は中見出し] 116 | 117 |  野だは大嫌《だいきら》いだ。こんな奴《やつ》は沢庵石《たくあんいし》をつけて海の底へ沈《しず》めちまう方が日本のためだ。赤シャツは声が気に食わない。あれは持前の声をわざと気取ってあんな優しいように見せてるんだろう。いくら気取ったって、あの面じゃ駄目《だめ》だ。惚《ほ》れるものがあったってマドンナぐらいなものだ。しかし教頭だけに野だよりむずかしい事を云《い》う。うちへ帰って、あいつの申し条を考えてみると一応もっとものようでもある。はっきりとした事は云わないから、見当がつきかねるが、何でも山嵐《やまあらし》がよくない奴だから用心しろと云うのらしい。それならそうとはっきり断言するがいい、男らしくもない。そうして、そんな悪《わ》るい教師なら、早く免職《めんしょく》さしたらよかろう。教頭なんて文学士の癖《くせ》に意気地《いくじ》のないもんだ。蔭口《かげぐち》をきくのでさえ、公然と名前が云えないくらいな男だから、弱虫に極《き》まってる。弱虫は親切なものだから、あの赤シャツも女のような親切ものなんだろう。親切は親切、声は声だから、声が気に入らないって、親切を無にしちゃ筋が違《ちが》う。それにしても世の中は不思議なものだ、虫の好かない奴が親切で、気のあった友達が悪漢《わるもの》だなんて、人を馬鹿《ばか》にしている。大方|田舎《いなか》だから万事東京のさかに行くんだろう。物騒《ぶっそう》な所だ。今に火事が氷って、石が豆腐《とうふ》になるかも知れない。しかし、あの山嵐が生徒を煽動するなんて、いたずらをしそうもないがな。一番人望のある教師だと云うから、やろうと思ったら大抵《たいてい》の事は出来るかも知れないが、——第一そんな廻《まわ》りくどい事をしないでも、じかにおれを捕《つら》まえて喧嘩《けんか》を吹き懸《か》けりゃ手数が省ける訳だ。おれが邪魔《じゃま》になるなら、実はこれこれだ、邪魔だから辞職してくれと云や、よさそうなもんだ。物は相談ずくでどうでもなる。向《むこ》うの云い条がもっともなら、明日にでも辞職してやる。ここばかり米が出来る訳でもあるまい。どこの果《はて》へ行ったって、のたれ死《じに》はしないつもりだ。山嵐もよっぽど話せない奴だな。 118 |  ここへ来た時第一番に氷水を奢《おご》ったのは山嵐だ。そんな裏表のある奴から、氷水でも奢ってもらっちゃ、おれの顔に関わる。おれはたった一|杯《ぱい》しか飲まなかったから一銭五|厘《りん》しか払《はら》わしちゃない。しかし一銭だろうが五厘だろうが、詐欺師《さぎし》の恩になっては、死ぬまで心持ちがよくない。あした学校へ行ったら、一銭五厘返しておこう。おれは清《きよ》から三円借りている。その三円は五年|経《た》った今日までまだ返さない。返せないんじゃない。返さないんだ。清は今に返すだろうなどと、かりそめにもおれの懐中《かいちゅう》をあてにしてはいない。おれも今に返そうなどと他人がましい義理立てはしないつもりだ。こっちがこんな心配をすればするほど清の心を疑ぐるようなもので、清の美しい心にけちを付けると同じ事になる。返さないのは清を踏《ふ》みつけるのじゃない、清をおれの片破《かたわ》れと思うからだ。清と山嵐とはもとより比べ物にならないが、たとい氷水だろうが、甘茶《あまちゃ》だろうが、他人から恵《めぐみ》を受けて、だまっているのは向うをひとかどの人間と見立てて、その人間に対する厚意の所作だ。割前を出せばそれだけの事で済むところを、心のうちで難有《ありがた》いと恩に着るのは銭金で買える返礼じゃない。無位無冠でも一人前の独立した人間だ。独立した人間が頭を下げるのは百万両より尊《たっ》といお礼と思わなければならない。 119 |  おれはこれでも山嵐に一銭五厘|奮発《ふんぱつ》させて、百万両より尊とい返礼をした気でいる。山嵐は難有《ありがた》いと思ってしかるべきだ。それに裏へ廻って卑劣《ひれつ》な振舞《ふるまい》をするとは怪《け》しからん野郎《やろう》だ。あした行って一銭五厘返してしまえば借りも貸しもない。そうしておいて喧嘩をしてやろう。 120 |  おれはここまで考えたら、眠《ねむ》くなったからぐうぐう寝《ね》てしまった。あくる日は思う仔細《しさい》があるから、例刻より早ヤ目に出校して山嵐を待ち受けた。ところがなかなか出て来ない。うらなりが出て来る。漢学の先生が出て来る。野だが出て来る。しまいには赤シャツまで出て来たが山嵐の机の上は白墨《はくぼく》が一本|竪《たて》に寝ているだけで閑静《かんせい》なものだ。おれは、控所《ひかえじょ》へはいるや否や返そうと思って、うちを出る時から、湯銭のように手の平へ入れて一銭五厘、学校まで握《にぎ》って来た。おれは膏《あぶら》っ手だから、開けてみると一銭五厘が汗《あせ》をかいている。汗をかいてる銭を返しちゃ、山嵐が何とか云うだろうと思ったから、机の上へ置いてふうふう吹いてまた握った。ところへ赤シャツが来て昨日は失敬、迷惑《めいわく》でしたろうと云ったから、迷惑じゃありません、お蔭で腹が減りましたと答えた。すると赤シャツは山嵐の机の上へ肱《ひじ》を突《つ》いて、あの盤台面《ばんだいづら》をおれの鼻の側面へ持って来たから、何をするかと思ったら、君昨日返りがけに船の中で話した事は、秘密にしてくれたまえ。まだ誰《だれ》にも話しやしますまいねと云った。女のような声を出すだけに心配性な男と見える。話さない事はたしかである。しかしこれから話そうと云う心持ちで、すでに一銭五厘手の平に用意しているくらいだから、ここで赤シャツから口留めをされちゃ、ちと困る。赤シャツも赤シャツだ。山嵐と名を指さないにしろ、あれほど推察の出来る謎《なぞ》をかけておきながら、今さらその謎を解いちゃ迷惑だとは教頭とも思えぬ無責任だ。元来ならおれが山嵐と戦争をはじめて鎬《しのぎ》を削《けず》ってる真中《まんなか》へ出て堂々とおれの肩《かた》を持つべきだ。それでこそ一校の教頭で、赤シャツを着ている主意も立つというもんだ。 121 |  おれは教頭に向《むか》って、まだ誰にも話さないが、これから山嵐と談判するつもりだと云ったら、赤シャツは大いに狼狽《ろうばい》して、君そんな無法な事をしちゃ困る。僕《ぼく》は堀田《ほった》君の事について、別段君に何も明言した覚えはないんだから——君がもしここで乱暴を働いてくれると、僕は非常に迷惑する。君は学校に騒動《そうどう》を起すつもりで来たんじゃなかろうと妙《みょう》に常識をはずれた質問をするから、当《あた》り前《まえ》です、月給をもらったり、騒動を起したりしちゃ、学校の方でも困るでしょうと云った。すると赤シャツはそれじゃ昨日の事は君の参考だけにとめて、口外してくれるなと汗をかいて依頼《いらい》に及《およ》ぶから、よろしい、僕も困るんだが、そんなにあなたが迷惑ならよしましょうと受け合った。君|大丈夫《だいじょうぶ》かいと赤シャツは念を押《お》した。どこまで女らしいんだか奥行《おくゆき》がわからない。文学士なんて、みんなあんな連中ならつまらんものだ。辻褄《つじつま》の合わない、論理に欠けた注文をして恬然《てんぜん》としている。しかもこのおれを疑ぐってる。憚《はばか》りながら男だ。受け合った事を裏へ廻って反古《ほご》にするようなさもしい了見《りょうけん》はもってるもんか。 122 |  ところへ両隣《りょうどな》りの机の所有主も出校したんで、赤シャツは早々自分の席へ帰って行った。赤シャツは歩《あ》るき方から気取ってる。部屋の中を往来するのでも、音を立てないように靴《くつ》の底をそっと落《おと》す。音を立てないであるくのが自慢《じまん》になるもんだとは、この時から始めて知った。泥棒《どろぼう》の稽古《けいこ》じゃあるまいし、当り前にするがいい。やがて始業の喇叭《らっぱ》がなった。山嵐はとうとう出て来ない。仕方がないから、一銭五厘を机の上へ置いて教場へ出掛《でか》けた。 123 |  授業の都合《つごう》で一時間目は少し後《おく》れて、控所へ帰ったら、ほかの教師はみんな机を控えて話をしている。山嵐もいつの間にか来ている。欠勤だと思ったら遅刻《ちこく》したんだ。おれの顔を見るや否や今日は君のお蔭で遅刻したんだ。罰金《ばっきん》を出したまえと云った。おれは机の上にあった一銭五厘を出して、これをやるから取っておけ。先達《せんだっ》て通町《とおりちょう》で飲んだ氷水の代だと山嵐の前へ置くと、何を云ってるんだと笑いかけたが、おれが存外|真面目《まじめ》でいるので、つまらない冗談《じょうだん》をするなと銭をおれの机の上に掃《は》き返した。おや山嵐の癖《くせ》にどこまでも奢る気だな。 124 | 「冗談じゃない本当だ。おれは君に氷水を奢られる因縁《いんえん》がないから、出すんだ。取らない法があるか」 125 | 「そんなに一銭五厘が気になるなら取ってもいいが、なぜ思い出したように、今時分返すんだ」 126 | 「今時分でも、いつ時分でも、返すんだ。奢られるのが、いやだから返すんだ」 127 |  山嵐は冷然とおれの顔を見てふんと云った。赤シャツの依頼がなければ、ここで山嵐の卑劣《ひれつ》をあばいて大喧嘩をしてやるんだが、口外しないと受け合ったんだから動きがとれない。人がこんなに真赤《まっか》になってるのにふんという理窟《りくつ》があるものか。 128 | 「氷水の代は受け取るから、下宿は出てくれ」 129 | 「一銭五厘受け取ればそれでいい。下宿を出ようが出まいがおれの勝手だ」 130 | 「ところが勝手でない、昨日、あすこの亭主《ていしゅ》が来て君に出てもらいたいと云うから、その訳を聞いたら亭主の云うのはもっともだ。それでももう一応たしかめるつもりで今朝《けさ》あすこへ寄って詳《くわ》しい話を聞いてきたんだ」 131 |  おれには山嵐の云う事が何の意味だか分らない。 132 | 「亭主が君に何を話したんだか、おれが知ってるもんか。そう自分だけで極めたって仕様があるか。訳があるなら、訳を話すが順だ。てんから亭主の云う方がもっともだなんて失敬千万な事を云うな」 133 | 「うん、そんなら云ってやろう。君は乱暴であの下宿で持て余《あ》まされているんだ。いくら下宿の女房だって、下女たあ違うぜ。足を出して拭《ふ》かせるなんて、威張《いば》り過ぎるさ」 134 | 「おれが、いつ下宿の女房に足を拭かせた」 135 | 「拭かせたかどうだか知らないが、とにかく向うじゃ、君に困ってるんだ。下宿料の十円や十五円は懸物《かけもの》を一|幅《ぷく》売りゃ、すぐ浮《う》いてくるって云ってたぜ」 136 | 「利いた風な事をぬかす野郎《やろう》だ。そんなら、なぜ置いた」 137 | 「なぜ置いたか、僕は知らん、置くことは置いたんだが、いやになったんだから、出ろと云うんだろう。君出てやれ」 138 | 「当り前だ。居てくれと手を合せたって、居るものか。一体そんな云い懸《がか》りを云うような所へ周旋《しゅうせん》する君からしてが不埒《ふらち》だ」 139 | 「おれが不埒か、君が大人《おとな》しくないんだか、どっちかだろう」 140 |  山嵐もおれに劣《おと》らぬ肝癪持《かんしゃくも》ちだから、負け嫌《ぎら》いな大きな声を出す。控所に居た連中は何事が始まったかと思って、みんな、おれと山嵐の方を見て、顋《あご》を長くしてぼんやりしている。おれは、別に恥《は》ずかしい事をした覚えはないんだから、立ち上がりながら、部屋中一通り見巡《みま》わしてやった。みんなが驚《おど》ろいてるなかに野だだけは面白そうに笑っていた。おれの大きな眼《め》が、貴様も喧嘩をするつもりかと云う権幕で、野だの干瓢《かんぴょう》づらを射貫《いぬ》いた時に、野だは突然《とつぜん》真面目な顔をして、大いにつつしんだ。少し怖《こ》わかったと見える。そのうち喇叭が鳴る。山嵐もおれも喧嘩を中止して教場へ出た。 141 | 142 |  午後は、先夜おれに対して無礼を働いた寄宿生の処分法についての会議だ。会議というものは生れて始めてだからとんと容子《ようす》が分らないが、職員が寄って、たかって自分勝手な説をたてて、それを校長が好い加減に纏《まと》めるのだろう。纏めるというのは黒白《こくびゃく》の決しかねる事柄《ことがら》について云うべき言葉だ。この場合のような、誰が見たって、不都合としか思われない事件に会議をするのは暇潰《ひまつぶ》しだ。誰が何と解釈したって異説の出ようはずがない。こんな明白なのは即座《そくざ》に校長が処分してしまえばいいに。随分《ずいぶん》決断のない事だ。校長ってものが、これならば、何の事はない、煮《に》え切《き》らない愚図《ぐず》の異名だ。 143 |  会議室は校長室の隣《とな》りにある細長い部屋で、平常は食堂の代理を勤める。黒い皮で張った椅子《いす》が二十|脚《きゃく》ばかり、長いテーブルの周囲に並《なら》んでちょっと神田の西洋料理屋ぐらいな格だ。そのテーブルの端《はじ》に校長が坐《すわ》って、校長の隣りに赤シャツが構える。あとは勝手次第に席に着くんだそうだが、体操《たいそう》の教師だけはいつも席末に謙遜《けんそん》するという話だ。おれは様子が分らないから、博物の教師と漢学の教師の間へはいり込《こ》んだ。向うを見ると山嵐と野だが並んでる。野だの顔はどう考えても劣等だ。喧嘩はしても山嵐の方が遥《はる》かに趣《おもむき》がある。おやじの葬式《そうしき》の時に小日向《こびなた》の養源寺《ようげんじ》の座敷《ざしき》にかかってた懸物はこの顔によく似ている。坊主《ぼうず》に聞いてみたら韋駄天《いだてん》と云う怪物だそうだ。今日は怒《おこ》ってるから、眼をぐるぐる廻しちゃ、時々おれの方を見る。そんな事で威嚇《おど》かされてたまるもんかと、おれも負けない気で、やっぱり眼をぐりつかせて、山嵐をにらめてやった。おれの眼は恰好《かっこう》はよくないが、大きい事においては大抵な人には負けない。あなたは眼が大きいから役者になるときっと似合いますと清がよく云ったくらいだ。 144 |  もう大抵お揃《そろ》いでしょうかと校長が云うと、書記の川村と云うのが一つ二つと頭数を勘定《かんじょう》してみる。一人足りない。一人不足ですがと考えていたが、これは足りないはずだ。唐茄子《とうなす》のうらなり君が来ていない。おれとうらなり君とはどう云う宿世《すくせ》の因縁かしらないが、この人の顔を見て以来どうしても忘れられない。控所へくれば、すぐ、うらなり君が眼に付く、途中《とちゅう》をあるいていても、うらなり先生の様子が心に浮《うか》ぶ。温泉へ行くと、うらなり君が時々|蒼《あお》い顔をして湯壺《ゆつぼ》のなかに膨《ふく》れている。挨拶《あいさつ》をするとへえと恐縮《きょうしゅく》して頭を下げるから気の毒になる。学校へ出てうらなり君ほど大人しい人は居ない。めったに笑った事もないが、余計な口をきいた事もない。おれは君子という言葉を書物の上で知ってるが、これは字引にあるばかりで、生きてるものではないと思ってたが、うらなり君に逢《あ》ってから始めて、やっぱり正体のある文字だと感心したくらいだ。 145 |  このくらい関係の深い人の事だから、会議室へはいるや否や、うらなり君の居ないのは、すぐ気がついた。実を云うと、この男の次へでも坐《す》わろうかと、ひそかに目標《めじるし》にして来たくらいだ。校長はもうやがて見えるでしょうと、自分の前にある紫《むらさき》の袱紗包《ふくさづつみ》をほどいて、蒟蒻版《こんにゃくばん》のような者を読んでいる。赤シャツは琥珀《こはく》のパイプを絹ハンケチで磨《みが》き始めた。この男はこれが道楽である。赤シャツ相当のところだろう。ほかの連中は隣り同志で何だか私語《ささや》き合っている。手持無沙汰《てもちぶさた》なのは鉛筆《えんぴつ》の尻《しり》に着いている、護謨《ゴム》の頭でテーブルの上へしきりに何か書いている。野だは時々山嵐に話しかけるが、山嵐は一向応じない。ただうん[#「うん」に傍点]とかああ[#「ああ」に傍点]と云うばかりで、時々|怖《こわ》い眼をして、おれの方を見る。おれも負けずに睨《にら》め返す。 146 |  ところへ待ちかねた、うらなり君が気の毒そうにはいって来て少々用事がありまして、遅刻|致《いた》しましたと慇懃《いんぎん》に狸《たぬき》に挨拶《あいさつ》をした。では会議を開きますと狸はまず書記の川村君に蒟蒻版を配布させる。見ると最初が処分の件、次が生徒|取締《とりしまり》の件、その他二三ヶ条である。狸は例の通りもったいぶって、教育の生霊《いきりょう》という見えでこんな意味の事を述べた。「学校の職員や生徒に過失のあるのは、みんな自分の寡徳《かとく》の致すところで、何か事件がある度に、自分はよくこれで校長が勤まるとひそかに慚愧《ざんき》の念に堪《た》えんが、不幸にして今回もまたかかる騒動を引き起したのは、深く諸君に向って謝罪しなければならん。しかしひとたび起った以上は仕方がない、どうにか処分をせんければならん、事実はすでに諸君のご承知の通りであるからして、善後策について腹蔵のない事を参考のためにお述べ下さい」 147 |  おれは校長の言葉を聞いて、なるほど校長だの狸だのと云うものは、えらい事を云うもんだと感心した。こう校長が何もかも責任を受けて、自分の咎《とが》だとか、不徳だとか云うくらいなら、生徒を処分するのは、やめにして、自分から先へ免職《めんしょく》になったら、よさそうなもんだ。そうすればこんな面倒《めんどう》な会議なんぞを開く必要もなくなる訳だ。第一常識から云《い》っても分ってる。おれが大人しく宿直をする。生徒が乱暴をする。わるいのは校長でもなけりゃ、おれでもない、生徒だけに極《きま》ってる。もし山嵐が煽動《せんどう》したとすれば、生徒と山嵐を退治《たいじ》ればそれでたくさんだ。人の尻《しり》を自分で背負《しょ》い込《こ》んで、おれの尻だ、おれの尻だと吹き散らかす奴が、どこの国にあるもんか、狸でなくっちゃ出来る芸当じゃない。彼《かれ》はこんな条理《じょうり》に適《かな》わない議論を吐《は》いて、得意気に一同を見廻した。ところが誰も口を開くものがない。博物の教師は第一教場の屋根に烏《からす》がとまってるのを眺《なが》めている。漢学の先生は蒟蒻版《こんにゃくばん》を畳《たた》んだり、延ばしたりしてる。山嵐はまだおれの顔をにらめている。会議と云うものが、こんな馬鹿気《ばかげ》たものなら、欠席して昼寝でもしている方がましだ。 148 |  おれは、じれったくなったから、一番大いに弁じてやろうと思って、半分尻をあげかけたら、赤シャツが何か云い出したから、やめにした。見るとパイプをしまって、縞《しま》のある絹ハンケチで顔をふきながら、何か云っている。あの手巾《はんけち》はきっとマドンナから巻き上げたに相違《そうい》ない。男は白い麻《あさ》を使うもんだ。「私も寄宿生の乱暴を聞いてはなはだ教頭として不行届《ふゆきとどき》であり、かつ平常の徳化が少年に及ばなかったのを深く慚《は》ずるのであります。でこう云う事は、何か陥欠《かんけつ》があると起るもので、事件その物を見ると何だか生徒だけがわるいようであるが、その真相を極めると責任はかえって学校にあるかも知れない。だから表面上にあらわれたところだけで厳重な制裁を加えるのは、かえって未来のためによくないかとも思われます。かつ少年血気のものであるから活気があふれて、善悪の考えはなく、半ば無意識にこんな悪戯《いたずら》をやる事はないとも限らん。でもとより処分法は校長のお考えにある事だから、私の容喙《ようかい》する限りではないが、どうかその辺をご斟酌《しんしゃく》になって、なるべく寛大なお取計《とりはからい》を願いたいと思います」 149 |  なるほど狸が狸なら、赤シャツも赤シャツだ。生徒があばれるのは、生徒がわるいんじゃない教師が悪るいんだと公言している。気狂《きちがい》が人の頭を撲《なぐ》り付けるのは、なぐられた人がわるいから、気狂がなぐるんだそうだ。難有《ありがた》い仕合せだ。活気にみちて困るなら運動場へ出て相撲《すもう》でも取るがいい、半ば無意識に床の中へバッタを入れられてたまるものか。この様子じゃ寝頸《ねくび》をかかれても、半ば無意識だって放免するつもりだろう。 150 |  おれはこう考えて何か云おうかなと考えてみたが、云うなら人を驚ろすかように滔々《とうとう》と述べたてなくっちゃつまらない、おれの癖として、腹が立ったときに口をきくと、二言か三言で必ず行き塞《つま》ってしまう。狸でも赤シャツでも人物から云うと、おれよりも下等だが、弁舌はなかなか達者だから、まずい事を喋舌《しゃべ》って揚足《あげあし》を取られちゃ面白くない。ちょっと腹案を作ってみようと、胸のなかで文章を作ってる。すると前に居た野だが突然起立したには驚ろいた。野だの癖に意見を述べるなんて生意気だ。野だは例のへらへら調で「実に今回のバッタ事件及び咄喊《とっかん》事件は吾々《われわれ》心ある職員をして、ひそかに吾《わが》校将来の前途《ぜんと》に危惧《きぐ》の念を抱《いだ》かしむるに足る珍事《ちんじ》でありまして、吾々職員たるものはこの際|奮《ふる》って自ら省りみて、全校の風紀を振粛《しんしゅく》しなければなりません。それでただ今校長及び教頭のお述べになったお説は、実に肯綮《こうけい》に中《あた》った剴切《がいせつ》なお考えで私は徹頭徹尾《てっとうてつび》賛成致します。どうかなるべく寛大《かんだい》のご処分を仰《あお》ぎたいと思います」と云った。野だの云う事は言語はあるが意味がない、漢語をのべつに陳列《ちんれつ》するぎりで訳が分らない。分ったのは徹頭徹尾賛成致しますと云う言葉だけだ。 151 |  おれは野だの云う意味は分らないけれども、何だか非常に腹が立ったから、腹案も出来ないうちに起《た》ち上がってしまった。「私は徹頭徹尾反対です……」と云ったがあとが急に出て来ない。「……そんな頓珍漢《とんちんかん》な、処分は大嫌《だいきら》いです」とつけたら、職員が一同笑い出した。「一体生徒が全然|悪《わ》るいです。どうしても詫《あや》まらせなくっちゃ、癖になります。退校さしても構いません。……何だ失敬な、新しく来た教師だと思って……」と云って着席した。すると右隣りに居る博物が「生徒がわるい事も、わるいが、あまり厳重な罰などをするとかえって反動を起していけないでしょう。やっぱり教頭のおっしゃる通り、寛な方に賛成します」と弱い事を云った。左隣の漢学は穏便説《おんびんせつ》に賛成と云った。歴史も教頭と同説だと云った。忌々《いまいま》しい、大抵のものは赤シャツ党だ。こんな連中が寄り合って学校を立てていりゃ世話はない。おれは生徒をあやまらせるか、辞職するか二つのうち一つに極めてるんだから、もし赤シャツが勝ちを制したら、早速うちへ帰って荷作りをする覚悟《かくご》でいた。どうせ、こんな手合《てあい》を弁口《べんこう》で屈伏《くっぷく》させる手際はなし、させたところでいつまでご交際を願うのは、こっちでご免だ。学校に居ないとすればどうなったって構うもんか。また何か云うと笑うに違いない。だれが云うもんかと澄《すま》していた。 152 |  すると今までだまって聞いていた山嵐が奮然として、起ち上がった。野郎また赤シャツ賛成の意を表するな、どうせ、貴様とは喧嘩だ、勝手にしろと見ていると山嵐は硝子《ガラス》窓を振《ふる》わせるような声で「私《わたくし》は教頭及びその他諸君のお説には全然不同意であります。というものはこの事件はどの点から見ても、五十名の寄宿生が新来の教師|某氏《ぼうし》を軽侮《けいぶ》してこれを翻弄《ほんろう》しようとした所為《しょい》とより外《ほか》には認められんのであります。教頭はその源因を教師の人物いかんにお求めになるようでありますが失礼ながらそれは失言かと思います。某氏が宿直にあたられたのは着後早々の事で、まだ生徒に接せられてから二十日に満たぬ頃《ころ》であります。この短かい二十日間において生徒は君の学問人物を評価し得る余地がないのであります。軽侮されべき至当な理由があって、軽侮を受けたのなら生徒の行為に斟酌《しんしゃく》を加える理由もありましょうが、何らの源因もないのに新来の先生を愚弄《ぐろう》するような軽薄な生徒を寛仮《かんか》しては学校の威信《いしん》に関わる事と思います。教育の精神は単に学問を授けるばかりではない、高尚《こうしょう》な、正直な、武士的な元気を鼓吹《こすい》すると同時に、野卑《やひ》な、軽躁《けいそう》な、暴慢《ぼうまん》な悪風を掃蕩《そうとう》するにあると思います。もし反動が恐《おそろ》しいの、騒動が大きくなるのと姑息《こそく》な事を云った日にはこの弊風《へいふう》はいつ矯正《きょうせい》出来るか知れません。かかる弊風を杜絶《とぜつ》するためにこそ吾々はこの学校に職を奉じているので、これを見逃《みの》がすくらいなら始めから教師にならん方がいいと思います。私は以上の理由で寄宿生一同を厳罰《げんばつ》に処する上に、当該《とうがい》教師の面前において公けに謝罪の意を表せしむるのを至当の所置と心得ます」と云いながら、どんと腰《こし》を卸《おろ》した。一同はだまって何にも言わない。赤シャツはまたパイプを拭《ふ》き始めた。おれは何だか非常に嬉《うれ》しかった。おれの云おうと思うところをおれの代りに山嵐がすっかり言ってくれたようなものだ。おれはこう云う単純な人間だから、今までの喧嘩はまるで忘れて、大いに難有《ありがた》いと云う顔をもって、腰を卸した山嵐の方を見たら、山嵐は一向知らん面《かお》をしている。 153 |  しばらくして山嵐はまた起立した。「ただ今ちょっと失念して言い落《おと》しましたから、申します。当夜の宿直員は宿直中外出して温泉に行かれたようであるが、あれはもっての外の事と考えます。いやしくも自分が一校の留守番を引き受けながら、咎《とが》める者のないのを幸《さいわい》に、場所もあろうに温泉などへ入湯にいくなどと云うのは大きな失体である。生徒は生徒として、この点については校長からとくに責任者にご注意あらん事を希望します」 154 |  妙な奴だ、ほめたと思ったら、あとからすぐ人の失策をあばいている。おれは何の気もなく、前の宿直が出あるいた事を知って、そんな習慣だと思って、つい温泉まで行ってしまったんだが、なるほどそう云われてみると、これはおれが悪るかった。攻撃《こうげき》されても仕方がない。そこでおれはまた起って「私は正に宿直中に温泉に行きました。これは全くわるい。あやまります」と云って着席したら、一同がまた笑い出した。おれが何か云いさえすれば笑う。つまらん奴等《やつら》だ。貴様等これほど自分のわるい事を公けにわるかったと断言出来るか、出来ないから笑うんだろう。 155 |  それから校長は、もう大抵ご意見もないようでありますから、よく考えた上で処分しましょうと云った。ついでだからその結果を云うと、寄宿生は一週間の禁足になった上に、おれの前へ出て謝罪をした。謝罪をしなければその時辞職して帰るところだったがなまじい、おれのいう通りになったのでとうとう大変な事になってしまった。それはあとから話すが、校長はこの時会議の引き続きだと号してこんな事を云った。生徒の風儀《ふうぎ》は、教師の感化で正していかなくてはならん、その一着手として、教師はなるべく飲食店などに出入《しゅつにゅう》しない事にしたい。もっとも送別会などの節は特別であるが、単独にあまり上等でない場所へ行くのはよしたい——たとえば蕎麦屋《そばや》だの、団子屋《だんごや》だの——と云いかけたらまた一同が笑った。野だが山嵐を見て天麩羅《てんぷら》と云って目くばせをしたが山嵐は取り合わなかった。いい気味《きび》だ。 156 |  おれは脳がわるいから、狸の云うことなんか、よく分らないが、蕎麦屋や団子屋へ行って、中学の教師が勤まらなくっちゃ、おれみたような食い心棒《しんぼう》にゃ到底《とうてい》出来っ子ないと思った。それなら、それでいいから、初手から蕎麦と団子の嫌いなものと注文して雇《やと》うがいい。だんまりで辞令を下げておいて、蕎麦を食うな、団子を食うなと罪なお布令《ふれ》を出すのは、おれのような外に道楽のないものにとっては大変な打撃だ。すると赤シャツがまた口を出した。「元来中学の教師なぞは社会の上流にくらいするものだからして、単に物質的の快楽ばかり求めるべきものでない。その方に耽《ふけ》るとつい品性にわるい影響《えいきょう》を及ぼすようになる。しかし人間だから、何か娯楽《ごらく》がないと、田舎《いなか》へ来て狭《せま》い土地では到底|暮《くら》せるものではない。それで釣《つり》に行くとか、文学書を読むとか、または新体詩や俳句を作るとか、何でも高尚《こうしょう》な精神的娯楽を求めなくってはいけない……」 157 |  だまって聞いてると勝手な熱を吹く。沖《おき》へ行って肥料《こやし》を釣ったり、ゴルキが露西亜《ロシア》の文学者だったり、馴染《なじみ》の芸者が松《まつ》の木の下に立ったり、古池へ蛙《かわず》が飛び込んだりするのが精神的娯楽なら、天麩羅を食って団子を呑《の》み込むのも精神的娯楽だ。そんな下さらない娯楽を授けるより赤シャツの洗濯《せんたく》でもするがいい。あんまり腹が立ったから「マドンナに逢《あ》うのも精神的娯楽ですか」と聞いてやった。すると今度は誰も笑わない。妙な顔をして互《たがい》に眼と眼を見合せている。赤シャツ自身は苦しそうに下を向いた。それ見ろ。利いたろう。ただ気の毒だったのはうらなり君で、おれが、こう云ったら蒼い顔をますます蒼くした。 158 | 159 | [#5字下げ]七[#「七」は中見出し] 160 | 161 |  おれは即夜《そくや》下宿を引き払《はら》った。宿へ帰って荷物をまとめていると、女房《にょうぼう》が何か不都合《ふつごう》でもございましたか、お腹の立つ事があるなら、云《い》っておくれたら改めますと云う。どうも驚《おど》ろく。世の中にはどうして、こんな要領を得ない者ばかり揃《そろ》ってるんだろう。出てもらいたいんだか、居てもらいたいんだか分《わか》りゃしない。まるで気狂《きちがい》だ。こんな者を相手に喧嘩《けんか》をしたって江戸《えど》っ子の名折れだから、車屋をつれて来てさっさと出てきた。 162 |  出た事は出たが、どこへ行くというあてもない。車屋が、どちらへ参りますと云うから、だまって尾《つ》いて来い、今にわかる、と云って、すたすたやって来た。面倒《めんどう》だから山城屋へ行こうかとも考えたが、また出なければならないから、つまり手数だ。こうして歩いてるうちには下宿とか、何とか看板のあるうちを目付け出すだろう。そうしたら、そこが天意に叶《かな》ったわが宿と云う事にしよう。とぐるぐる、閑静《かんせい》で住みよさそうな所をあるいているうち、とうとう鍛冶屋町《かじやちょう》へ出てしまった。ここは士族|屋敷《やしき》で下宿屋などのある町ではないから、もっと賑《にぎ》やかな方へ引き返そうかとも思ったが、ふといい事を考え付いた。おれが敬愛するうらなり君はこの町内に住んでいる。うらなり君は土地の人で先祖代々の屋敷を控《ひか》えているくらいだから、この辺の事情には通じているに相違《そうい》ない。あの人を尋《たず》ねて聞いたら、よさそうな下宿を教えてくれるかも知れない。幸《さいわい》一度|挨拶《あいさつ》に来て勝手は知ってるから、捜《さ》がしてあるく面倒はない。ここだろうと、いい加減に見当をつけて、ご免《めん》ご免と二返ばかり云うと、奥《おく》から五十ぐらいな年寄《としより》が古風な紙燭《しそく》をつけて、出て来た。おれは若い女も嫌《きら》いではないが、年寄を見ると何だかなつかしい心持ちがする。大方|清《きよ》がすきだから、その魂《たましい》が方々のお婆《ばあ》さんに乗り移るんだろう。これは大方うらなり君のおっ母《か》さんだろう。切り下げの品格のある婦人だが、よくうらなり君に似ている。まあお上がりと云うところを、ちょっとお目にかかりたいからと、主人を玄関《げんかん》まで呼び出して実はこれこれだが君どこか心当りはありませんかと尋ねてみた。うらなり先生それはさぞお困りでございましょう、としばらく考えていたが、この裏町に萩野《はぎの》と云って老人夫婦ぎりで暮《く》らしているものがある、いつぞや座敷《ざしき》を明けておいても無駄《むだ》だから、たしかな人があるなら貸してもいいから周旋《しゅうせん》してくれと頼《たの》んだ事がある。今でも貸すかどうか分らんが、まあいっしょに行って聞いてみましょうと、親切に連れて行ってくれた。 163 |  その夜から萩野の家の下宿人となった。驚《おどろ》いたのは、おれがいか銀の座敷を引き払うと、翌日《あくるひ》から入れ違《ちが》いに野だが平気な顔をして、おれの居た部屋を占領《せんりょう》した事だ。さすがのおれもこれにはあきれた。世の中はいかさま師ばかりで、お互《たがい》に乗せっこをしているのかも知れない。いやになった。 164 |  世間がこんなものなら、おれも負けない気で、世間並《せけんなみ》にしなくちゃ、遣《や》りきれない訳になる。巾着切《きんちゃくきり》の上前をはねなければ三度のご膳《ぜん》が戴《いただ》けないと、事が極《き》まればこうして、生きてるのも考え物だ。と云ってぴんぴんした達者なからだで、首を縊《くく》っちゃ先祖へ済まない上に、外聞が悪い。考えると物理学校などへはいって、数学なんて役にも立たない芸を覚えるよりも、六百円を資本《もとで》にして牛乳屋でも始めればよかった。そうすれば清もおれの傍《そば》を離《はな》れずに済むし、おれも遠くから婆さんの事を心配しずに暮《くら》される。いっしょに居るうちは、そうでもなかったが、こうして田舎《いなか》へ来てみると清はやっぱり善人だ。あんな気立《きだて》のいい女は日本中さがして歩いたってめったにはない。婆さん、おれの立つときに、少々|風邪《かぜ》を引いていたが今頃《いまごろ》はどうしてるか知らん。先だっての手紙を見たらさぞ喜んだろう。それにしても、もう返事がきそうなものだが——おれはこんな事ばかり考えて二三日暮していた。 165 |  気になるから、宿のお婆さんに、東京から手紙は来ませんかと時々|尋《たず》ねてみるが、聞くたんびに何にも参りませんと気の毒そうな顔をする。ここの夫婦はいか銀とは違って、もとが士族だけに双方《そうほう》共上品だ。爺《じい》さんが夜《よ》るになると、変な声を出して謡《うたい》をうたうには閉口するが、いか銀のようにお茶を入れましょうと無暗《むやみ》に出て来ないから大きに楽だ。お婆さんは時々部屋へ来ていろいろな話をする。どうして奥さんをお連れなさって、いっしょにお出《い》でなんだのぞなもしなどと質問をする。奥さんがあるように見えますかね。可哀想《かわいそう》にこれでもまだ二十四ですぜと云ったらそれでも、あなた二十四で奥さんがおありなさるのは当り前ぞなもしと冒頭《ぼうとう》を置いて、どこの誰《だれ》さんは二十でお嫁《よめ》をお貰《もら》いたの、どこの何とかさんは二十二で子供を二人《ふたり》お持ちたのと、何でも例を半ダースばかり挙げて反駁《はんばく》を試みたには恐《おそ》れ入った。それじゃ僕《ぼく》も二十四でお嫁をお貰いるけれ、世話をしておくれんかなと田舎言葉を真似《まね》て頼んでみたら、お婆さん正直に本当かなもしと聞いた。 166 | 「本当の本当《ほんま》のって僕あ、嫁が貰いたくって仕方がないんだ」 167 | 「そうじゃろうがな、もし。若いうちは誰もそんなものじゃけれ」この挨拶《あいさつ》には痛み入って返事が出来なかった。 168 | 「しかし先生はもう、お嫁がおありなさるに極《きま》っとらい。私はちゃんと、もう、睨《ね》らんどるぞなもし」 169 | 「へえ、活眼《かつがん》だね。どうして、睨らんどるんですか」 170 | 「どうしててて。東京から便りはないか、便りはないかてて、毎日便りを待ち焦《こ》がれておいでるじゃないかなもし」 171 | 「こいつあ驚《おどろ》いた。大変な活眼だ」 172 | 「中《あた》りましたろうがな、もし」 173 | 「そうですね。中ったかも知れませんよ」 174 | 「しかし今時の女子《おなご》は、昔《むかし》と違《ちご》うて油断が出来んけれ、お気をお付けたがええぞなもし」 175 | 「何ですかい、僕の奥さんが東京で間男でもこしらえていますかい」 176 | 「いいえ、あなたの奥さんはたしかじゃけれど……」 177 | 「それで、やっと安心した。それじゃ何を気を付けるんですい」 178 | 「あなたのはたしか——あなたのはたしかじゃが——」 179 | 「どこに不たしかなのが居ますかね」 180 | 「ここ等《ら》にも大分|居《お》ります。先生、あの遠山のお嬢《じょう》さんをご存知かなもし」 181 | 「いいえ、知りませんね」 182 | 「まだご存知ないかなもし。ここらであなた一番の別嬪《べっぴん》さんじゃがなもし。あまり別嬪さんじゃけれ、学校の先生方はみんなマドンナマドンナと言うといでるぞなもし。まだお聞きんのかなもし」 183 | 「うん、マドンナですか。僕あ芸者の名かと思った」 184 | 「いいえ、あなた。マドンナと云うと唐人《とうじん》の言葉で、別嬪さんの事じゃろうがなもし」 185 | 「そうかも知れないね。驚いた」 186 | 「大方画学の先生がお付けた名ぞなもし」 187 | 「野だがつけたんですかい」 188 | 「いいえ、あの吉川《よしかわ》先生がお付けたのじゃがなもし」 189 | 「そのマドンナが不たしかなんですかい」 190 | 「そのマドンナさんが不たしかなマドンナさんでな、もし」 191 | 「厄介《やっかい》だね。渾名《あだな》の付いてる女にゃ昔から碌《ろく》なものは居ませんからね。そうかも知れませんよ」 192 | 「ほん当にそうじゃなもし。鬼神《きじん》のお松《まつ》じゃの、妲妃《だっき》のお百じゃのてて怖《こわ》い女が居《お》りましたなもし」 193 | 「マドンナもその同類なんですかね」 194 | 「そのマドンナさんがなもし、あなた。そらあの、あなたをここへ世話をしておくれた古賀先生なもし——あの方の所へお嫁《よめ》に行く約束《やくそく》が出来ていたのじゃがなもし——」 195 | 「へえ、不思議なもんですね。あのうらなり君が、そんな艶福《えんぷく》のある男とは思わなかった。人は見懸《みか》けによらない者だな。ちっと気を付けよう」 196 | 「ところが、去年あすこのお父さんが、お亡くなりて、——それまではお金もあるし、銀行の株も持ってお出《いで》るし、万事|都合《つごう》がよかったのじゃが——それからというものは、どういうものか急に暮し向きが思わしくなくなって——つまり古賀さんがあまりお人が好過《よす》ぎるけれ、お欺《だま》されたんぞなもし。それや、これやでお輿入《こしいれ》も延びているところへ、あの教頭さんがお出《い》でて、是非お嫁にほしいとお云いるのじゃがなもし」 197 | 「あの赤シャツがですか。ひどい奴《やつ》だ。どうもあのシャツはただのシャツじゃないと思ってた。それから?」 198 | 「人を頼んで懸合《かけお》うておみると、遠山さんでも古賀さんに義理があるから、すぐには返事は出来かねて——まあよう考えてみようぐらいの挨拶をおしたのじゃがなもし。すると赤シャツさんが、手蔓《てづる》を求めて遠山さんの方へ出入《でいり》をおしるようになって、とうとうあなた、お嬢さんを手馴付《てなづ》けておしまいたのじゃがなもし。赤シャツさんも赤シャツさんじゃが、お嬢さんもお嬢さんじゃてて、みんなが悪《わ》るく云いますのよ。いったん古賀さんへ嫁に行くてて承知をしときながら、今さら学士さんがお出《いで》たけれ、その方に替《か》えよてて、それじゃ今日様《こんにちさま》へ済むまいがなもし、あなた」 199 | 「全く済まないね。今日様どころか明日様にも明後日様にも、いつまで行ったって済みっこありませんね」 200 | 「それで古賀さんにお気の毒じゃてて、お友達の堀田《ほった》さんが教頭の所へ意見をしにお行きたら、赤シャツさんが、あしは約束のあるものを横取りするつもりはない。破約になれば貰うかも知れんが、今のところは遠山家とただ交際をしているばかりじゃ、遠山家と交際をするには別段古賀さんに済まん事もなかろうとお云いるけれ、堀田さんも仕方がなしにお戻《もど》りたそうな。赤シャツさんと堀田さんは、それ以来|折合《おりあい》がわるいという評判ぞなもし」 201 | 「よくいろいろな事を知ってますね。どうして、そんな詳《くわ》しい事が分るんですか。感心しちまった」 202 | 「狭《せま》いけれ何でも分りますぞなもし」 203 |  分り過ぎて困るくらいだ。この容子《ようす》じゃおれの天麩羅《てんぷら》や団子《だんご》の事も知ってるかも知れない。厄介《やっかい》な所だ。しかしお蔭様《かげさま》でマドンナの意味もわかるし、山嵐と赤シャツの関係もわかるし大いに後学になった。ただ困るのはどっちが悪る者だか判然しない。おれのような単純なものには白とか黒とか片づけてもらわないと、どっちへ味方をしていいか分らない。 204 | 「赤シャツと山嵐たあ、どっちがいい人ですかね」 205 | 「山嵐て何ぞなもし」 206 | 「山嵐というのは堀田の事ですよ」 207 | 「そりゃ強い事は堀田さんの方が強そうじゃけれど、しかし赤シャツさんは学士さんじゃけれ、働きはある方《かた》ぞな、もし。それから優しい事も赤シャツさんの方が優しいが、生徒の評判は堀田さんの方がええというぞなもし」 208 | 「つまりどっちがいいんですかね」 209 | 「つまり月給の多い方が豪《えら》いのじゃろうがなもし」 210 |  これじゃ聞いたって仕方がないから、やめにした。それから二三日して学校から帰るとお婆さんがにこにこして、へえお待遠さま。やっと参りました。と一本の手紙を持って来てゆっくりご覧と云って出て行った。取り上げてみると清からの便りだ。符箋《ふせん》が二三|枚《まい》ついてるから、よく調べると、山城屋から、いか銀の方へ廻《まわ》して、いか銀から、萩野《はぎの》へ廻って来たのである。その上山城屋では一週間ばかり逗留《とうりゅう》している。宿屋だけに手紙まで泊《とめ》るつもりなんだろう。開いてみると、非常に長いもんだ。坊《ぼ》っちゃんの手紙を頂いてから、すぐ返事をかこうと思ったが、あいにく風邪を引いて一週間ばかり寝《ね》ていたものだから、つい遅《おそ》くなって済まない。その上今時のお嬢さんのように読み書きが達者でないものだから、こんなまずい字でも、かくのによっぽど骨が折れる。甥《おい》に代筆を頼もうと思ったが、せっかくあげるのに自分でかかなくっちゃ、坊っちゃんに済まないと思って、わざわざ下《し》たがきを一返して、それから清書をした。清書をするには二日で済んだが、下た書きをするには四日かかった。読みにくいかも知れないが、これでも一生懸命《いっしょうけんめい》にかいたのだから、どうぞしまいまで読んでくれ。という冒頭《ぼうとう》で四尺ばかり何やらかやら認《したた》めてある。なるほど読みにくい。字がまずいばかりではない、大抵《たいてい》平仮名だから、どこで切れて、どこで始まるのだか句読《くとう》をつけるのによっぽど骨が折れる。おれは焦《せ》っ勝《か》ちな性分だから、こんな長くて、分りにくい手紙は、五円やるから読んでくれと頼まれても断わるのだが、この時ばかりは真面目《まじめ》になって、始《はじめ》から終《しまい》まで読み通した。読み通した事は事実だが、読む方に骨が折れて、意味がつながらないから、また頭から読み直してみた。部屋のなかは少し暗くなって、前の時より見にくく、なったから、とうとう椽鼻《えんばな》へ出て腰《こし》をかけながら鄭寧《ていねい》に拝見した。すると初秋《はつあき》の風が芭蕉《ばしょう》の葉を動かして、素肌《すはだ》に吹《ふ》きつけた帰りに、読みかけた手紙を庭の方へなびかしたから、しまいぎわには四尺あまりの半切れがさらりさらりと鳴って、手を放すと、向《むこ》うの生垣まで飛んで行きそうだ。おれはそんな事には構っていられない。坊っちゃんは竹を割ったような気性だが、ただ肝癪《かんしゃく》が強過ぎてそれが心配になる。——ほかの人に無暗《むやみ》に渾名《あだな》なんか、つけるのは人に恨《うら》まれるもとになるから、やたらに使っちゃいけない、もしつけたら、清だけに手紙で知らせろ。——田舎者は人がわるいそうだから、気をつけてひどい目に遭《あ》わないようにしろ。——気候だって東京より不順に極ってるから、寝冷《ねびえ》をして風邪を引いてはいけない。坊っちゃんの手紙はあまり短過ぎて、容子がよくわからないから、この次にはせめてこの手紙の半分ぐらいの長さのを書いてくれ。——宿屋へ茶代を五円やるのはいいが、あとで困りゃしないか、田舎へ行って頼《たよ》りになるはお金ばかりだから、なるべく倹約《けんやく》して、万一の時に差支《さしつか》えないようにしなくっちゃいけない。——お小遣《こづかい》がなくて困るかも知れないから、為替《かわせ》で十円あげる。——先《せん》だって坊っちゃんからもらった五十円を、坊っちゃんが、東京へ帰って、うちを持つ時の足しにと思って、郵便局へ預けておいたが、この十円を引いてもまだ四十円あるから大丈夫だ。——なるほど女と云うものは細かいものだ。 211 |  おれが椽鼻で清の手紙をひらつかせながら、考え込《こ》んでいると、しきりの襖《ふすま》をあけて、萩野のお婆さんが晩めしを持ってきた。まだ見てお出《い》でるのかなもし。えっぽど長いお手紙じゃなもし、と云ったから、ええ大事な手紙だから風に吹かしては見、吹かしては見るんだと、自分でも要領を得ない返事をして膳《ぜん》についた。見ると今夜も薩摩芋《さつまいも》の煮《に》つけだ。ここのうちは、いか銀よりも鄭寧《ていねい》で、親切で、しかも上品だが、惜《お》しい事に食い物がまずい。昨日も芋、一昨日《おととい》も芋で今夜も芋だ。おれは芋は大好きだと明言したには相違ないが、こう立てつづけに芋を食わされては命がつづかない。うらなり君を笑うどころか、おれ自身が遠からぬうちに、芋のうらなり先生になっちまう。清ならこんな時に、おれの好きな鮪《まぐろ》のさし身か、蒲鉾《かまぼこ》のつけ焼を食わせるんだが、貧乏《びんぼう》士族のけちん坊《ぼう》と来ちゃ仕方がない。どう考えても清といっしょでなくっちあ駄目《だめ》だ。もしあの学校に長くでも居る模様なら、東京から召《よ》び寄《よ》せてやろう。天麩羅|蕎麦《そば》を食っちゃならない、団子を食っちゃならない、それで下宿に居て芋ばかり食って黄色くなっていろなんて、教育者はつらいものだ。禅宗《ぜんしゅう》坊主だって、これよりは口に栄耀《えよう》をさせているだろう。——おれは一皿の芋を平げて、机の抽斗《ひきだし》から生卵を二つ出して、茶碗《ちゃわん》の縁《ふち》でたたき割って、ようやく凌《しの》いだ。生卵ででも営養をとらなくっちあ一週二十一時間の授業が出来るものか。 212 |  今日は清の手紙で湯に行く時間が遅くなった。しかし毎日行きつけたのを一日でも欠かすのは心持ちがわるい。汽車にでも乗って出懸《でか》けようと、例の赤手拭《あかてぬぐい》をぶら下げて停車場《ていしゃば》まで来ると二三分前に発車したばかりで、少々待たなければならぬ。ベンチへ腰を懸けて、敷島《しきしま》を吹かしていると、偶然《ぐうぜん》にもうらなり君がやって来た。おれはさっきの話を聞いてから、うらなり君がなおさら気の毒になった。平常《ふだん》から天地の間に居候《いそうろう》をしているように、小さく構えているのがいかにも憐《あわ》れに見えたが、今夜は憐れどころの騒《さわ》ぎではない。出来るならば月給を倍にして、遠山のお嬢さんと明日《あした》から結婚《けっこん》さして、一ヶ月ばかり東京へでも遊びにやってやりたい気がした矢先だから、やお湯ですか、さあ、こっちへお懸けなさいと威勢《いせい》よく席を譲《ゆず》ると、うらなり君は恐《おそ》れ入った体裁で、いえ構《かも》うておくれなさるな、と遠慮《えんりょ》だか何だかやっぱり立ってる。少し待たなくっちゃ出ません、草臥《くたび》れますからお懸けなさいとまた勧めてみた。実はどうかして、そばへ懸けてもらいたかったくらいに気の毒でたまらない。それではお邪魔《じゃま》を致《いた》しましょうとようやくおれの云う事を聞いてくれた。世の中には野だみたように生意気な、出ないで済む所へ必ず顔を出す奴もいる。山嵐のようにおれが居なくっちゃ日本《にっぽん》が困るだろうと云うような面を肩《かた》の上へ載《の》せてる奴もいる。そうかと思うと、赤シャツのようにコスメチックと色男の問屋をもって自ら任じているのもある。教育が生きてフロックコートを着ればおれになるんだと云わぬばかりの狸《たぬき》もいる。皆々《みなみな》それ相応に威張ってるんだが、このうらなり先生のように在れどもなきがごとく、人質に取られた人形のように大人《おとな》しくしているのは見た事がない。顔はふくれているが、こんな結構な男を捨てて赤シャツに靡《なび》くなんて、マドンナもよっぼど気の知れないおきゃんだ。赤シャツが何ダース寄ったって、これほど立派な旦那様《だんなさま》が出来るもんか。 213 | 「あなたはどっか悪いんじゃありませんか。大分たいぎそうに見えますが……」「いえ、別段これという持病もないですが……」 214 | 「そりゃ結構です。からだが悪いと人間も駄目ですね」 215 | 「あなたは大分ご丈夫《じょうぶ》のようですな」 216 | 「ええ瘠《や》せても病気はしません。病気なんてものあ大嫌いですから」 217 |  うらなり君は、おれの言葉を聞いてにやにやと笑った。 218 |  ところへ入口で若々しい女の笑声が聞《きこ》えたから、何心なく振《ふ》り返ってみるとえらい奴が来た。色の白い、ハイカラ頭の、背の高い美人と、四十五六の奥さんとが並《なら》んで切符《きっぷ》を売る窓の前に立っている。おれは美人の形容などが出来る男でないから何にも云えないが全く美人に相違ない。何だか水晶《すいしょう》の珠《たま》を香水《こうすい》で暖《あっ》ためて、掌《てのひら》へ握《にぎ》ってみたような心持ちがした。年寄の方が背は低い。しかし顔はよく似ているから親子だろう。おれは、や、来たなと思う途端《とたん》に、うらなり君の事は全然《すっかり》忘れて、若い女の方ばかり見ていた。すると、うらなり君が突然《とつぜん》おれの隣《となり》から、立ち上がって、そろそろ女の方へ歩き出したんで、少し驚いた。マドンナじゃないかと思った。三人は切符所の前で軽く挨拶している。遠いから何を云ってるのか分らない。 219 |  停車場の時計を見るともう五分で発車だ。早く汽車がくればいいがなと、話し相手が居なくなったので待ち遠しく思っていると、また一人あわてて場内へ馳《か》け込《こ》んで来たものがある。見れば赤シャツだ。何だかべらべら然たる着物へ縮緬《ちりめん》の帯をだらしなく巻き付けて、例の通り金鎖《きんぐさ》りをぶらつかしている。あの金鎖りは贋物《にせもの》である。赤シャツは誰《だれ》も知るまいと思って、見せびらかしているが、おれはちゃんと知ってる。赤シャツは馳け込んだなり、何かきょろきょろしていたが、切符|売下所《うりさげじょ》の前に話している三人へ慇懃《いんぎん》にお辞儀《じぎ》をして、何か二こと、三こと、云ったと思ったら、急にこっちへ向いて、例のごとく猫足《ねこあし》にあるいて来て、や君も湯ですか、僕は乗り後れやしないかと思って心配して急いで来たら、まだ三四分ある。あの時計はたしかかしらんと、自分の金側《きんがわ》を出して、二分ほどちがってると云いながら、おれの傍《そば》へ腰を卸《おろ》した。女の方はちっとも見返らないで杖《つえ》の上に顋《あご》をのせて、正面ばかり眺《なが》めている。年寄の婦人は時々赤シャツを見るが、若い方は横を向いたままである。いよいよマドンナに違いない。 220 |  やがて、ピューと汽笛《きてき》が鳴って、車がつく。待ち合せた連中はぞろぞろ吾《わ》れ勝《がち》に乗り込む。赤シャツはいの一号に上等へ飛び込んだ。上等へ乗ったって威張れるどころではない、住田《すみた》まで上等が五銭で下等が三銭だから、わずか二銭違いで上下の区別がつく。こういうおれでさえ上等を奮発《ふんぱつ》して白切符を握《にぎ》ってるんでもわかる。もっとも田舎者はけちだから、たった二銭の出入でもすこぶる苦になると見えて、大抵《たいてい》は下等へ乗る。赤シャツのあとからマドンナとマドンナのお袋が上等へはいり込んだ。うらなり君は活版で押《お》したように下等ばかりへ乗る男だ。先生、下等の車室の入口へ立って、何だか躊躇《ちゅうちょ》の体《てい》であったが、おれの顔を見るや否や思いきって、飛び込んでしまった。おれはこの時何となく気の毒でたまらなかったから、うらなり君のあとから、すぐ同じ車室へ乗り込んだ。上等の切符で下等へ乗るに不都合はなかろう。 221 |  温泉へ着いて、三階から、浴衣《ゆかた》のなりで湯壺《ゆつぼ》へ下りてみたら、またうらなり君に逢った。おれは会議や何かでいざと極まると、咽喉《のど》が塞《ふさ》がって饒舌《しゃべ》れない男だが、平常《ふだん》は随分《ずいぶん》弁ずる方だから、いろいろ湯壺のなかでうらなり君に話しかけてみた。何だか憐れぽくってたまらない。こんな時に一口でも先方の心を慰《なぐさ》めてやるのは、江戸《えど》っ子の義務だと思ってる。ところがあいにくうらなり君の方では、うまい具合にこっちの調子に乗ってくれない。何を云っても、え[#「え」に傍点]とかいえ[#「いえ」に傍点]とかぎりで、しかもそのえ[#「え」に傍点]といえ[#「いえ」に傍点]が大分|面倒《めんどう》らしいので、しまいにはとうとう切り上げて、こっちからご免蒙《めんこうむ》った。 222 |  湯の中では赤シャツに逢わなかった。もっとも風呂《ふろ》の数はたくさんあるのだから、同じ汽車で着いても、同じ湯壺で逢うとは極まっていない。別段不思議にも思わなかった。風呂を出てみるといい月だ。町内の両側に柳《やなぎ》が植《うわ》って、柳の枝《えだ》が丸《ま》るい影を往来の中へ落《おと》している。少し散歩でもしよう。北へ登って町のはずれへ出ると、左に大きな門があって、門の突き当りがお寺で、左右が妓楼《ぎろう》である。山門のなかに遊廓《ゆうかく》があるなんて、前代未聞の現象だ。ちょっとはいってみたいが、また狸から会議の時にやられるかも知れないから、やめて素通りにした。門の並びに黒い暖簾《のれん》をかけた、小さな格子窓《こうしまど》の平屋はおれが団子を食って、しくじった所だ。丸提灯《まるぢょうちん》に汁粉《しるこ》、お雑煮《ぞうに》とかいたのがぶらさがって、提灯の火が、軒端《のきば》に近い一本の柳の幹を照らしている。食いたいなと思ったが我慢して通り過ぎた。 223 |  食いたい団子の食えないのは情ない。しかし自分の許嫁《いいなずけ》が他人に心を移したのは、なお情ないだろう。うらなり君の事を思うと、団子は愚《おろ》か、三日ぐらい断食《だんじき》しても不平はこぼせない訳だ。本当に人間ほどあてにならないものはない。あの顔を見ると、どうしたって、そんな不人情な事をしそうには思えないんだが——うつくしい人が不人情で、冬瓜《とうがん》の水膨《みずぶく》れのような古賀さんが善良な君子なのだから、油断が出来ない。淡泊《たんぱく》だと思った山嵐は生徒を煽動《せんどう》したと云うし。生徒を煽動したのかと思うと、生徒の処分を校長に逼《せま》るし。厭味《いやみ》で練りかためたような赤シャツが存外親切で、おれに余所《よそ》ながら注意をしてくれるかと思うと、マドンナを胡魔化《ごまか》したり、胡魔化したのかと思うと、古賀の方が破談にならなければ結婚は望まないんだと云うし。いか銀が難癖《なんくせ》をつけて、おれを追い出すかと思うと、すぐ野だ公が入《い》れ替《かわ》ったり——どう考えてもあてにならない。こんな事を清にかいてやったら定めて驚く事だろう。箱根《はこね》の向うだから化物《ばけもの》が寄り合ってるんだと云うかも知れない。 224 |  おれは、性来《しょうらい》構わない性分だから、どんな事でも苦にしないで今日まで凌いで来たのだが、ここへ来てからまだ一ヶ月立つか、立たないうちに、急に世のなかを物騒《ぶっそう》に思い出した。別段際だった大事件にも出逢わないのに、もう五つ六つ年を取ったような気がする。早く切り上げて東京へ帰るのが一番よかろう。などとそれからそれへ考えて、いつか石橋を渡《わた》って野芹川《のぜりがわ》の堤《どて》へ出た。川と云うとえらそうだが実は一間ぐらいな、ちょろちょろした流れで、土手に沿うて十二丁ほど下ると相生村《あいおいむら》へ出る。村には観音様《かんのんさま》がある。 225 |  温泉《ゆ》の町を振り返ると、赤い灯が、月の光の中にかがやいている。太鼓《たいこ》が鳴るのは遊廓に相違ない。川の流れは浅いけれども早いから、神経質の水のようにやたらに光る。ぶらぶら土手の上をあるきながら、約三丁も来たと思ったら、向うに人影《ひとかげ》が見え出した。月に透《す》かしてみると影は二つある。温泉《ゆ》へ来て村へ帰る若い衆《しゅ》かも知れない。それにしては唄《うた》もうたわない。存外静かだ。 226 |  だんだん歩いて行くと、おれの方が早足だと見えて、二つの影法師が、次第に大きくなる。一人は女らしい。おれの足音を聞きつけて、十間ぐらいの距離《きょり》に逼った時、男がたちまち振り向いた。月は後《うしろ》からさしている。その時おれは男の様子を見て、はてなと思った。男と女はまた元の通りにあるき出した。おれは考えがあるから、急に全速力で追っ懸《か》けた。先方は何の気もつかずに最初の通り、ゆるゆる歩を移している。今は話し声も手に取るように聞える。土手の幅は六尺ぐらいだから、並んで行けば三人がようやくだ。おれは苦もなく後ろから追い付いて、男の袖《そで》を擦《す》り抜《ぬ》けざま、二足前へ出した踵《くびす》をぐるりと返して男の顔を覗《のぞ》き込《こ》んだ。月は正面からおれの五分|刈《がり》の頭から顋の辺《あた》りまで、会釈《えしゃく》もなく照《てら》す。男はあっと小声に云ったが、急に横を向いて、もう帰ろうと女を促《うな》がすが早いか、温泉《ゆ》の町の方へ引き返した。 227 |  赤シャツは図太くて胡魔化すつもりか、気が弱くて名乗り損《そく》なったのかしら。ところが狭くて困ってるのは、おればかりではなかった。 228 | 229 | [#5字下げ]八[#「八」は中見出し] 230 | 231 |  赤シャツに勧められて釣《つり》に行った帰りから、山嵐《やまあらし》を疑ぐり出した。無い事を種に下宿を出ろと云われた時は、いよいよ不埒《ふらち》な奴《やつ》だと思った。ところが会議の席では案に相違《そうい》して滔々《とうとう》と生徒|厳罰論《げんばつろん》を述べたから、おや変だなと首を捩《ひね》った。萩野《はぎの》の婆《ばあ》さんから、山嵐が、うらなり君のために赤シャツと談判をしたと聞いた時は、それは感心だと手を拍《う》った。この様子ではわる者は山嵐じゃあるまい、赤シャツの方が曲ってるんで、好加減《いいかげん》な邪推《じゃすい》を実《まこと》しやかに、しかも遠廻《とおまわ》しに、おれの頭の中へ浸《し》み込《こ》ましたのではあるまいかと迷ってる矢先へ、野芹川《のぜりがわ》の土手で、マドンナを連れて散歩なんかしている姿を見たから、それ以来赤シャツは曲者《くせもの》だと極《き》めてしまった。曲者だか何だかよくは分《わか》らないが、ともかくも善《い》い男じゃない。表と裏とは違《ちが》った男だ。人間は竹のように真直《まっすぐ》でなくっちゃ頼《たの》もしくない。真直なものは喧嘩《けんか》をしても心持ちがいい。赤シャツのようなやさしいのと、親切なのと、高尚《こうしょう》なのと、琥珀《こはく》のパイプとを自慢《じまん》そうに見せびらかすのは油断が出来ない、めったに喧嘩も出来ないと思った。喧嘩をしても、回向院《えこういん》の相撲《すもう》のような心持ちのいい喧嘩は出来ないと思った。そうなると一銭五厘の出入《でいり》で控所《ひかえじょ》全体を驚《おど》ろかした議論の相手の山嵐の方がはるかに人間らしい。会議の時に金壺眼《かなつぼまなこ》をぐりつかせて、おれを睨《にら》めた時は憎《にく》い奴だと思ったが、あとで考えると、それも赤シャツのねちねちした猫撫声《ねこなでごえ》よりはましだ。実はあの会議が済んだあとで、よっぽど仲直りをしようかと思って、一こと二こと話しかけてみたが、野郎《やろう》返事もしないで、まだ眼《め》を剥《むく》ってみせたから、こっちも腹が立ってそのままにしておいた。 232 |  それ以来山嵐はおれと口を利かない。机の上へ返した一銭五厘はいまだに机の上に乗っている。ほこりだらけになって乗っている。おれは無論手が出せない、山嵐は決して持って帰らない。この一銭五厘が二人の間の墻壁《しょうへき》になって、おれは話そうと思っても話せない、山嵐は頑《がん》として黙《だま》ってる。おれと山嵐には一銭五厘が祟《たた》った。しまいには学校へ出て一銭五厘を見るのが苦になった。 233 |  山嵐とおれが絶交の姿となったに引き易《か》えて、赤シャツとおれは依然《いぜん》として在来の関係を保って、交際をつづけている。野芹川で逢《あ》った翌日などは、学校へ出ると第一番におれの傍《そば》へ来て、君今度の下宿はいいですかのまたいっしょに露西亜《ロシア》文学を釣《つ》りに行こうじゃないかのといろいろな事を話しかけた。おれは少々|憎《にく》らしかったから、昨夜《ゆうべ》は二返逢いましたねと云《い》ったら、ええ停車場《ていしゃば》で——君はいつでもあの時分|出掛《でか》けるのですか、遅いじゃないかと云う。野芹川の土手でもお目に懸《かか》りましたねと喰《く》らわしてやったら、いいえ僕《ぼく》はあっちへは行かない、湯にはいって、すぐ帰ったと答えた。何もそんなに隠《かく》さないでもよかろう、現に逢ってるんだ。よく嘘《うそ》をつく男だ。これで中学の教頭が勤まるなら、おれなんか大学総長がつとまる。おれはこの時からいよいよ赤シャツを信用しなくなった。信用しない赤シャツとは口をきいて、感心している山嵐とは話をしない。世の中は随分妙《ずいぶんみょう》なものだ。 234 |  ある日の事赤シャツがちょっと君に話があるから、僕のうちまで来てくれと云うから、惜《お》しいと思ったが温泉行きを欠勤して四時|頃《ごろ》出掛けて行った。赤シャツは一人ものだが、教頭だけに下宿はとくの昔《むかし》に引き払《はら》って立派な玄関《げんかん》を構えている。家賃は九円五|拾銭《じっせん》だそうだ。田舎《いなか》へ来て九円五拾銭払えばこんな家へはいれるなら、おれも一つ奮発《ふんぱつ》して、東京から清を呼び寄せて喜ばしてやろうと思ったくらいな玄関だ。頼むと云ったら、赤シャツの弟が取次《とりつぎ》に出て来た。この弟は学校で、おれに代数と算術を教わる至って出来のわるい子だ。その癖渡《くせわた》りものだから、生れ付いての田舎者よりも人が悪《わ》るい。 235 |  赤シャツに逢って用事を聞いてみると、大将例の琥珀のパイプで、きな臭《くさ》い烟草《たばこ》をふかしながら、こんな事を云った。「君が来てくれてから、前任者の時代よりも成績《せいせき》がよくあがって、校長も大いにいい人を得たと喜んでいるので——どうか学校でも信頼《しんらい》しているのだから、そのつもりで勉強していただきたい」 236 | 「へえ、そうですか、勉強って今より勉強は出来ませんが——」 237 | 「今のくらいで充分《じゅうぶん》です。ただ先だってお話しした事ですね、あれを忘れずにいて下さればいいのです」 238 | 「下宿の世話なんかするものあ剣呑《けんのん》だという事ですか」 239 | 「そう露骨《ろこつ》に云うと、意味もない事になるが——まあ善いさ——精神は君にもよく通じている事と思うから。そこで君が今のように出精《しゅっせい》して下されば、学校の方でも、ちゃんと見ているんだから、もう少しして都合《つごう》さえつけば、待遇《たいぐう》の事も多少はどうにかなるだろうと思うんですがね」 240 | 「へえ、俸給《ほうきゅう》ですか。俸給なんかどうでもいいんですが、上がれば上がった方がいいですね」 241 | 「それで幸い今度転任者が一人出来るから——もっとも校長に相談してみないと無論受け合えない事だが——その俸給から少しは融通《ゆうずう》が出来るかも知れないから、それで都合をつけるように校長に話してみようと思うんですがね」 242 | 「どうも難有《ありがと》う。だれが転任するんですか」 243 | 「もう発表になるから話しても差し支《つか》えないでしょう。実は古賀君です」 244 | 「古賀さんは、だってここの人じゃありませんか」 245 | 「ここの地《じ》の人ですが、少し都合があって——半分は当人の希望です」 246 | 「どこへ行《ゆ》くんです」 247 | 「日向《ひゅうが》の延岡《のべおか》で——土地が土地だから一級俸|上《あが》って行く事になりました」 248 | 「誰《だれ》か代りが来るんですか」 249 | 「代りも大抵《たいてい》極まってるんです。その代りの具合で君の待遇上の都合もつくんです」 250 | 「はあ、結構です。しかし無理に上がらないでも構いません」 251 | 「とも角も僕は校長に話すつもりです。それで校長も同意見らしいが、追っては君にもっと働いて頂《いた》だかなくってはならんようになるかも知れないから、どうか今からそのつもりで覚悟《かくご》をしてやってもらいたいですね」 252 | 「今より時間でも増すんですか」 253 | 「いいえ、時間は今より減るかも知れませんが——」 254 | 「時間が減って、もっと働くんですか、妙だな」 255 | 「ちょっと聞くと妙だが、——判然とは今言いにくいが——まあつまり、君にもっと重大な責任を持ってもらうかも知れないという意味なんです」 256 |  おれには一向分らない。今より重大な責任と云えば、数学の主任だろうが、主任は山嵐だから、やっこさんなかなか辞職する気遣《きづか》いはない。それに、生徒の人望があるから転任や免職《めんしょく》は学校の得策であるまい。赤シャツの談話はいつでも要領を得ない。要領を得なくっても用事はこれで済んだ。それから少し雑談をしているうちに、うらなり君の送別会をやる事や、ついてはおれが酒を飲むかと云う問や、うらなり先生は君子で愛すべき人だと云う事や——赤シャツはいろいろ弁じた。しまいに話をかえて君俳句をやりますかと来たから、こいつは大変だと思って、俳句はやりません、さようならと、そこそこに帰って来た。発句《ほっく》は芭蕉《ばしょう》か髪結床《かみいどこ》の親方のやるもんだ。数学の先生が朝顔やに釣瓶《つるべ》をとられてたまるものか。 257 |  帰ってうんと考え込んだ。世間には随分気の知れない男が居る。家屋敷はもちろん、勤める学校に不足のない故郷がいやになったからと云って、知らぬ他国へ苦労を求めに出る。それも花の都の電車が通《かよ》ってる所なら、まだしもだが、日向の延岡とは何の事だ。おれは船つきのいいここへ来てさえ、一ヶ月立たないうちにもう帰りたくなった。延岡と云えば山の中も山の中も大変な山の中だ。赤シャツの云うところによると船から上がって、一日《いちんち》馬車へ乗って、宮崎へ行って、宮崎からまた一日《いちんち》車へ乗らなくっては着けないそうだ。名前を聞いてさえ、開けた所とは思えない。猿《さる》と人とが半々に住んでるような気がする。いかに聖人のうらなり君だって、好んで猿の相手になりたくもないだろうに、何という物数奇《ものずき》だ。 258 |  ところへあいかわらず婆《ばあ》さんが夕食《ゆうめし》を運んで出る。今日もまた芋《いも》ですかいと聞いてみたら、いえ今日はお豆腐《とうふ》ぞなもしと云った。どっちにしたって似たものだ。 259 | 「お婆さん古賀さんは日向へ行くそうですね」 260 | 「ほん当にお気の毒じゃな、もし」 261 | 「お気の毒だって、好んで行くんなら仕方がないですね」 262 | 「好んで行くて、誰がぞなもし」 263 | 「誰がぞなもしって、当人がさ。古賀先生が物数奇に行くんじゃありませんか」 264 | 「そりゃあなた、大違いの勘五郎《かんごろう》ぞなもし」 265 | 「勘五郎かね。だって今赤シャツがそう云いましたぜ。それが勘五郎なら赤シャツは嘘つきの法螺右衛門《ほらえもん》だ」 266 | 「教頭さんが、そうお云いるのはもっともじゃが、古賀さんのお往《い》きともないのももっともぞなもし」 267 | 「そんなら両方もっともなんですね。お婆さんは公平でいい。一体どういう訳なんですい」 268 | 「今朝古賀のお母さんが見えて、だんだん訳をお話したがなもし」 269 | 「どんな訳をお話したんです」 270 | 「あそこもお父さんがお亡くなりてから、あたし達が思うほど暮《くら》し向《むき》が豊かになうてお困りじゃけれ、お母さんが校長さんにお頼みて、もう四年も勤めているものじゃけれ、どうぞ毎月頂くものを、今少しふやしておくれんかてて、あなた」 271 | 「なるほど」 272 | 「校長さんが、ようまあ考えてみとこうとお云いたげな。それでお母さんも安心して、今に増給のご沙汰《さた》があろぞ、今月か来月かと首を長くして待っておいでたところへ、校長さんがちょっと来てくれと古賀さんにお云いるけれ、行ってみると、気の毒だが学校は金が足りんけれ、月給を上げる訳にゆかん。しかし延岡になら空いた口があって、そっちなら毎月五円余分にとれるから、お望み通りでよかろうと思うて、その手続きにしたから行くがええと云われたげな。——」 273 | 「じゃ相談じゃない、命令じゃありませんか」 274 | 「さよよ。古賀さんはよそへ行って月給が増すより、元のままでもええから、ここに居《お》りたい。屋敷もあるし、母もあるからとお頼みたけれども、もうそう極めたあとで、古賀さんの代りは出来ているけれ仕方がないと校長がお云いたげな」 275 | 「へん人を馬鹿《ばか》にしてら、面白《おもしろ》くもない。じゃ古賀さんは行く気はないんですね。どうれで変だと思った。五円ぐらい上がったって、あんな山の中へ猿のお相手をしに行く唐変木《とうへんぼく》はまずないからね」 276 | 「唐変木て、先生なんぞなもし」 277 | 「何でもいいでさあ、——全く赤シャツの作略《さりゃく》だね。よくない仕打《しうち》だ。まるで欺撃《だましうち》ですね。それでおれの月給を上げるなんて、不都合《ふつごう》な事があるものか。上げてやるったって、誰が上がってやるものか」 278 | 「先生は月給がお上りるのかなもし」 279 | 「上げてやるって云うから、断《こと》わろうと思うんです」 280 | 「何で、お断わりるのぞなもし」 281 | 「何でもお断わりだ。お婆さん、あの赤シャツは馬鹿ですぜ。卑怯《ひきょう》でさあ」 282 | 「卑怯でもあんた、月給を上げておくれたら、大人《おとな》しく頂いておく方が得ぞなもし。若いうちはよく腹の立つものじゃが、年をとってから考えると、も少しの我慢《がまん》じゃあったのに惜しい事をした。腹立てたためにこないな損をしたと悔《くや》むのが当り前じゃけれ、お婆の言う事をきいて、赤シャツさんが月給をあげてやろとお言いたら、難有《ありがと》うと受けておおきなさいや」 283 | 「年寄《としより》の癖に余計な世話を焼かなくってもいい。おれの月給は上がろうと下がろうとおれの月給だ」 284 |  婆さんはだまって引き込んだ。爺《じい》さんは呑気《のんき》な声を出して謡《うたい》をうたってる。謡というものは読んでわかる所を、やにむずかしい節をつけて、わざと分らなくする術だろう。あんな者を毎晩|飽《あ》きずに唸《うな》る爺さんの気が知れない。おれは謡どころの騒《さわ》ぎじゃない。月給を上げてやろうと云うから、別段欲しくもなかったが、入らない金を余しておくのももったいないと思って、よろしいと承知したのだが、転任したくないものを無理に転任させてその男の月給の上前を跳《は》ねるなんて不人情な事が出来るものか。当人がもとの通りでいいと云うのに延岡|下《くんだ》りまで落ちさせるとは一体どう云う了見《りょうけん》だろう。太宰権帥《だざいごんのそつ》でさえ博多《はかた》近辺で落ちついたものだ。河合又五郎《かあいまたごろう》だって相良《さがら》でとまってるじゃないか。とにかく赤シャツの所へ行って断わって来なくっちあ気が済まない。 285 |  小倉《こくら》の袴《はかま》をつけてまた出掛けた。大きな玄関へ突《つ》っ立って頼むと云うと、また例の弟が取次に出て来た。おれの顔を見てまた来たかという眼付《めつき》をした。用があれば二度だって三度だって来る。よる夜なかだって叩《たた》き起《おこ》さないとは限らない。教頭の所へご機嫌伺《きげんうかが》いにくるようなおれと見損《みそくな》ってるか。これでも月給が入らないから返しに来《きた》んだ。すると弟が今来客中だと云うから、玄関でいいからちょっとお目にかかりたいと云ったら奥《おく》へ引き込んだ。足元を見ると、畳付《たたみつ》きの薄っぺらな、のめりの駒下駄《こまげた》がある。奥でもう万歳《ばんざい》ですよと云う声が聞《きこ》える。お客とは野だだなと気がついた。野だでなくては、あんな黄色い声を出して、こんな芸人じみた下駄を穿《は》くものはない。 286 |  しばらくすると、赤シャツがランプを持って玄関まで出て来て、まあ上がりたまえ、外の人じゃない吉川君だ、と云うから、いえここでたくさんです。ちょっと話せばいいんです、と云って、赤シャツの顔を見ると金時のようだ。野だ公と一杯《いっぱい》飲んでると見える。 287 | 「さっき僕の月給を上げてやるというお話でしたが、少し考えが変ったから断わりに来たんです」 288 |  赤シャツはランプを前へ出して、奥の方からおれの顔を眺《なが》めたが、とっさの場合返事をしかねて茫然《ぼうぜん》としている。増給を断わる奴が世の中にたった一人飛び出して来たのを不審《ふしん》に思ったのか、断わるにしても、今帰ったばかりで、すぐ出直してこなくってもよさそうなものだと、呆《あき》れ返ったのか、または双方合併《そうほうがっぺい》したのか、妙な口をして突っ立ったままである。 289 | 「あの時承知したのは、古賀君が自分の希望で転任するという話でしたからで……」 290 | 「古賀君は全く自分の希望で半ば転任するんです」 291 | 「そうじゃないんです、ここに居たいんです。元の月給でもいいから、郷里に居たいのです」 292 | 「君は古賀君から、そう聞いたのですか」 293 | 「そりゃ当人から、聞いたんじゃありません」 294 | 「じゃ誰からお聞きです」 295 | 「僕の下宿の婆さんが、古賀さんのおっ母《か》さんから聞いたのを今日僕に話したのです」 296 | 「じゃ、下宿の婆さんがそう云ったのですね」 297 | 「まあそうです」 298 | 「それは失礼ながら少し違うでしょう。あなたのおっしゃる通りだと、下宿屋の婆さんの云う事は信ずるが、教頭の云う事は信じないと云うように聞えるが、そういう意味に解釈して差支《さしつか》えないでしょうか」 299 |  おれはちょっと困った。文学士なんてものはやっぱりえらいものだ。妙な所へこだわって、ねちねち押《お》し寄せてくる。おれはよく親父《おやじ》から貴様はそそっかしくて駄目《だめ》だ駄目だと云われたが、なるほど少々そそっかしいようだ。婆さんの話を聞いてはっと思って飛び出して来たが、実はうらなり君にもうらなりのおっ母さんにも逢って詳《くわ》しい事情は聞いてみなかったのだ。だからこう文学士流に斬《き》り付けられると、ちょっと受け留めにくい。 300 |  正面からは受け留めにくいが、おれはもう赤シャツに対して不信任を心の中《うち》で申し渡してしまった。下宿の婆さんもけちん坊《ぼう》の欲張り屋に相違ないが、嘘は吐《つ》かない女だ、赤シャツのように裏表はない。おれは仕方がないから、こう答えた。 301 | 「あなたの云う事は本当かも知れないですが——とにかく増給はご免蒙《めんこうむ》ります」 302 | 「それはますます可笑《おか》しい。今君がわざわざお出《いで》になったのは増俸を受けるには忍《しの》びない、理由を見出したからのように聞えたが、その理由が僕の説明で取り去られたにもかかわらず増俸を否まれるのは少し解しかねるようですね」 303 | 「解しかねるかも知れませんがね。とにかく断わりますよ」 304 | 「そんなに否《いや》なら強いてとまでは云いませんが、そう二三時間のうちに、特別の理由もないのに豹変《ひょうへん》しちゃ、将来君の信用にかかわる」 305 | 「かかわっても構わないです」 306 | 「そんな事はないはずです、人間に信用ほど大切なものはありませんよ。よしんば今一歩|譲《ゆず》って、下宿の主人が……」 307 | 「主人じゃない、婆さんです」 308 | 「どちらでもよろしい。下宿の婆さんが君に話した事を事実としたところで、君の増給は古賀君の所得を削《けず》って得たものではないでしょう。古賀君は延岡へ行かれる。その代りがくる。その代りが古賀君よりも多少低給で来てくれる。その剰余《じょうよ》を君に廻《ま》わすと云うのだから、君は誰にも気の毒がる必要はないはずです。古賀君は延岡でただ今よりも栄進される。新任者は最初からの約束《やくそく》で安くくる。それで君が上がられれば、これほど都合《つごう》のいい事はないと思うですがね。いやなら否《いや》でもいいが、もう一返うちでよく考えてみませんか」 309 |  おれの頭はあまりえらくないのだから、いつもなら、相手がこういう巧妙《こうみょう》な弁舌を揮《ふる》えば、おやそうかな、それじゃ、おれが間違ってたと恐《おそ》れ入って引きさがるのだけれども、今夜はそうは行かない。ここへ来た最初から赤シャツは何だか虫が好かなかった。途中《とちゅう》で親切な女みたような男だと思い返した事はあるが、それが親切でも何でもなさそうなので、反動の結果今じゃよっぽど厭《いや》になっている。だから先がどれほどうまく論理的に弁論を逞《たくまし》くしようとも、堂々たる教頭流におれを遣り込めようとも、そんな事は構わない。議論のいい人が善人とはきまらない。遣り込められる方が悪人とは限らない。表向きは赤シャツの方が重々もっともだが、表向きがいくら立派だって、腹の中まで惚《ほ》れさせる訳には行かない。金や威力《いりょく》や理屈《りくつ》で人間の心が買える者なら、高利貸でも巡査《じゅんさ》でも大学教授でも一番人に好かれなくてはならない。中学の教頭ぐらいな論法でおれの心がどう動くものか。人間は好き嫌いで働くものだ。論法で働くものじゃない。 310 | 「あなたの云う事はもっともですが、僕は増給がいやになったんですから、まあ断わります。考えたって同じ事です。さようなら」と云いすてて門を出た。頭の上には天の川が一筋かかっている。 311 | 312 | [#5字下げ]九[#「九」は中見出し] 313 | 314 |  うらなり君の送別会のあるという日の朝、学校へ出たら、山嵐《やまあらし》が突然《とつぜん》、君先だってはいか銀が来て、君が乱暴して困るから、どうか出るように話してくれと頼《たの》んだから、真面目《まじめ》に受けて、君に出てやれと話したのだが、あとから聞いてみると、あいつは悪《わ》るい奴《やつ》で、よく偽筆《ぎひつ》へ贋落款《にせらっかん》などを押《お》して売りつけるそうだから、全く君の事も出鱈目《でたらめ》に違《ちが》いない。君に懸物《かけもの》や骨董《こっとう》を売りつけて、商売にしようと思ってたところが、君が取り合わないで儲《もう》けがないものだから、あんな作りごとをこしらえて胡魔化《ごまか》したのだ。僕はあの人物を知らなかったので君に大変失敬した勘弁《かんべん》したまえと長々しい謝罪をした。 315 |  おれは何とも云わずに、山嵐の机の上にあった、一銭五|厘《りん》をとって、おれの蝦蟇口《がまぐち》のなかへ入れた。山嵐は君それを引き込《こ》めるのかと不審《ふしん》そうに聞くから、うんおれは君に奢《おご》られるのが、いやだったから、是非返すつもりでいたが、その後だんだん考えてみると、やっぱり奢ってもらう方がいいようだから、引き込ますんだと説明した。山嵐は大きな声をしてアハハハと笑いながら、そんなら、なぜ早く取らなかったのだと聞いた。実は取ろう取ろうと思ってたが、何だか妙《みょう》だからそのままにしておいた。近来は学校へ来て一銭五厘を見るのが苦になるくらいいやだったと云ったら、君はよっぽど負け惜《お》しみの強い男だと云うから、君はよっぽど剛情張《ごうじょうっぱ》りだと答えてやった。それから二人の間にこんな問答が起《おこ》った。 316 | 「君は一体どこの産だ」 317 | 「おれは江戸《えど》っ子だ」 318 | 「うん、江戸っ子か、道理で負け惜しみが強いと思った」 319 | 「きみはどこだ」 320 | 「僕は会津《あいづ》だ」 321 | 「会津っぽか、強情な訳だ。今日の送別会へ行くのかい」 322 | 「行くとも、君は?」 323 | 「おれは無論行くんだ。古賀さんが立つ時は、浜《はま》まで見送りに行こうと思ってるくらいだ」 324 | 「送別会は面白いぜ、出て見たまえ。今日は大いに飲むつもりだ」 325 | 「勝手に飲むがいい。おれは肴《さかな》を食ったら、すぐ帰る。酒なんか飲む奴は馬鹿《ばか》だ」 326 | 「君はすぐ喧嘩《けんか》を吹《ふ》き懸《か》ける男だ。なるほど江戸っ子の軽跳《けいちょう》な風を、よく、あらわしてる」 327 | 「何でもいい、送別会へ行く前にちょっとおれのうちへお寄り、話《はな》しがあるから」 328 | 329 |  山嵐は約束《やくそく》通りおれの下宿へ寄った。おれはこの間から、うらなり君の顔を見る度に気の毒でたまらなかったが、いよいよ送別の今日となったら、何だか憐《あわ》れっぽくって、出来る事なら、おれが代りに行ってやりたい様な気がしだした。それで送別会の席上で、大いに演説でもしてその行を盛《さかん》にしてやりたいと思うのだが、おれのべらんめえ調子じゃ、到底《とうてい》物にならないから、大きな声を出す山嵐を雇《やと》って、一番赤シャツの荒肝《あらぎも》を挫《ひし》いでやろうと考え付いたから、わざわざ山嵐を呼んだのである。 330 |  おれはまず冒頭《ぼうとう》としてマドンナ事件から説き出したが、山嵐は無論マドンナ事件はおれより詳《くわ》しく知っている。おれが野芹川《のぜりがわ》の土手の話をして、あれは馬鹿野郎《ばかやろう》だと云ったら、山嵐は君はだれを捕《つら》まえても馬鹿|呼《よば》わりをする。今日学校で自分の事を馬鹿と云ったじゃないか。自分が馬鹿なら、赤シャツは馬鹿じゃない。自分は赤シャツの同類じゃないと主張した。それじゃ赤シャツは腑抜《ふぬ》けの呆助《ほうすけ》だと云ったら、そうかもしれないと山嵐は大いに賛成した。山嵐は強い事は強いが、こんな言葉になると、おれより遥《はる》かに字を知っていない。会津っぽなんてものはみんな、こんな、ものなんだろう。 331 |  それから増給事件と将来重く登用すると赤シャツが云った話をしたら山嵐はふふんと鼻から声を出して、それじゃ僕を免職《めんしょく》する考えだなと云った。免職するつもりだって、君は免職になる気かと聞いたら、誰《だれ》がなるものか、自分が免職になるなら、赤シャツもいっしょに免職させてやると大いに威張《いば》った。どうしていっしょに免職させる気かと押し返して尋《たず》ねたら、そこはまだ考えていないと答えた。山嵐は強そうだが、智慧《ちえ》はあまりなさそうだ。おれが増給を断《こと》わったと話したら、大将大きに喜んでさすが江戸っ子だ、えらいと賞《ほ》めてくれた。 332 |  うらなりが、そんなに厭《いや》がっているなら、なぜ留任の運動をしてやらなかったと聞いてみたら、うらなりから話を聞いた時は、既《すで》にきまってしまって、校長へ二度、赤シャツへ一度行って談判してみたが、どうする事も出来なかったと話した。それについても古賀があまり好人物過ぎるから困る。赤シャツから話があった時、断然断わるか、一応考えてみますと逃《に》げればいいのに、あの弁舌に胡魔化されて、即席《そくせき》に許諾《きょだく》したものだから、あとからお母《っか》さんが泣きついても、自分が談判に行っても役に立たなかったと非常に残念がった。 333 |  今度の事件は全く赤シャツが、うらなりを遠ざけて、マドンナを手に入れる策略なんだろうとおれが云ったら、無論そうに違いない。あいつは大人《おとな》しい顔をして、悪事を働いて、人が何か云うと、ちゃんと逃道《にげみち》を拵《こしら》えて待ってるんだから、よっぽど奸物《かんぶつ》だ。あんな奴にかかっては鉄拳制裁《てっけんせいさい》でなくっちゃ利かないと、瘤《こぶ》だらけの腕《うで》をまくってみせた。おれはついでだから、君の腕は強そうだな柔術《じゅうじゅつ》でもやるかと聞いてみた。すると大将二の腕へ力瘤を入れて、ちょっと攫《つか》んでみろと云うから、指の先で揉《も》んでみたら、何の事はない湯屋にある軽石の様なものだ。 334 |  おれはあまり感心したから、君そのくらいの腕なら、赤シャツの五人や六人は一度に張り飛ばされるだろうと聞いたら、無論さと云いながら、曲げた腕を伸《の》ばしたり、縮ましたりすると、力瘤がぐるりぐるりと皮のなかで廻転《かいてん》する。すこぶる愉快《ゆかい》だ。山嵐の証明する所によると、かんじん綯《よ》りを二本より合せて、この力瘤の出る所へ巻きつけて、うんと腕を曲げると、ぷつりと切れるそうだ。かんじんよりなら、おれにも出来そうだと云ったら、出来るものか、出来るならやってみろと来た。切れないと外聞がわるいから、おれは見合せた。 335 |  君どうだ、今夜の送別会に大いに飲んだあと、赤シャツと野だを撲《なぐ》ってやらないかと面白半分に勧めてみたら、山嵐はそうだなと考えていたが、今夜はまあよそうと云った。なぜと聞くと、今夜は古賀に気の毒だから——それにどうせ撲るくらいなら、あいつらの悪るい所を見届けて現場で撲らなくっちゃ、こっちの落度になるからと、分別のありそうな事を附加《つけた》した。山嵐でもおれよりは考えがあると見える。 336 |  じゃ演説をして古賀君を大いにほめてやれ、おれがすると江戸っ子のぺらぺらになって重みがなくていけない。そうして、きまった所へ出ると、急に溜飲《りゅういん》が起って咽喉《のど》の所へ、大きな丸《たま》が上がって来て言葉が出ないから、君に譲《ゆず》るからと云ったら、妙な病気だな、じゃ君は人中じゃ口は利けないんだね、困るだろう、と聞くから、何そんなに困りゃしないと答えておいた。 337 |  そうこうするうち時間が来たから、山嵐と一所に会場へ行く。会場は花晨亭《かしんてい》といって、当地《ここ》で第一等の料理屋だそうだが、おれは一度も足を入れた事がない。もとの家老とかの屋敷《やしき》を買い入れて、そのまま開業したという話だが、なるほど見懸《みかけ》からして厳《いか》めしい構えだ。家老の屋敷が料理屋になるのは、陣羽織《じんばおり》を縫《ぬ》い直して、胴着《どうぎ》にする様なものだ。 338 |  二人が着いた頃《ころ》には、人数《にんず》ももう大概《たいがい》揃《そろ》って、五十|畳《じょう》の広間に二つ三つ人間の塊《かたまり》が出来ている。五十畳だけに床《とこ》は素敵に大きい。おれが山城屋で占領《せんりょう》した十五畳敷の床とは比較にならない。尺を取ってみたら二間あった。右の方に、赤い模様のある瀬戸物の瓶《かめ》を据《す》えて、その中に松《まつ》の大きな枝《えだ》が挿《さ》してある。松の枝を挿して何にする気か知らないが、何ヶ月立っても散る気遣いがないから、銭が懸らなくって、よかろう。あの瀬戸物はどこで出来るんだと博物の教師に聞いたら、あれは瀬戸物じゃありません、伊万里《いまり》ですと云った。伊万里だって瀬戸物じゃないかと、云ったら、博物はえへへへへと笑っていた。あとで聞いてみたら、瀬戸で出来る焼物だから、瀬戸と云うのだそうだ。おれは江戸っ子だから、陶器《とうき》の事を瀬戸物というのかと思っていた。床の真中に大きな懸物があって、おれの顔くらいな大きさな字が二十八字かいてある。どうも下手《へた》なものだ。あんまり不味《まず》いから、漢学の先生に、なぜあんなまずいものを麗々《れいれい》と懸けておくんですと尋《たず》ねたところ、先生はあれは海屋《かいおく》といって有名な書家のかいた者だと教えてくれた。海屋だか何だか、おれは今だに下手だと思っている。 339 |  やがて書記の川村がどうかお着席をと云うから、柱があって靠《よ》りかかるのに都合のいい所へ坐《すわ》った。海屋の懸物の前に狸《たぬき》が羽織《はおり》、袴《はかま》で着席すると、左に赤シャツが同じく羽織袴で陣取《じんど》った。右の方は主人公だというのでうらなり先生、これも日本服で控《ひか》えている。おれは洋服だから、かしこまるのが窮屈《きゅうくつ》だったから、すぐ胡坐《あぐら》をかいた。隣《とな》りの体操《たいそう》教師は黒ずぼん[#「ずぼん」に傍点]で、ちゃんとかしこまっている。体操の教師だけにいやに修行が積んでいる。やがてお膳《ぜん》が出る。徳利《とくり》が並《なら》ぶ。幹事が立って、一言《いちごん》開会の辞を述べる。それから狸が立つ。赤シャツが起《た》つ。ことごとく送別の辞を述べたが、三人共申し合せたようにうらなり君の、良教師で好人物な事を吹聴《ふいちょう》して、今回去られるのはまことに残念である、学校としてのみならず、個人として大いに惜しむところであるが、ご一身上のご都合で、切に転任をご希望になったのだから致《いた》し方《かた》がないという意味を述べた。こんな嘘《うそ》をついて送別会を開いて、それでちっとも恥《はず》かしいとも思っていない。ことに赤シャツに至って三人のうちで一番うらなり君をほめた。この良友を失うのは実に自分にとって大なる不幸であるとまで云った。しかもそのいい方がいかにも、もっともらしくって、例のやさしい声を一層やさしくして、述べ立てるのだから、始めて聞いたものは、誰でもきっとだまされるに極《きま》ってる。マドンナも大方この手で引掛《ひっか》けたんだろう。赤シャツが送別の辞を述べ立てている最中、向側《むかいがわ》に坐っていた山嵐がおれの顔を見てちょっと稲光《いなびかり》をさした。おれは返電として、人指し指でべっかんこうをして見せた。 340 |  赤シャツが座に復するのを待ちかねて、山嵐がぬっと立ち上がったから、おれは嬉《うれ》しかったので、思わず手をぱちぱちと拍《う》った。すると狸を始め一同がことごとくおれの方を見たには少々困った。山嵐は何を云うかと思うとただ今校長始めことに教頭は古賀君の転任を非常に残念がられたが、私は少々反対で古賀君が一日《いちじつ》も早く当地を去られるのを希望しております。延岡は僻遠《へきえん》の地で、当地に比べたら物質上の不便はあるだろう。が、聞くところによれば風俗のすこぶる淳朴《じゅんぼく》な所で、職員生徒ことごとく上代樸直《じょうだいぼくちょく》の気風を帯びているそうである。心にもないお世辞を振《ふ》り蒔《ま》いたり、美しい顔をして君子を陥《おとしい》れたりするハイカラ野郎は一人もないと信ずるからして、君のごとき温良|篤厚《とっこう》の士は必ずその地方一般の歓迎《かんげい》を受けられるに相違《そうい》ない。吾輩《わがはい》は大いに古賀君のためにこの転任を祝するのである。終りに臨んで君が延岡に赴任《ふにん》されたら、その地の淑女《しゅくじょ》にして、君子の好逑《こうきゅう》となるべき資格あるものを択《えら》んで一日《いちじつ》も早く円満なる家庭をかたち作って、かの不貞無節なるお転婆《てんば》を事実の上において慚死《ざんし》せしめん事を希望します。えへんえへんと二つばかり大きな咳払《せきばら》いをして席に着いた。おれは今度も手を叩《たた》こうと思ったが、またみんながおれの面《かお》を見るといやだから、やめにしておいた。山嵐が坐ると今度はうらなり先生が起った。先生はご鄭寧《ていねい》に、自席から、座敷の端《はし》の末座まで行って、慇懃《いんぎん》に一同に挨拶《あいさつ》をした上、今般は一身上の都合で九州へ参る事になりましたについて、諸先生方が小生のためにこの盛大《せいだい》なる送別会をお開き下さったのは、まことに感銘《かんめい》の至りに堪《た》えぬ次第で——ことにただ今は校長、教頭その他諸君の送別の辞を頂戴《ちょうだい》して、大いに難有《ありがた》く服膺《ふくよう》する訳であります。私はこれから遠方へ参りますが、なにとぞ従前の通りお見捨てなくご愛顧《あいこ》のほどを願います。とへえつく張って席に戻《もど》った。うらなり君はどこまで人が好いんだか、ほとんど底が知れない。自分がこんなに馬鹿にされている校長や、教頭に恭《うやうや》しくお礼を云っている。それも義理|一遍《いっぺん》の挨拶ならだが、あの様子や、あの言葉つきや、あの顔つきから云うと、心《しん》から感謝しているらしい。こんな聖人に真面目にお礼を云われたら、気の毒になって、赤面しそうなものだが狸も赤シャツも真面目に謹聴《きんちょう》しているばかりだ。 341 |  挨拶が済んだら、あちらでもチュー、こちらでもチュー、という音がする。おれも真似をして汁《しる》を飲んでみたがまずいもんだ。口取《くちとり》に蒲鉾《かまぼこ》はついてるが、どす黒くて竹輪の出来損《できそこ》ないである。刺身《さしみ》も並んでるが、厚くって鮪《まぐろ》の切り身を生で食うと同じ事だ。それでも隣《とな》り近所の連中はむしゃむしゃ旨《うま》そうに食っている。大方江戸前の料理を食った事がないんだろう。 342 |  そのうち燗徳利《かんどくり》が頻繁《ひんぱん》に往来し始めたら、四方が急に賑《にぎ》やかになった。野だ公は恭しく校長の前へ出て盃《さかずき》を頂いてる。いやな奴だ。うらなり君は順々に献酬《けんしゅう》をして、一巡周《いちじゅんめぐ》るつもりとみえる。はなはだご苦労である。うらなり君がおれの前へ来て、一つ頂戴致しましょうと袴のひだを正して申し込まれたから、おれも窮屈にズボンのままかしこまって、一|盃《ぱい》差し上げた。せっかく参って、すぐお別れになるのは残念ですね。ご出立《しゅったつ》はいつです、是非浜までお見送りをしましょうと云ったら、うらなり君はいえご用|多《おお》のところ決してそれには及《およ》びませんと答えた。うらなり君が何と云ったって、おれは学校を休んで送る気でいる。 343 |  それから一時間ほどするうちに席上は大分乱れて来る。まあ一|杯《ぱい》、おや僕が飲めと云うのに……などと呂律《ろれつ》の巡《まわ》りかねるのも一人二人《ひとりふたり》出来て来た。少々|退屈《たいくつ》したから便所へ行って、昔風な庭を星明りにすかして眺《なが》めていると山嵐が来た。どうださっきの演説はうまかったろう。と大分得意である。大賛成だが一ヶ所気に入らないと抗議《こうぎ》を申し込んだら、どこが不賛成だと聞いた。 344 | 「美しい顔をして人を陥れるようなハイカラ野郎は延岡に居《お》らないから……と君は云ったろう」 345 | 「うん」 346 | 「ハイカラ野郎だけでは不足だよ」 347 | 348 | 「じゃ何と云うんだ」 349 | 「ハイカラ野郎の、ペテン師の、イカサマ師の、猫被《ねこっかぶ》りの、香具師《やし》の、モモンガーの、岡っ引きの、わんわん鳴けば犬も同然な奴とでも云うがいい」 350 | 「おれには、そう舌は廻らない。君は能弁だ。第一単語を大変たくさん知ってる。それで演舌《えんぜつ》が出来ないのは不思議だ」 351 | 「なにこれは喧嘩《けんか》のときに使おうと思って、用心のために取っておく言葉さ。演舌となっちゃ、こうは出ない」 352 | 「そうかな、しかしぺらぺら出るぜ。もう一遍やって見たまえ」 353 | 「何遍でもやるさいいか。——ハイカラ野郎のペテン師の、イカサマ師の……」と云いかけていると、椽側《えんがわ》をどたばた云わして、二人ばかり、よろよろしながら馳《か》け出して来た。 354 | 「両君そりゃひどい、——逃げるなんて、——僕が居るうちは決して逃《にが》さない、さあのみたまえ。——いかさま師?——面白い、いかさま面白い。——さあ飲みたまえ」 355 | とおれと山嵐をぐいぐい引っ張って行く。実はこの両人共便所に来たのだが、酔《よ》ってるもんだから、便所へはいるのを忘れて、おれ等を引っ張るのだろう。酔っ払いは目の中《あた》る所へ用事を拵えて、前の事はすぐ忘れてしまうんだろう。 356 | 「さあ、諸君、いかさま師を引っ張って来た。さあ飲ましてくれたまえ。いかさま師をうんと云うほど、酔わしてくれたまえ。君逃げちゃいかん」 357 | と逃げもせぬ、おれを壁際《かべぎわ》へ圧《お》し付けた。諸方を見廻してみると、膳の上に満足な肴の乗っているのは一つもない。自分の分を奇麗《きれい》に食い尽《つく》して、五六間先へ遠征《えんせい》に出た奴もいる。校長はいつ帰ったか姿が見えない。 358 |  ところへお座敷はこちら? と芸者が三四人はいって来た。おれも少し驚《おど》ろいたが、壁際へ圧し付けられているんだから、じっとしてただ見ていた。すると今まで床柱《とこばしら》へもたれて例の琥珀《こはく》のパイプを自慢《じまん》そうに啣《くわ》えていた、赤シャツが急に起《た》って、座敷を出にかかった。向《むこ》うからはいって来た芸者の一人が、行き違いながら、笑って挨拶をした。その一人は一番若くて一番奇麗な奴だ。遠くで聞《きこ》えなかったが、おや今晩はぐらい云ったらしい。赤シャツは知らん顔をして出て行ったぎり、顔を出さなかった。大方校長のあとを追懸《おいか》けて帰ったんだろう。 359 |  芸者が来たら座敷中急に陽気になって、一同が鬨《とき》の声を揚《あ》げて歓迎《かんげい》したのかと思うくらい、騒々《そうぞう》しい。そうしてある奴はなんこを攫《つか》む。その声の大きな事、まるで居合抜《いあいぬき》の稽古《けいこ》のようだ。こっちでは拳《けん》を打ってる。よっ、はっ、と夢中《むちゅう》で両手を振るところは、ダーク一座の操人形《あやつりにんぎょう》よりよっぽど上手《じょうず》だ。向うの隅《すみ》ではおいお酌《しゃく》だ、と徳利を振ってみて、酒だ酒だと言い直している。どうもやかましくて騒々しくってたまらない。そのうちで手持無沙汰《てもちぶさた》に下を向いて考え込んでるのはうらなり君ばかりである。自分のために送別会を開いてくれたのは、自分の転任を惜《おし》んでくれるんじゃない。みんなが酒を呑《の》んで遊ぶためだ。自分独りが手持無沙汰で苦しむためだ。こんな送別会なら、開いてもらわない方がよっぽどましだ。 360 |  しばらくしたら、めいめい胴間声《どうまごえ》を出して何か唄《うた》い始めた。おれの前へ来た一人の芸者が、あんた、なんぞ、唄いなはれ、と三味線を抱《かか》えたから、おれは唄わない、貴様唄ってみろと云ったら、金《かね》や太鼓《たいこ》でねえ、迷子の迷子の三太郎と、どんどこ、どんのちゃんちきりん。叩いて廻って逢《あ》われるものならば、わたしなんぞも、金や太鼓でどんどこ、どんのちゃんちきりんと叩いて廻って逢いたい人がある、と二た息にうたって、おおしんどと云った。おおしんどなら、もっと楽なものをやればいいのに。 361 |  すると、いつの間にか傍《そば》へ来て坐った、野だが、鈴ちゃん逢いたい人に逢ったと思ったら、すぐお帰りで、お気の毒さまみたようでげすと相変らず噺《はな》し家みたような言葉使いをする。知りまへんと芸者はつんと済ました。野だは頓着《とんじゃく》なく、たまたま逢いは逢いながら……と、いやな声を出して義太夫《ぎだゆう》の真似《まね》をやる。おきなはれやと芸者は平手で野だの膝《ひざ》を叩いたら野だは恐悦《きょうえつ》して笑ってる。この芸者は赤シャツに挨拶をした奴だ。芸者に叩かれて笑うなんて、野だもおめでたい者だ。鈴ちゃん僕が紀伊《き》の国を踴《おど》るから、一つ弾《ひ》いて頂戴と云い出した。野だはこの上まだ踴る気でいる。 362 |  向うの方で漢学のお爺《じい》さんが歯のない口を歪《ゆが》めて、そりゃ聞えません伝兵衛《でんべい》さん、お前とわたしのその中は……とまでは無事に済《すま》したが、それから? と芸者に聞いている。爺さんなんて物覚えのわるいものだ。一人が博物を捕《つら》まえて近頃《ちかごろ》こないなのが、でけましたぜ、弾いてみまほうか。よう聞いて、いなはれや——花月巻《かげつまき》、白いリボンのハイカラ頭、乗るは自転車、弾くはヴァイオリン、半可《はんか》の英語でぺらぺらと、I am glad to see you と唄うと、博物はなるほど面白い、英語入りだねと感心している。 363 |  山嵐は馬鹿に大きな声を出して、芸者、芸者と呼んで、おれが剣舞《けんぶ》をやるから、三味線を弾けと号令を下した。芸者はあまり乱暴な声なので、あっけに取られて返事もしない。山嵐は委細構わず、ステッキを持って来て、踏破千山万岳烟《ふみやぶるせんざんばんがくのけむり》と真中《まんなか》へ出て独りで隠《かく》し芸を演じている。ところへ野だがすでに紀伊《き》の国を済まして、かっぽれを済まして、棚《たな》の達磨《だるま》さんを済して丸裸《まるはだか》の越中褌《えっちゅうふんどし》一つになって、棕梠箒《しゅろぼうき》を小脇に抱《か》い込んで、日清談判|破裂《はれつ》して……と座敷中練りあるき出した。まるで気違《きちが》いだ。 364 |  おれはさっきから苦しそうに袴も脱《ぬ》がず控えているうらなり君が気の毒でたまらなかったが、なんぼ自分の送別会だって、越中褌の裸踴《はだかおどり》まで羽織袴で我慢《がまん》してみている必要はあるまいと思ったから、そばへ行って、古賀さんもう帰りましょうと退去を勧めてみた。するとうらなり君は今日は私の送別会だから、私が先へ帰っては失礼です、どうぞご遠慮《えんりょ》なくと動く景色もない。なに構うもんですか、送別会なら、送別会らしくするがいいです、あの様をご覧なさい。気狂会《きちがいかい》です。さあ行きましょうと、進まないのを無理に勧めて、座敷を出かかるところへ、野だが箒を振り振り進行して来て、やご主人が先へ帰るとはひどい。日清談判だ。帰せないと箒を横にして行く手を塞《ふさ》いだ。おれはさっきから肝癪《かんしゃく》が起っているところだから、日清談判なら貴様はちゃんちゃんだろうと、いきなり拳骨《げんこつ》で、野だの頭をぽかりと喰《く》わしてやった。野だは二三秒の間毒気を抜かれた体《てい》で、ぼんやりしていたが、おやこれはひどい。お撲《ぶ》ちになったのは情ない。この吉川をご打擲《ちょうちゃく》とは恐れ入った。いよいよもって日清談判だ。とわからぬ事をならべているところへ、うしろから山嵐が何か騒動《そうどう》が始まったと見てとって、剣舞をやめて、飛んできたが、このていたらくを見て、いきなり頸筋《くびすじ》をうんと攫《つか》んで引き戻《もど》した。日清……いたい。いたい。どうもこれは乱暴だと振りもがくところを横に捩《ねじ》ったら、すとんと倒《たお》れた。あとはどうなったか知らない。途中《とちゅう》でうらなり君に別れて、うちへ帰ったら十一時過ぎだった。 365 | 366 | [#5字下げ]十[#「十」は中見出し] 367 | 368 |  祝勝会で学校はお休みだ。練兵場《れんぺいば》で式があるというので、狸《たぬき》は生徒を引率して参列しなくてはならない。おれも職員の一人《ひとり》としていっしょにくっついて行くんだ。町へ出ると日の丸だらけで、まぼしいくらいである。学校の生徒は八百人もあるのだから、体操の教師が隊伍《たいご》を整えて、一組一組の間を少しずつ明けて、それへ職員が一人か二人《ふたり》ずつ監督《かんとく》として割り込《こ》む仕掛《しか》けである。仕掛《しかけ》だけはすこぶる巧妙《こうみょう》なものだが、実際はすこぶる不手際である。生徒は小供《こども》の上に、生意気で、規律を破らなくっては生徒の体面にかかわると思ってる奴等《やつら》だから、職員が幾人《いくたり》ついて行ったって何の役に立つもんか。命令も下さないのに勝手な軍歌をうたったり、軍歌をやめるとワーと訳もないのに鬨《とき》の声を揚《あ》げたり、まるで浪人《ろうにん》が町内をねりあるいてるようなものだ。軍歌も鬨の声も揚げない時はがやがや何か喋舌《しゃべ》ってる。喋舌らないでも歩けそうなもんだが、日本人はみな口から先へ生れるのだから、いくら小言を云《い》ったって聞きっこない。喋舌るのもただ喋舌るのではない、教師のわる口を喋舌るんだから、下等だ。おれは宿直事件で生徒を謝罪さして、まあこれならよかろうと思っていた。ところが実際は大違《おおちが》いである。下宿の婆《ばあ》さんの言葉を借りて云えば、正に大違いの勘五郎《かんごろう》である。生徒があやまったのは心《しん》から後悔《こうかい》してあやまったのではない。ただ校長から、命令されて、形式的に頭を下げたのである。商人が頭ばかり下げて、狡《ずる》い事をやめないのと一般で生徒も謝罪だけはするが、いたずらは決してやめるものでない。よく考えてみると世の中はみんなこの生徒のようなものから成立しているかも知れない。人があやまったり詫《わ》びたりするのを、真面目《まじめ》に受けて勘弁するのは正直過ぎる馬鹿《ばか》と云うんだろう。あやまるのも仮りにあやまるので、勘弁するのも仮りに勘弁するのだと思ってれば差《さ》し支《つか》えない。もし本当にあやまらせる気なら、本当に後悔するまで叩《たた》きつけなくてはいけない。 369 |  おれが組と組の間にはいって行くと、天麩羅《てんぷら》だの、団子《だんご》だの、と云う声が絶えずする。しかも大勢だから、誰《だれ》が云うのだか分らない。よし分ってもおれの事を天麩羅と云ったんじゃありません、団子と申したのじゃありません、それは先生が神経衰弱《しんけいすいじゃく》だから、ひがんで、そう聞くんだぐらい云うに極《き》まってる。こんな卑劣《ひれつ》な根性は封建時代から、養成したこの土地の習慣なんだから、いくら云って聞かしたって、教えてやったって、到底《とうてい》直りっこない。こんな土地に一年も居ると、潔白なおれも、この真似《まね》をしなければならなく、なるかも知れない。向《むこ》うでうまく言い抜《ぬ》けられるような手段で、おれの顔を汚《よご》すのを抛《ほう》っておく、樗蒲一《ちょぼいち》はない。向こうが人ならおれも人だ。生徒だって、子供だって、ずう体はおれより大きいや。だから刑罰《けいばつ》として何か返報をしてやらなくっては義理がわるい。ところがこっちから返報をする時分に尋常《じんじょう》の手段で行くと、向うから逆捩《さかねじ》を食わして来る。貴様がわるいからだと云うと、初手から逃《に》げ路《みち》が作ってある事だから滔々《とうとう》と弁じ立てる。弁じ立てておいて、自分の方を表向きだけ立派にしてそれからこっちの非を攻撃《こうげき》する。もともと返報にした事だから、こちらの弁護は向うの非が挙がらない上は弁護にならない。つまりは向うから手を出しておいて、世間体はこっちが仕掛けた喧嘩《けんか》のように、見傚《みな》されてしまう。大変な不利益だ。それなら向うのやるなり、愚迂多良童子《ぐうたらどうじ》を極め込んでいれば、向うはますます増長するばかり、大きく云えば世の中のためにならない。そこで仕方がないから、こっちも向うの筆法を用いて捕《つら》まえられないで、手の付けようのない返報をしなくてはならなくなる。そうなっては江戸《えど》っ子も駄目《だめ》だ。駄目だが一年もこうやられる以上は、おれも人間だから駄目でも何でもそうならなくっちゃ始末がつかない。どうしても早く東京へ帰って清《きよ》といっしょになるに限る。こんな田舎《いなか》に居るのは堕落《だらく》しに来ているようなものだ。新聞配達をしたって、ここまで堕落するよりはましだ。 370 |  こう考えて、いやいや、附《つ》いてくると、何だか先鋒《せんぽう》が急にがやがや騒《さわ》ぎ出した。同時に列はぴたりと留まる。変だから、列を右へはずして、向うを見ると、大手町《おおてまち》を突《つ》き当って薬師町《やくしまち》へ曲がる角の所で、行き詰《づま》ったぎり、押《お》し返したり、押し返されたりして揉《も》み合っている。前方から静かに静かにと声を涸《か》らして来た体操教師に何ですと聞くと、曲り角で中学校と師範《しはん》学校が衝突《しょうとつ》したんだと云う。 371 |  中学と師範とはどこの県下でも犬と猿《さる》のように仲がわるいそうだ。なぜだかわからないが、まるで気風が合わない。何かあると喧嘩をする。大方|狭《せま》い田舎で退屈《たいくつ》だから、暇潰《ひまつぶ》しにやる仕事なんだろう。おれは喧嘩は好きな方だから、衝突と聞いて、面白半分に馳《か》け出して行った。すると前の方にいる連中は、しきりに何だ地方税の癖《くせ》に、引き込めと、怒鳴《どな》ってる。後ろからは押せ押せと大きな声を出す。おれは邪魔《じゃま》になる生徒の間をくぐり抜けて、曲がり角へもう少しで出ようとした時に、前へ! と云う高く鋭《するど》い号令が聞《きこ》えたと思ったら師範学校の方は粛粛《しゅくしゅく》として行進を始めた。先を争った衝突は、折合がついたには相違《そうい》ないが、つまり中学校が一歩を譲《ゆず》ったのである。資格から云うと師範学校の方が上だそうだ。 372 |  祝勝の式はすこぶる簡単なものであった。旅団長が祝詞を読む、知事が祝詞を読む、参列者が万歳《ばんざい》を唱える。それでおしまいだ。余興は午後にあると云う話だから、ひとまず下宿へ帰って、こないだじゅうから、気に掛《かか》っていた、清への返事をかきかけた。今度はもっと詳《くわ》しく書いてくれとの注文だから、なるべく念入《ねんいり》に認《したた》めなくっちゃならない。しかしいざとなって、半切《はんきれ》を取り上げると、書く事はたくさんあるが、何から書き出していいか、わからない。あれにしようか、あれは面倒臭《めんどうくさ》い。これにしようか、これはつまらない。何か、すらすらと出て、骨が折れなくって、そうして清が面白がるようなものはないかしらん、と考えてみると、そんな注文通りの事件は一つもなさそうだ。おれは墨《すみ》を磨《す》って、筆をしめして、巻紙を睨《にら》めて、——巻紙を睨めて、筆をしめして、墨を磨って——同じ所作を同じように何返も繰《く》り返したあと、おれには、とても手紙は書けるものではないと、諦《あきら》めて硯《すずり》の蓋《ふた》をしてしまった。手紙なんぞをかくのは面倒臭い。やっぱり東京まで出掛けて行って、逢《あ》って話をするのが簡便だ。清の心配は察しないでもないが、清の注文通りの手紙を書くのは三七日の断食《だんじき》よりも苦しい。 373 |  おれは筆と巻紙を抛《ほう》り出して、ごろりと転がって肱枕《ひじまくら》をして庭《にわ》の方を眺《なが》めてみたが、やっぱり清の事が気にかかる。その時おれはこう思った。こうして遠くへ来てまで、清の身の上を案じていてやりさえすれば、おれの真心《まこと》は清に通じるに違いない。通じさえすれば手紙なんぞやる必要はない。やらなければ無事で暮《くら》してると思ってるだろう。たよりは死んだ時か病気の時か、何か事の起った時にやりさえすればいい訳だ。 374 |  庭は十坪《とつぼ》ほどの平庭で、これという植木もない。ただ一本の蜜柑《みかん》があって、塀《へい》のそとから、目標《めじるし》になるほど高い。おれはうちへ帰ると、いつでもこの蜜柑を眺める。東京を出た事のないものには蜜柑の生《な》っているところはすこぶる珍《めずら》しいものだ。あの青い実がだんだん熟してきて、黄色になるんだろうが、定めて奇麗《きれい》だろう。今でももう半分色の変ったのがある。婆《ばあ》さんに聞いてみると、すこぶる水気の多い、旨《うま》い蜜柑だそうだ。今に熟《うれ》たら、たんと召《め》し上がれと云ったから、毎日少しずつ食ってやろう。もう三週間もしたら、充分《じゅうぶん》食えるだろう。まさか三週間以内にここを去る事もなかろう。 375 |  おれが蜜柑の事を考えているところへ、偶然《ぐうぜん》山嵐《やまあらし》が話しにやって来た。今日は祝勝会だから、君といっしょにご馳走《ちそう》を食おうと思って牛肉を買って来たと、竹の皮の包《つつみ》を袂《たもと》から引きずり出して、座敷《ざしき》の真中《まんなか》へ抛り出した。おれは下宿で芋責《いもぜめ》豆腐責になってる上、蕎麦《そば》屋行き、団子《だんご》屋行きを禁じられてる際だから、そいつは結構だと、すぐ婆さんから鍋《なべ》と砂糖をかり込んで、煮方《にかた》に取りかかった。 376 |  山嵐は無暗《むやみ》に牛肉を頬張《ほおば》りながら、君あの赤シャツが芸者に馴染《なじみ》のある事を知ってるかと聞くから、知ってるとも、この間うらなりの送別会の時に来た一人がそうだろうと云ったら、そうだ僕《ぼく》はこの頃《ごろ》ようやく勘づいたのに、君はなかなか敏捷《びんしょう》だと大いにほめた。 377 | 「あいつは、ふた言目には品性だの、精神的|娯楽《ごらく》だのと云う癖《くせ》に、裏へ廻《まわ》って、芸者と関係なんかつけとる、怪《け》しからん奴《やつ》だ。それもほかの人が遊ぶのを寛容《かんよう》するならいいが、君が蕎麦屋へ行ったり、団子屋へはいるのさえ取締上《とりしまりじょう》害になると云って、校長の口を通して注意を加えたじゃないか」 378 | 「うん、あの野郎の考えじゃ芸者買は精神的娯楽で、天麩羅や、団子は物理的娯楽なんだろう。精神的娯楽なら、もっと大べらにやるがいい。何だあの様《ざま》は。馴染の芸者がはいってくると、入れ代りに席をはずして、逃げるなんて、どこまでも人を胡魔化《ごまか》す気だから気に食わない。そうして人が攻撃《こうげき》すると、僕は知らないとか、露西亜《ロシア》文学だとか、俳句が新体詩の兄弟分だとか云って、人を烟《けむ》に捲《ま》くつもりなんだ。あんな弱虫は男じゃないよ。全く御殿女中《ごてんじょちゅう》の生れ変りか何かだぜ。ことによると、あいつのおやじは湯島のかげま[#「かげま」に傍点]かもしれない」 379 | 「湯島のかげま[#「かげま」に傍点]た何だ」 380 | 「何でも男らしくないもんだろう。——君そこのところはまだ煮えていないぜ。そんなのを食うと絛虫《さなだむし》が湧《わ》くぜ」 381 | 「そうか、大抵《たいてい》大丈夫《だいじょうぶ》だろう。それで赤シャツは人に隠《かく》れて、温泉《ゆ》の町の角屋《かどや》へ行って、芸者と会見するそうだ」 382 | 「角屋って、あの宿屋か」 383 | 「宿屋兼料理屋さ。だからあいつを一番へこますためには、あいつが芸者をつれて、あすこへはいり込むところを見届けておいて面詰《めんきつ》するんだね」 384 | 「見届けるって、夜番《よばん》でもするのかい」 385 | 「うん、角屋の前に枡屋《ますや》という宿屋があるだろう。あの表二階をかりて、障子《しょうじ》へ穴をあけて、見ているのさ」 386 | 「見ているときに来るかい」 387 | 「来るだろう。どうせひと晩じゃいけない。二週間ばかりやるつもりでなくっちゃ」 388 | 「随分《ずいぶん》疲れるぜ。僕あ、おやじの死ぬとき一週間ばかり徹夜《てつや》して看病した事があるが、あとでぼんやりして、大いに弱った事がある」 389 | 「少しぐらい身体が疲れたって構わんさ。あんな奸物《かんぶつ》をあのままにしておくと、日本のためにならないから、僕が天に代って誅戮《ちゅうりく》を加えるんだ」 390 | 「愉快《ゆかい》だ。そう事が極まれば、おれも加勢してやる。それで今夜から夜番をやるのかい」 391 | 「まだ枡屋に懸合《かけあ》ってないから、今夜は駄目だ」 392 | 「それじゃ、いつから始めるつもりだい」 393 | 「近々のうちやるさ。いずれ君に報知をするから、そうしたら、加勢してくれたまえ」 394 | 「よろしい、いつでも加勢する。僕《ぼく》は計略《はかりごと》は下手《へた》だが、喧嘩とくるとこれでなかなかすばしこいぜ」 395 |  おれと山嵐がしきりに赤シャツ退治の計略《はかりごと》を相談していると、宿の婆さんが出て来て、学校の生徒さんが一人、堀田《ほった》先生にお目にかかりたいててお出《い》でたぞなもし。今お宅へ参じたのじゃが、お留守《るす》じゃけれ、大方ここじゃろうてて捜《さが》し当ててお出でたのじゃがなもしと、閾《しきい》の所へ膝《ひざ》を突《つ》いて山嵐の返事を待ってる。山嵐はそうですかと玄関《げんかん》まで出て行ったが、やがて帰って来て、君、生徒が祝勝会の余興を見に行かないかって誘《さそ》いに来たんだ。今日は高知《こうち》から、何とか踴《おど》りをしに、わざわざここまで多人数《たにんず》乗り込んで来ているのだから、是非見物しろ、めったに見られない踴《おどり》だというんだ、君もいっしょに行ってみたまえと山嵐は大いに乗り気で、おれに同行を勧める。おれは踴なら東京でたくさん見ている。毎年|八幡様《はちまんさま》のお祭りには屋台が町内へ廻ってくるんだから汐酌《しおく》みでも何でもちゃんと心得ている。土佐っぽの馬鹿踴なんか、見たくもないと思ったけれども、せっかく山嵐が勧めるもんだから、つい行く気になって門へ出た。山嵐を誘いに来たものは誰かと思ったら赤シャツの弟だ。妙《みょう》な奴《やつ》が来たもんだ。 396 |  会場へはいると、回向院《えこういん》の相撲《すもう》か本門寺《ほんもんじ》の御会式《おえしき》のように幾旒《いくながれ》となく長い旗を所々に植え付けた上に、世界万国の国旗をことごとく借りて来たくらい、縄《なわ》から縄、綱《つな》から綱へ渡《わた》しかけて、大きな空が、いつになく賑《にぎ》やかに見える。東の隅《すみ》に一夜作りの舞台《ぶたい》を設けて、ここでいわゆる高知の何とか踴りをやるんだそうだ。舞台を右へ半町ばかりくると葭簀《よしず》の囲いをして、活花《いけばな》が陳列《ちんれつ》してある。みんなが感心して眺めているが、一向くだらないものだ。あんなに草や竹を曲げて嬉《うれ》しがるなら、背虫の色男や、跛《びっこ》の亭主《ていしゅ》を持って自慢《じまん》するがよかろう。 397 |  舞台とは反対の方面で、しきりに花火を揚げる。花火の中から風船が出た。帝国万歳《ていこくばんざい》とかいてある。天主の松の上をふわふわ飛んで営所のなかへ落ちた。次はぽんと音がして、黒い団子が、しょっと秋の空を射抜《いぬ》くように揚《あ》がると、それがおれの頭の上で、ぽかりと割れて、青い烟《けむり》が傘《かさ》の骨のように開いて、だらだらと空中に流れ込んだ。風船がまた上がった。今度は陸海軍万歳と赤地に白く染め抜いた奴が風に揺られて、温泉《ゆ》の町から、相生村《あいおいむら》の方へ飛んでいった。大方観音様の境内《けいだい》へでも落ちたろう。 398 |  式の時はさほどでもなかったが、今度は大変な人出だ。田舎にもこんなに人間が住んでるかと驚《おど》ろいたぐらいうじゃうじゃしている。利口《りこう》な顔はあまり見当らないが、数から云うとたしかに馬鹿に出来ない。そのうち評判の高知の何とか踴が始まった。踴というから藤間か何ぞのやる踴りかと早合点していたが、これは大間違いであった。 399 |  いかめしい後鉢巻《うしろはちまき》をして、立《た》っ付《つ》け袴《ばかま》を穿《は》いた男が十人ばかりずつ、舞台の上に三列に並《なら》んで、その三十人がことごとく抜き身を携《さ》げているには魂消《たまげ》た。前列と後列の間はわずか一尺五寸ぐらいだろう、左右の間隔《かんかく》はそれより短いとも長くはない。たった一人列を離《はな》れて舞台の端《はし》に立ってるのがあるばかりだ。この仲間|外《はず》れの男は袴だけはつけているが、後鉢巻は倹約して、抜身の代りに、胸へ太鼓《たいこ》を懸《か》けている。太鼓は太神楽《だいかぐら》の太鼓と同じ物だ。この男がやがて、いやあ、はああと呑気《のんき》な声を出して、妙な謡《うた》をうたいながら、太鼓をぼこぼん、ぼこぼんと叩《たた》く。歌の調子は前代未聞の不思議なものだ。三河万歳《みかわまんざい》と普陀洛《ふだらく》やの合併《がっぺい》したものと思えば大した間違いにはならない。 400 |  歌はすこぶる悠長《ゆうちょう》なもので、夏分の水飴《みずあめ》のように、だらしがないが、句切りをとるためにぼこぼんを入れるから、のべつのようでも拍子《ひょうし》は取れる。この拍子に応じて三十人の抜き身がぴかぴかと光るのだが、これはまたすこぶる迅速《じんそく》なお手際で、拝見していても冷々《ひやひや》する。隣《とな》りも後ろも一尺五寸以内に生きた人間が居て、その人間がまた切れる抜き身を自分と同じように振《ふ》り舞《ま》わすのだから、よほど調子が揃《そろ》わなければ、同志撃《どうしうち》を始めて怪我《けが》をする事になる。それも動かないで刀だけ前後とか上下とかに振るのなら、まだ危険《あぶなく》もないが、三十人が一度に足踏《あしぶ》みをして横を向く時がある。ぐるりと廻る事がある。膝を曲げる事がある。隣りのものが一秒でも早過ぎるか、遅《おそ》過ぎれば、自分の鼻は落ちるかも知れない。隣りの頭はそがれるかも知れない。抜き身の動くのは自由自在だが、その動く範囲《はんい》は一尺五寸角の柱のうちにかぎられた上に、前後左右のものと同方向に同速度にひらめかなければならない。こいつは驚いた、なかなかもって汐酌《しおくみ》や関《せき》の戸《と》の及《およ》ぶところでない。聞いてみると、これははなはだ熟練の入るもので容易な事では、こういう風に調子が合わないそうだ。ことにむずかしいのは、かの万歳節のぼこぼん先生だそうだ。三十人の足の運びも、手の働きも、腰《こし》の曲げ方も、ことごとくこのぼこぼん君の拍子一つで極まるのだそうだ。傍《はた》で見ていると、この大将が一番呑気そうに、いやあ、はああと気楽にうたってるが、その実ははなはだ責任が重くって非常に骨が折れるとは不思議なものだ。 401 |  おれと山嵐が感心のあまりこの踴を余念なく見物していると、半町ばかり、向うの方で急にわっと云う鬨の声がして、今まで穏《おだ》やかに諸所を縦覧していた連中が、にわかに波を打って、右左りに揺《うご》き始める。喧嘩だ喧嘩だと云う声がすると思うと、人の袖《そで》を潜《くぐ》り抜《ぬ》けて来た赤シャツの弟が、先生また喧嘩です、中学の方で、今朝《けさ》の意趣返《いしゅがえ》しをするんで、また師範《しはん》の奴と決戦を始めたところです、早く来て下さいと云いながらまた人の波のなかへ潜《もぐ》り込《こ》んでどっかへ行ってしまった。 402 |  山嵐は世話の焼ける小僧だまた始めたのか、いい加減にすればいいのにと逃げる人を避《よ》けながら一散に馳《か》け出した。見ている訳にも行かないから取り鎮《しず》めるつもりだろう。おれは無論の事逃げる気はない。山嵐の踵《かかと》を踏んであとからすぐ現場へ馳けつけた。喧嘩は今が真最中《まっさいちゅう》である。師範の方は五六十人もあろうか、中学はたしかに三割方多い。師範は制服をつけているが、中学は式後|大抵《たいてい》は日本服に着換《きが》えているから、敵味方はすぐわかる。しかし入り乱れて組んづ、解《ほご》れつ戦ってるから、どこから、どう手を付けて引き分けていいか分らない。山嵐は困ったなと云う風で、しばらくこの乱雑な有様を眺めていたが、こうなっちゃ仕方がない。巡査《じゅんさ》がくると面倒だ。飛び込んで分けようと、おれの方を見て云うから、おれは返事もしないで、いきなり、一番喧嘩の烈《はげ》しそうな所へ躍《おど》り込《こ》んだ。止《よ》せ止せ。そんな乱暴をすると学校の体面に関わる。よさないかと、出るだけの声を出して敵と味方の分界線らしい所を突《つ》き貫《ぬ》けようとしたが、なかなかそう旨《うま》くは行かない。一二間はいったら、出る事も引く事も出来なくなった。目の前に比較的《ひかくてき》大きな師範生が、十五六の中学生と組み合っている。止せと云ったら、止さないかと師範生の肩《かた》を持って、無理に引き分けようとする途端《とたん》にだれか知らないが、下からおれの足をすくった。おれは不意を打たれて握《にぎ》った、肩を放して、横に倒《たお》れた。堅《かた》い靴《くつ》でおれの背中の上へ乗った奴がある。両手と膝を突いて下から、跳《は》ね起きたら、乗った奴は右の方へころがり落ちた。起き上がって見ると、三間ばかり向うに山嵐の大きな身体が生徒の間に挟《はさ》まりながら、止せ止せ、喧嘩は止せ止せと揉み返されてるのが見えた。おい到底駄目だと云ってみたが聞えないのか返事もしない。 403 |  ひゅうと風を切って飛んで来た石が、いきなりおれの頬骨《ほおぼね》へ中《あた》ったなと思ったら、後ろからも、背中を棒《ぼう》でどやした奴がある。教師の癖《くせ》に出ている、打《ぶ》て打てと云う声がする。教師は二人だ。大きい奴と、小さい奴だ。石を抛《な》げろ。と云う声もする。おれは、なに生意気な事をぬかすな、田舎者の癖にと、いきなり、傍《そば》に居た師範生の頭を張りつけてやった。石がまたひゅうと来る。今度はおれの五|分《ぶ》刈《がり》の頭を掠《かす》めて後ろの方へ飛んで行った。山嵐はどうなったか見えない。こうなっちゃ仕方がない。始めは喧嘩をとめにはいったんだが、どやされたり、石をなげられたりして、恐《おそ》れ入って引き下がるうんでれがんがあるものか。おれを誰だと思うんだ。身長《なり》は小さくっても喧嘩の本場で修行を積んだ兄さんだと無茶苦茶に張り飛ばしたり、張り飛ばされたりしていると、やがて巡査だ巡査だ逃げろ逃げろと云う声がした。今まで葛練《くずね》りの中で泳いでるように身動きも出来なかったのが、急に楽になったと思ったら、敵も味方も一度に引上げてしまった。田舎者でも退却《たいきゃく》は巧妙だ。クロパトキンより旨いくらいである。 404 |  山嵐はどうしたかと見ると、紋付《もんつき》の一重羽織《ひとえばおり》をずたずたにして、向うの方で鼻を拭《ふ》いている。鼻柱をなぐられて大分出血したんだそうだ。鼻がふくれ上がって真赤《まっか》になってすこぶる見苦しい。おれは飛白《かすり》の袷《あわせ》を着ていたから泥《どろ》だらけになったけれども、山嵐の羽織ほどな損害はない。しかし頬《ほっ》ぺたがぴりぴりしてたまらない。山嵐は大分血が出ているぜと教えてくれた。 405 |  巡査は十五六名来たのだが、生徒は反対の方面から退却したので、捕《つら》まったのは、おれと山嵐だけである。おれらは姓名《せいめい》を告げて、一部始終を話したら、ともかくも警察まで来いと云うから、警察へ行って、署長の前で事の顛末《てんまつ》を述べて下宿へ帰った。 406 | 407 | [#5字下げ]十一[#「十一」は中見出し] 408 | 409 |  あくる日|眼《め》が覚めてみると、身体中《からだじゅう》痛くてたまらない。久しく喧嘩《けんか》をしつけなかったから、こんなに答えるんだろう。これじゃあんまり自慢《じまん》もできないと床《とこ》の中で考えていると、婆《ばあ》さんが四国新聞を持ってきて枕元《まくらもと》へ置いてくれた。実は新聞を見るのも退儀《たいぎ》なんだが、男がこれしきの事に閉口《へこ》たれて仕様があるものかと無理に腹這《はらば》いになって、寝《ね》ながら、二頁を開けてみると驚《おど》ろいた。昨日の喧嘩がちゃんと出ている。喧嘩の出ているのは驚ろかないのだが、中学の教師|堀田某《ほったぼう》と、近頃《ちかごろ》東京から赴任《ふにん》した生意気なる某とが、順良なる生徒を使嗾《しそう》してこの騒動《そうどう》を喚起《かんき》せるのみならず、両人は現場にあって生徒を指揮したる上、みだりに師範生に向《むか》って暴行をほしいままにしたりと書いて、次にこんな意見が附記《ふき》してある。本県の中学は昔時《せきじ》より善良温順の気風をもって全国の羨望《せんぼう》するところなりしが、軽薄《けいはく》なる二|豎子《じゅし》のために吾校《わがこう》の特権を毀損《きそん》せられて、この不面目を全市に受けたる以上は、吾人《ごじん》は奮然《ふんぜん》として起《た》ってその責任を問わざるを得ず。吾人は信ず、吾人が手を下す前に、当局者は相当の処分をこの無頼漢《ぶらいかん》の上に加えて、彼等《かれら》をして再び教育界に足を入るる余地なからしむる事を。そうして一字ごとにみんな黒点を加えて、お灸《きゅう》を据《す》えたつもりでいる。おれは床の中で、糞《くそ》でも喰《く》らえと云《い》いながら、むっくり飛び起きた。不思議な事に今まで身体の関節《ふしぶし》が非常に痛かったのが、飛び起きると同時に忘れたように軽くなった。 410 |  おれは新聞を丸めて庭へ抛《な》げつけたが、それでもまだ気に入らなかったから、わざわざ後架《こうか》へ持って行って棄《す》てて来た。新聞なんて無暗《むやみ》な嘘《うそ》を吐《つ》くもんだ。世の中に何が一番|法螺《ほら》を吹《ふ》くと云って、新聞ほどの法螺吹きはあるまい。おれの云ってしかるべき事をみんな向《むこ》うで並《なら》べていやがる。それに近頃東京から赴任した生意気な某とは何だ。天下に某と云う名前の人があるか。考えてみろ。これでもれっきとした姓《せい》もあり名もあるんだ。系図が見たけりゃ、多田満仲《ただのまんじゅう》以来の先祖を一人《ひとり》残らず拝ましてやらあ。——顔を洗ったら、頬《ほっ》ぺたが急に痛くなった。婆さんに鏡をかせと云ったら、けさの新聞をお見たかなもしと聞く。読んで後架へ棄てて来た。欲しけりゃ拾って来いと云ったら、驚《おどろ》いて引き下がった。鏡で顔を見ると昨日《きのう》と同じように傷がついている。これでも大事な顔だ、顔へ傷まで付けられた上へ生意気なる某などと、某呼ばわりをされればたくさんだ。 411 |  今日の新聞に辟易《へきえき》して学校を休んだなどと云われちゃ一生の名折れだから、飯を食っていの一号に出頭した。出てくる奴《やつ》も、出てくる奴もおれの顔を見て笑っている。何がおかしいんだ。貴様達にこしらえてもらった顔じゃあるまいし。そのうち、野だが出て来て、いや昨日はお手柄《てがら》で、——名誉《めいよ》のご負傷でげすか、と送別会の時に撲《なぐ》った返報と心得たのか、いやに冷《ひや》かしたから、余計な事を言わずに絵筆でも舐《な》めていろと云ってやった。するとこりゃ恐入《おそれい》りやした。しかしさぞお痛い事でげしょうと云うから、痛かろうが、痛くなかろうがおれの面だ。貴様の世話になるもんかと怒鳴《どな》りつけてやったら、向《むこ》う側の自席へ着いて、やっぱりおれの顔を見て、隣《とな》りの歴史の教師と何か内所話をして笑っている。 412 |  それから山嵐が出頭した。山嵐の鼻に至っては、紫色《むらさきいろ》に膨張《ぼうちょう》して、掘《ほ》ったら中から膿《うみ》が出そうに見える。自惚《うぬぼれ》のせいか、おれの顔よりよっぽど手ひどく遣《や》られている。おれと山嵐は机を並べて、隣り同志の近しい仲で、お負けにその机が部屋の戸口から真正面にあるんだから運がわるい。妙な顔が二つ塊《かた》まっている。ほかの奴は退屈《たいくつ》にさえなるときっとこっちばかり見る。飛んだ事でと口で云うが、心のうちではこの馬鹿《ばか》がと思ってるに相違《そうい》ない。それでなければああいう風に私語合《ささやきあ》ってはくすくす笑う訳がない。教場へ出ると生徒は拍手をもって迎《むか》えた。先生|万歳《ばんざい》と云うものが二三人あった。景気がいいんだか、馬鹿にされてるんだか分からない。おれと山嵐がこんなに注意の焼点《しょうてん》となってるなかに、赤シャツばかりは平常の通り傍《そば》へ来て、どうも飛んだ災難でした。僕は君等に対してお気の毒でなりません。新聞の記事は校長とも相談して、正誤を申し込《こ》む手続きにしておいたから、心配しなくてもいい。僕の弟が堀田君を誘《さそ》いに行ったから、こんな事が起《おこ》ったので、僕は実に申し訳がない。それでこの件についてはあくまで尽力《じんりょく》するつもりだから、どうかあしからず、などと半分謝罪的な言葉を並べている。校長は三時間目に校長室から出てきて、困った事を新聞がかき出しましたね。むずかしくならなければいいがと多少心配そうに見えた。おれには心配なんかない、先で免職《めんしょく》をするなら、免職される前に辞表を出してしまうだけだ。しかし自分がわるくないのにこっちから身を引くのは法螺吹きの新聞屋をますます増長させる訳だから、新聞屋を正誤させて、おれが意地にも務めるのが順当だと考えた。帰りがけに新聞屋に談判に行こうと思ったが、学校から取消《とりけし》の手続きはしたと云うから、やめた。 413 |  おれと山嵐は校長と教頭に時間の合間を見計《みはから》って、嘘のないところを一応説明した。校長と教頭はそうだろう、新聞屋が学校に恨《うら》みを抱《いだ》いて、あんな記事をことさらに掲《かか》げたんだろうと論断した。赤シャツはおれ等の行為《こうい》を弁解しながら控所《ひかえじょ》を一人ごとに廻《まわ》ってあるいていた。ことに自分の弟が山嵐を誘い出したのを自分の過失であるかのごとく吹聴《ふいちょう》していた。みんなは全く新聞屋がわるい、怪《け》しからん、両君は実に災難だと云った。 414 |  帰りがけに山嵐は、君赤シャツは臭《くさ》いぜ、用心しないとやられるぜと注意した。どうせ臭いんだ、今日から臭くなったんじゃなかろうと云うと、君まだ気が付かないか、きのうわざわざ、僕等を誘い出して喧嘩のなかへ、捲《ま》き込《こ》んだのは策だぜと教えてくれた。なるほどそこまでは気がつかなかった。山嵐は粗暴《そぼう》なようだが、おれより智慧《ちえ》のある男だと感心した。 415 | 「ああやって喧嘩をさせておいて、すぐあとから新聞屋へ手を廻してあんな記事をかかせたんだ。実に奸物《かんぶつ》だ」 416 | 「新聞までも赤シャツか。そいつは驚いた。しかし新聞が赤シャツの云う事をそう容易《たやす》く聴《き》くかね」 417 | 「聴かなくって。新聞屋に友達が居りゃ訳はないさ」 418 | 「友達が居るのかい」 419 | 「居なくても訳ないさ。嘘をついて、事実これこれだと話しゃ、すぐ書くさ」 420 | 「ひどいもんだな。本当に赤シャツの策なら、僕等はこの事件で免職になるかも知れないね」 421 | 「わるくすると、遣《や》られるかも知れない」 422 | 「そんなら、おれは明日《あした》辞表を出してすぐ東京へ帰っちまわあ。こんな下等な所に頼《たの》んだって居るのはいやだ」 423 | 「君が辞表を出したって、赤シャツは困らない」 424 | 「それもそうだな。どうしたら困るだろう」 425 | 「あんな奸物の遣る事は、何でも証拠《しょうこ》の挙がらないように、挙がらないようにと工夫するんだから、反駁《はんばく》するのはむずかしいね」 426 | 「厄介《やっかい》だな。それじゃ濡衣《ぬれぎぬ》を着るんだね。面白《おもしろ》くもない。天道是耶非《てんどうぜかひ》かだ」 427 | 「まあ、もう二三日様子を見ようじゃないか。それでいよいよとなったら、温泉《ゆ》の町で取って抑《おさ》えるより仕方がないだろう」 428 | 「喧嘩事件は、喧嘩事件としてか」 429 | 「そうさ。こっちはこっちで向うの急所を抑えるのさ」 430 | 「それもよかろう。おれは策略は下手《へた》なんだから、万事よろしく頼む。いざとなれば何でもする」 431 |  俺と山嵐はこれで分《わか》れた。赤シャツが果《はた》たして山嵐の推察通りをやったのなら、実にひどい奴だ。到底《とうてい》智慧比べで勝てる奴ではない。どうしても腕力《わんりょく》でなくっちゃ駄目《だめ》だ。なるほど世界に戦争は絶えない訳だ。個人でも、とどの詰《つま》りは腕力だ。 432 |  あくる日、新聞のくるのを待ちかねて、披《ひら》いてみると、正誤どころか取り消しも見えない。学校へ行って狸《たぬき》に催促《さいそく》すると、あしたぐらい出すでしょうと云う。明日になって六号活字で小さく取消が出た。しかし新聞屋の方で正誤は無論しておらない。また校長に談判すると、あれより手続きのしようはないのだと云う答だ。校長なんて狸のような顔をして、いやにフロック張っているが存外無勢力なものだ。虚偽《きょぎ》の記事を掲げた田舎新聞一つ詫《あや》まらせる事が出来ない。あんまり腹が立ったから、それじゃ私が一人で行って主筆に談判すると云ったら、それはいかん、君が談判すればまた悪口を書かれるばかりだ。つまり新聞屋にかかれた事は、うそにせよ、本当にせよ、つまりどうする事も出来ないものだ。あきらめるより外に仕方がないと、坊主の説教じみた説諭《せつゆ》を加えた。新聞がそんな者なら、一日も早く打《ぶ》っ潰《つぶ》してしまった方が、われわれの利益だろう。新聞にかかれるのと、泥鼈《すっぽん》に食いつかれるとが似たり寄ったりだとは今日《こんにち》ただ今狸の説明によって始めて承知|仕《つかまつ》った。 433 |  それから三日ばかりして、ある日の午後、山嵐が憤然《ふんぜん》とやって来て、いよいよ時機が来た、おれは例の計画を断行するつもりだと云うから、そうかそれじゃおれもやろうと、即座《そくざ》に一味徒党に加盟した。ところが山嵐が、君はよす方がよかろうと首を傾《かたむ》けた。なぜと聞くと君は校長に呼ばれて辞表を出せと云われたかと尋《たず》ねるから、いや云われない。君は? と聴き返すと、今日校長室で、まことに気の毒だけれども、事情やむをえんから処決《しょけつ》してくれと云われたとの事だ。 434 | 「そんな裁判はないぜ。狸は大方|腹鼓《はらつづみ》を叩《たた》き過ぎて、胃の位置が顛倒《てんどう》したんだ。君とおれは、いっしょに、祝勝会へ出てさ、いっしょに高知のぴかぴか踴《おど》りを見てさ、いっしょに喧嘩をとめにはいったんじゃないか。辞表を出せというなら公平に両方へ出せと云うがいい。なんで田舎《いなか》の学校はそう理窟《りくつ》が分らないんだろう。焦慮《じれった》いな」 435 | 「それが赤シャツの指金《さしがね》だよ。おれと赤シャツとは今までの行懸《ゆきがか》り上|到底《とうてい》両立しない人間だが、君の方は今の通り置いても害にならないと思ってるんだ」 436 | 「おれだって赤シャツと両立するものか。害にならないと思うなんて生意気だ」 437 | 「君はあまり単純過ぎるから、置いたって、どうでも胡魔化《ごまか》されると考えてるのさ」 438 | 「なお悪いや。誰《だれ》が両立してやるものか」 439 | 「それに先だって古賀が去ってから、まだ後任が事故のために到着《とうちゃく》しないだろう。その上に君と僕を同時に追い出しちゃ、生徒の時間に明きが出来て、授業にさし支《つか》えるからな」 440 | 「それじゃおれを間《あい》のくさびに一席|伺《うかが》わせる気なんだな。こん畜生《ちくしょう》、だれがその手に乗るものか」 441 | 442 |  翌日《あくるひ》おれは学校へ出て校長室へ入って談判を始めた。 443 | 「何で私に辞表を出せと云わないんですか」 444 | 「へえ?」と狸はあっけに取られている。 445 | 「堀田には出せ、私には出さないで好《い》いと云う法がありますか」 446 | 「それは学校の方の都合《つごう》で……」 447 | 「その都合が間違《まちが》ってまさあ。私が出さなくって済むなら堀田だって、出す必要はないでしょう」 448 | 「その辺は説明が出来かねますが——堀田君は去られてもやむをえんのですが、あなたは辞表をお出しになる必要を認めませんから」 449 |  なるほど狸だ、要領を得ない事ばかり並べて、しかも落ち付き払《はら》ってる。おれは仕様がないから 450 | 「それじゃ私も辞表を出しましょう。堀田君一人辞職させて、私が安閑《あんかん》として、留まっていられると思っていらっしゃるかも知れないが、私にはそんな不人情な事は出来ません」 451 | 「それは困る。堀田も去りあなたも去ったら、学校の数学の授業がまるで出来なくなってしまうから……」 452 | 「出来なくなっても私の知った事じゃありません」 453 | 「君そう我儘《わがまま》を云うものじゃない、少しは学校の事情も察してくれなくっちゃ困る。それに、来てから一月立つか立たないのに辞職したと云うと、君の将来の履歴《りれき》に関係するから、その辺も少しは考えたらいいでしょう」 454 | 「履歴なんか構うもんですか、履歴より義理が大切です」 455 | 「そりゃごもっとも——君の云うところは一々ごもっともだが、わたしの云う方も少しは察して下さい。君が是非辞職すると云うなら辞職されてもいいから、代りのあるまでどうかやってもらいたい。とにかく、うちでもう一返考え直してみて下さい」 456 |  考え直すって、直しようのない明々白々たる理由だが、狸が蒼《あお》くなったり、赤くなったりして、可愛想《かわいそう》になったからひとまず考え直す事として引き下がった。赤シャツには口もきかなかった。どうせ遣っつけるなら塊《かた》めて、うんと遣っつける方がいい。 457 |  山嵐に狸と談判した模様を話したら、大方そんな事だろうと思った。辞表の事はいざとなるまでそのままにしておいても差支《さしつか》えあるまいとの話だったから、山嵐の云う通りにした。どうも山嵐の方がおれよりも利巧《りこう》らしいから万事山嵐の忠告に従う事にした。 458 |  山嵐はいよいよ辞表を出して、職員一同に告別の挨拶《あいさつ》をして浜《はま》の港屋まで下《さが》ったが、人に知れないように引き返して、温泉《ゆ》の町の枡屋《ますや》の表二階へ潜《ひそ》んで、障子《しょうじ》へ穴をあけて覗《のぞ》き出した。これを知ってるものはおればかりだろう。赤シャツが忍《しの》んで来ればどうせ夜だ。しかも宵《よい》の口は生徒やその他の目があるから、少なくとも九時過ぎに極《きま》ってる。最初の二晩はおれも十一時|頃《ごろ》まで張番《はりばん》をしたが、赤シャツの影《かげ》も見えない。三日目には九時から十時半まで覗いたがやはり駄目だ。駄目を踏《ふ》んで夜なかに下宿へ帰るほど馬鹿気た事はない。四五日《しごんち》すると、うちの婆さんが少々心配を始めて、奥《おく》さんのおありるのに、夜遊びはおやめたがええぞなもしと忠告した。そんな夜遊びとは夜遊びが違う。こっちのは天に代って誅戮《ちゅうりく》を加える夜遊びだ。とはいうものの一週間も通って、少しも験《げん》が見えないと、いやになるもんだ。おれは性急《せっかち》な性分だから、熱心になると徹夜《てつや》でもして仕事をするが、その代り何によらず長持ちのした試しがない。いかに天誅党でも飽《あ》きる事に変りはない。六日目には少々いやになって、七日目にはもう休もうかと思った。そこへ行くと山嵐は頑固《がんこ》なものだ。宵《よい》から十二時|過《すぎ》までは眼を障子へつけて、角屋の丸ぼやの瓦斯燈《がすとう》の下を睨《にら》めっきりである。おれが行くと今日は何人客があって、泊《とま》りが何人、女が何人といろいろな統計を示すのには驚ろいた。どうも来ないようじゃないかと云うと、うん、たしかに来るはずだがと時々|腕組《うでぐみ》をして溜息《ためいき》をつく。可愛想に、もし赤シャツがここへ一度来てくれなければ、山嵐は、生涯《しょうがい》天誅を加える事は出来ないのである。 459 |  八日目には七時頃から下宿を出て、まずゆるりと湯に入って、それから町で鶏卵《けいらん》を八つ買った。これは下宿の婆さんの芋責《いもぜめ》に応ずる策である。その玉子を四つずつ左右の袂《たもと》へ入れて、例の赤手拭《あかてぬぐい》を肩《かた》へ乗せて、懐手《ふところで》をしながら、枡屋《ますや》の楷子段《はしごだん》を登って山嵐の座敷《ざしき》の障子をあけると、おい有望有望と韋駄天《いだてん》のような顔は急に活気を呈《てい》した。昨夜《ゆうべ》までは少し塞《ふさ》ぎの気味で、はたで見ているおれさえ、陰気臭《いんきくさ》いと思ったくらいだが、この顔色を見たら、おれも急にうれしくなって、何も聞かない先から、愉快《ゆかい》愉快と云った。 460 | 「今夜七時半頃あの小鈴《こすず》と云う芸者が角屋へはいった」 461 | 「赤シャツといっしょか」 462 | 「いいや」 463 | 「それじゃ駄目だ」 464 | 「芸者は二人づれだが、——どうも有望らしい」 465 | 「どうして」 466 | 「どうしてって、ああ云う狡《ずる》い奴だから、芸者を先へよこして、後から忍んでくるかも知れない」 467 | 「そうかも知れない。もう九時だろう」 468 | 「今九時十二分ばかりだ」と帯の間からニッケル製の時計を出して見ながら云ったが「おい洋燈《らんぷ》を消せ、障子へ二つ坊主頭が写ってはおかしい。狐《きつね》はすぐ疑ぐるから」 469 |  おれは一貫張《いっかんばり》の机の上にあった置き洋燈《らんぷ》をふっと吹きけした。星明りで障子だけは少々あかるい。月はまだ出ていない。おれと山嵐は一生懸命《いっしょうけんめい》に障子へ面《かお》をつけて、息を凝《こ》らしている。チーンと九時半の柱時計が鳴った。 470 | 「おい来るだろうかな。今夜来なければ僕はもう厭《いや》だぜ」 471 | 「おれは銭のつづく限りやるんだ」 472 | 「銭っていくらあるんだい」 473 | 「今日までで八日分五円六十銭払った。いつ飛び出しても都合《つごう》のいいように毎晩|勘定《かんじょう》するんだ」 474 | 「それは手廻しがいい。宿屋で驚いてるだろう」 475 | 「宿屋はいいが、気が放せないから困る」 476 | 「その代り昼寝《ひるね》をするだろう」 477 | 「昼寝はするが、外出が出来ないんで窮屈《きゅうくつ》でたまらない」 478 | 「天誅も骨が折れるな。これで天網恢々《てんもうかいかい》疎《そ》にして洩《も》らしちまったり、何かしちゃ、つまらないぜ」 479 | 「なに今夜はきっとくるよ。——おい見ろ見ろ」と小声になったから、おれは思わずどきりとした。黒い帽子《ぼうし》を戴《いただ》いた男が、角屋の瓦斯燈を下から見上げたまま暗い方へ通り過ぎた。違っている。おやおやと思った。そのうち帳場の時計が遠慮《えんりょ》なく十時を打った。今夜もとうとう駄目らしい。 480 |  世間は大分静かになった。遊廓《ゆうかく》で鳴らす太鼓《たいこ》が手に取るように聞《きこ》える。月が温泉《ゆ》の山の後《うしろ》からのっと顔を出した。往来はあかるい。すると、下《しも》の方から人声が聞えだした。窓から首を出す訳には行かないから、姿を突《つ》き留める事は出来ないが、だんだん近づいて来る模様だ。からんからんと駒下駄《こまげた》を引き擦《ず》る音がする。眼を斜《なな》めにするとやっと二人の影法師《かげぼうし》が見えるくらいに近づいた。 481 | 「もう大丈夫《だいじょうぶ》ですね。邪魔《じゃま》ものは追っ払ったから」正《まさ》しく野だの声である。「強がるばかりで策がないから、仕様がない」これは赤シャツだ。「あの男もべらんめえに似ていますね。あのべらんめえと来たら、勇み肌《はだ》の坊《ぼ》っちゃんだから愛嬌《あいきょう》がありますよ」「増給がいやだの辞表を出したいのって、ありゃどうしても神経に異状があるに相違ない」おれは窓をあけて、二階から飛び下りて、思う様|打《ぶ》ちのめしてやろうと思ったが、やっとの事で辛防《しんぼう》した。二人はハハハハと笑いながら、瓦斯燈の下を潜《くぐ》って、角屋の中へはいった。 482 | 「おい」 483 | 「おい」 484 | 「来たぜ」 485 | 「とうとう来た」 486 | 「これでようやく安心した」 487 | 「野だの畜生、おれの事を勇み肌の坊っちゃんだと抜《ぬ》かしやがった」 488 | 「邪魔物と云うのは、おれの事だぜ。失敬千万な」 489 |  おれと山嵐は二人の帰路を要撃《ようげき》しなければならない。しかし二人はいつ出てくるか見当がつかない。山嵐は下へ行って今夜ことによると夜中に用事があって出るかも知れないから、出られるようにしておいてくれと頼《たの》んで来た。今思うと、よく宿のものが承知したものだ。大抵《たいてい》なら泥棒《どろぼう》と間違えられるところだ。 490 |  赤シャツの来るのを待ち受けたのはつらかったが、出て来るのをじっとして待ってるのはなおつらい。寝る訳には行かないし、始終障子の隙《すき》から睨めているのもつらいし、どうも、こうも心が落ちつかなくって、これほど難儀《なんぎ》な思いをした事はいまだにない。いっその事角屋へ踏み込んで現場を取って抑《おさ》えようと発議《ほつぎ》したが、山嵐は一言にして、おれの申し出を斥《しりぞ》けた。自分共が今時分飛び込んだって、乱暴者だと云って途中《とちゅう》で遮《さえぎ》られる。訳を話して面会を求めれば居ないと逃《に》げるか別室へ案内をする。不用意のところへ踏み込めると仮定したところで何十とある座敷のどこに居るか分るものではない、退屈でも出るのを待つより外に策はないと云うから、ようやくの事でとうとう朝の五時まで我慢《がまん》した。 491 |  角屋から出る二人の影を見るや否や、おれと山嵐はすぐあとを尾《つ》けた。一番汽車はまだないから、二人とも城下まであるかなければならない。温泉《ゆ》の町をはずれると一丁ばかりの杉並木《すぎなみき》があって左右は田圃《たんぼ》になる。それを通りこすとここかしこに藁葺《わらぶき》があって、畠《はたけ》の中を一筋に城下まで通る土手へ出る。町さえはずれれば、どこで追いついても構わないが、なるべくなら、人家のない、杉並木で捕《つら》まえてやろうと、見えがくれについて来た。町を外《はず》れると急に馳《か》け足《あし》の姿勢で、はやてのように後ろから、追いついた。何が来たかと驚ろいて振《ふ》り向く奴を待てと云って肩に手をかけた。野だは狼狽《ろうばい》の気味で逃げ出そうという景色《けしき》だったから、おれが前へ廻って行手を塞《ふさ》いでしまった。 492 | 「教頭の職を持ってるものが何で角屋へ行って泊《とま》った」と山嵐はすぐ詰《なじ》りかけた。 493 | 「教頭は角屋へ泊って悪《わ》るいという規則がありますか」と赤シャツは依然《いぜん》として鄭寧《ていねい》な言葉を使ってる。顔の色は少々蒼い。 494 | 「取締上《とりしまりじょう》不都合だから、蕎麦屋《そばや》や団子屋《だんごや》へさえはいってはいかんと、云うくらい謹直《きんちょく》な人が、なぜ芸者といっしょに宿屋へとまり込んだ」野だは隙を見ては逃げ出そうとするからおれはすぐ前に立ち塞がって「べらんめえの坊っちゃんた何だ」と怒鳴り付けたら、「いえ君の事を云ったんじゃないんです、全くないんです」と鉄面皮に言訳がましい事をぬかした。おれはこの時気がついてみたら、両手で自分の袂を握《にぎ》ってる。追っかける時に袂の中の卵がぶらぶらして困るから、両手で握りながら来たのである。おれはいきなり袂へ手を入れて、玉子を二つ取り出して、やっと云いながら、野だの面へ擲《たた》きつけた。玉子がぐちゃりと割れて鼻の先から黄味がだらだら流れだした。野だはよっぽど仰天《ぎょうてん》した者と見えて、わっと言いながら、尻持《しりもち》をついて、助けてくれと云った。おれは食うために玉子は買ったが、打《ぶ》つけるために袂へ入れてる訳ではない。ただ肝癪《かんしゃく》のあまりに、ついぶつけるともなしに打つけてしまったのだ。しかし野だが尻持を突いたところを見て始めて、おれの成功した事に気がついたから、こん畜生《ちくしょう》、こん畜生と云いながら残る六つを無茶苦茶に擲《たた》きつけたら、野だは顔中黄色になった。 495 |  おれが玉子をたたきつけているうち、山嵐と赤シャツはまだ談判最中である。 496 | 「芸者をつれて僕が宿屋へ泊ったと云う証拠《しょうこ》がありますか」 497 | 「宵に貴様のなじみの芸者が角屋へはいったのを見て云う事だ。胡魔化せるものか」 498 | 「胡魔化す必要はない。僕は吉川君と二人で泊ったのである。芸者が宵にはいろうが、はいるまいが、僕の知った事ではない」 499 | 「だまれ」と山嵐は拳骨《げんこつ》を食わした。赤シャツはよろよろしたが「これは乱暴だ、狼藉《ろうぜき》である。理非を弁じないで腕力に訴えるのは無法だ」 500 | 「無法でたくさんだ」とまたぽかりと撲《な》ぐる。「貴様のような奸物はなぐらなくっちゃ、答えないんだ」とぽかぽかなぐる。おれも同時に野だを散々に擲き据えた。しまいには二人とも杉の根方にうずくまって動けないのか、眼がちらちらするのか逃げようともしない。 501 | 「もうたくさんか、たくさんでなけりゃ、まだ撲《なぐ》ってやる」とぽかんぽかんと両人《ふたり》でなぐったら「もうたくさんだ」と云った。野だに「貴様もたくさんか」と聞いたら「無論たくさんだ」と答えた。 502 | 「貴様等は奸物だから、こうやって天誅を加えるんだ。これに懲《こ》りて以来つつしむがいい。いくら言葉|巧《たく》みに弁解が立っても正義は許さんぞ」と山嵐が云ったら両人共《ふたりとも》だまっていた。ことによると口をきくのが退儀《たいぎ》なのかも知れない。 503 | 「おれは逃げも隠《かく》れもせん。今夜五時までは浜の港屋に居る。用があるなら巡査《じゅんさ》なりなんなり、よこせ」と山嵐が云うから、おれも「おれも逃げも隠れもしないぞ。堀田と同じ所に待ってるから警察へ訴《うった》えたければ、勝手に訴えろ」と云って、二人してすたすたあるき出した。 504 |  おれが下宿へ帰ったのは七時少し前である。部屋へはいるとすぐ荷作りを始めたら、婆さんが驚いて、どうおしるのぞなもしと聞いた。お婆さん、東京へ行って奥さんを連れてくるんだと答えて勘定を済まして、すぐ汽車へ乗って浜へ来て港屋へ着くと、山嵐は二階で寝ていた。おれは早速辞表を書こうと思ったが、何と書いていいか分らないから、私儀《わたくしぎ》都合|有之《これあり》辞職の上東京へ帰り申候《もうしそろ》につき左様御承知被下度候《さようごしょうちくだされたくそろ》以上とかいて校長|宛《あて》にして郵便で出した。 505 |  汽船は夜六時の出帆《しゅっぱん》である。山嵐もおれも疲れて、ぐうぐう寝込んで眼が覚めたら、午後二時であった。下女に巡査は来ないかと聞いたら参りませんと答えた。「赤シャツも野だも訴えなかったなあ」と二人は大きに笑った。 506 |  その夜おれと山嵐はこの不浄《ふじょう》な地を離《はな》れた。船が岸を去れば去るほどいい心持ちがした。神戸から東京までは直行で新橋へ着いた時は、ようやく娑婆《しゃば》へ出たような気がした。山嵐とはすぐ分れたぎり今日まで逢う機会がない。 507 |  清《きよ》の事を話すのを忘れていた。——おれが東京へ着いて下宿へも行かず、革鞄《かばん》を提げたまま、清や帰ったよと飛び込んだら、あら坊っちゃん、よくまあ、早く帰って来て下さったと涙《なみだ》をぽたぽたと落した。おれもあまり嬉《うれ》しかったから、もう田舎《いなか》へは行かない、東京で清とうちを持つんだと云った。 508 |  その後ある人の周旋《しゅうせん》で街鉄《がいてつ》の技手になった。月給は二十五円で、家賃は六円だ。清は玄関《げんかん》付きの家でなくっても至極満足の様子であったが気の毒な事に今年の二月|肺炎《はいえん》に罹《かか》って死んでしまった。死ぬ前日おれを呼んで坊っちゃん後生だから清が死んだら、坊っちゃんのお寺へ埋《う》めて下さい。お墓のなかで坊っちゃんの来るのを楽しみに待っておりますと云った。だから清の墓は小日向《こびなた》の養源寺にある。 509 | [#地から1字上げ](明治三十九年四月) 510 | 511 | 512 | 513 | 底本:「ちくま日本文学全集 夏目漱石」筑摩書房 514 |    1992(平成4)年1月20日第1刷発行 515 | 底本の親本:「夏目漱石全集2」ちくま文庫、筑摩書房 516 |    1987(昭和62)年10月27日第1刷発行 517 | ※底本の注にれば、本作品の原稿には、「そのうち学校もいやになった。」の後に、漱石自身による2字あけの指定があるという。このファイルでは、その情報にもとづいて、当該の箇所を2字あけとした。 518 | ※底本は、物を数える際や地名などに用いる「ヶ」(区点番号5-86)を、大振りにつくっています。 519 | 入力:真先芳秋 520 | 校正:柳沢成雄 521 | 1999年9月13日公開 522 | 2011年5月20日修正 523 | 青空文庫作成ファイル: 524 | このファイルは、インターネットの図書館、青空文庫(http://www.aozora.gr.jp/)で作られました。入力、校正、制作にあたったのは、ボランティアの皆さんです。 525 | -------------------------------------------------------------------------------- /zlib_git/txts/helloworld.txt: -------------------------------------------------------------------------------- 1 | hello world 2 | -------------------------------------------------------------------------------- /zlib_git/zlib.c: -------------------------------------------------------------------------------- 1 | /** 2 | * zlib 圧縮・解凍するツール 3 | * 4 | * original from http://oku.edu.mie-u.ac.jp/~okumura/compression/comptest.c 5 | * licensed under http://creativecommons.org/licenses/by/4.0/ 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define INBUFSIZ 1024 13 | #define OUTBUFSIZ 1024 14 | 15 | void _compress(FILE *fin, FILE *fout) 16 | { 17 | z_stream z; 18 | char inbuf[INBUFSIZ]; 19 | char outbuf[OUTBUFSIZ]; 20 | int count, flush, status; 21 | 22 | /* すべてのメモリ管理をライブラリに任せる */ 23 | z.zalloc = Z_NULL; 24 | z.zfree = Z_NULL; 25 | z.opaque = Z_NULL; 26 | 27 | /* 初期化 */ 28 | /* 第2引数は圧縮の度合。0〜9 の範囲の整数で,0 は無圧縮 */ 29 | /* Z_DEFAULT_COMPRESSION (= 6) が標準 */ 30 | if (deflateInit(&z, Z_DEFAULT_COMPRESSION) != Z_OK) { 31 | fprintf(stderr, "deflateInit: %s\n", (z.msg) ? z.msg : "???"); 32 | exit(1); 33 | } 34 | 35 | z.avail_in = 0; /* 入力バッファ中のデータのバイト数 */ 36 | z.next_out = (Bytef *)outbuf; /* 出力ポインタ */ 37 | z.avail_out = OUTBUFSIZ; /* 出力バッファのサイズ */ 38 | 39 | /* 通常は deflate() の第2引数は Z_NO_FLUSH にして呼び出す */ 40 | flush = Z_NO_FLUSH; 41 | 42 | while (1) { 43 | if (z.avail_in == 0) { /* 入力が尽きれば */ 44 | z.next_in = (Bytef *)inbuf; /* 入力ポインタを入力バッファの先頭に */ 45 | z.avail_in = fread(inbuf, 1, INBUFSIZ, fin); /* データを読み込む */ 46 | 47 | /* 入力が最後になったら deflate() の第2引数は Z_FINISH にする */ 48 | if (z.avail_in < INBUFSIZ) flush = Z_FINISH; 49 | } 50 | status = deflate(&z, flush); /* 圧縮する */ 51 | if (status == Z_STREAM_END) break; /* 完了 */ 52 | if (status != Z_OK) { /* エラー */ 53 | fprintf(stderr, "deflate: %s\n", (z.msg) ? z.msg : "???"); 54 | exit(1); 55 | } 56 | if (z.avail_out == 0) { /* 出力バッファが尽きれば */ 57 | /* まとめて書き出す */ 58 | if (fwrite(outbuf, 1, OUTBUFSIZ, fout) != OUTBUFSIZ) { 59 | fprintf(stderr, "Write error\n"); 60 | exit(1); 61 | } 62 | z.next_out = (Bytef *)outbuf; /* 出力バッファ残量を元に戻す */ 63 | z.avail_out = OUTBUFSIZ; /* 出力ポインタを元に戻す */ 64 | } 65 | } 66 | 67 | /* 残りを吐き出す */ 68 | if ((count = OUTBUFSIZ - z.avail_out) != 0) { 69 | if (fwrite(outbuf, 1, count, fout) != count) { 70 | fprintf(stderr, "Write error\n"); 71 | exit(1); 72 | } 73 | } 74 | 75 | /* 後始末 */ 76 | if (deflateEnd(&z) != Z_OK) { 77 | fprintf(stderr, "deflateEnd: %s\n", (z.msg) ? z.msg : "???"); 78 | exit(1); 79 | } 80 | } 81 | 82 | void _decompress(FILE *fin, FILE *fout) 83 | { 84 | z_stream z; 85 | char inbuf[INBUFSIZ]; 86 | char outbuf[OUTBUFSIZ]; 87 | int count, status; 88 | 89 | /* すべてのメモリ管理をライブラリに任せる */ 90 | z.zalloc = Z_NULL; 91 | z.zfree = Z_NULL; 92 | z.opaque = Z_NULL; 93 | 94 | /* 初期化 */ 95 | z.next_in = Z_NULL; 96 | z.avail_in = 0; 97 | if (inflateInit(&z) != Z_OK) { 98 | fprintf(stderr, "inflateInit: %s\n", (z.msg) ? z.msg : "???"); 99 | exit(1); 100 | } 101 | 102 | z.next_out = (Bytef *)outbuf; /* 出力ポインタ */ 103 | z.avail_out = OUTBUFSIZ; /* 出力バッファ残量 */ 104 | status = Z_OK; 105 | 106 | while (status != Z_STREAM_END) { 107 | if (z.avail_in == 0) { /* 入力残量がゼロになれば */ 108 | z.next_in = (Bytef *)inbuf; /* 入力ポインタを元に戻す */ 109 | z.avail_in = fread(inbuf, 1, INBUFSIZ, fin); /* データを読む */ 110 | } 111 | status = inflate(&z, Z_NO_FLUSH); /* 展開 */ 112 | if (status == Z_STREAM_END) break; /* 完了 */ 113 | if (status != Z_OK) { /* エラー */ 114 | fprintf(stderr, "inflate: %s\n", (z.msg) ? z.msg : "???"); 115 | exit(1); 116 | } 117 | if (z.avail_out == 0) { /* 出力バッファが尽きれば */ 118 | /* まとめて書き出す */ 119 | if (fwrite(outbuf, 1, OUTBUFSIZ, fout) != OUTBUFSIZ) { 120 | fprintf(stderr, "Write error\n"); 121 | exit(1); 122 | } 123 | z.next_out = (Bytef *)outbuf; /* 出力ポインタを元に戻す */ 124 | z.avail_out = OUTBUFSIZ; /* 出力バッファ残量を元に戻す */ 125 | } 126 | } 127 | 128 | /* 残りを吐き出す */ 129 | if ((count = OUTBUFSIZ - z.avail_out) != 0) { 130 | if (fwrite(outbuf, 1, count, fout) != count) { 131 | fprintf(stderr, "Write error\n"); 132 | exit(1); 133 | } 134 | } 135 | 136 | /* 後始末 */ 137 | if (inflateEnd(&z) != Z_OK) { 138 | fprintf(stderr, "inflateEnd: %s\n", (z.msg) ? z.msg : "???"); 139 | exit(1); 140 | } 141 | } 142 | 143 | void usage() 144 | { 145 | fprintf(stderr, "Usage:\n"); 146 | fprintf(stderr, " zlib -c in_file out_file\n"); 147 | fprintf(stderr, " zlib -d in_file out_file\n"); 148 | } 149 | 150 | int main(int argc, char *argv[]) 151 | { 152 | int c; 153 | FILE *fin, *fout; 154 | 155 | if (argc == 1) { 156 | usage(); 157 | exit(0); 158 | } 159 | 160 | if (strcmp(argv[1],"-c") == 0) { 161 | c = 1; 162 | } else if (strcmp(argv[1], "-d") == 0) { 163 | c = 0; 164 | } else { 165 | usage(); 166 | exit(0); 167 | } 168 | 169 | if ((fin = fopen(argv[2], "r")) == NULL) { 170 | fprintf(stderr, "Can't open %s\n", argv[2]); 171 | exit(1); 172 | } 173 | if ((fout = fopen(argv[3], "w")) == NULL) { 174 | fprintf(stderr, "Can't open %s\n", argv[3]); 175 | exit(1); 176 | } 177 | if (c) { 178 | _compress(fin, fout); 179 | } else { 180 | _decompress(fin, fout); 181 | } 182 | 183 | fclose(fin); 184 | fclose(fout); 185 | return 0; 186 | } 187 | --------------------------------------------------------------------------------