プログラムについて実際のプログラムはこちらです。このリンクは新しいブラウザウィンドウを開きます。このプログラムは著作権フリーとします。このプログラムを使用することによるいかなる損害にも関知しません。動作確認はリムネットだけです。他のプロバイダでは確認してません。このプログラムを使用するときには拡張子をcにしてください。画像の出力まずいきなり、画像を出力します。今回のCGIは画像を出力することに意味はないからです。ここでは1ドットの透明GIFを出力しています。渡された引数ですが、実はこのままでは使えません。渡された文字列にはエスケープシーケンスが入っている可能性があります。文字列の中に~とか|が入っていた場合には、\~とか\|に置き換えられています。そのため、このエスケープシーケンスを削除する必要があります。そのための関数がDelYen()です。一文字ずつチェックして渡すというちょっとベタな方法を取っています。URLのサーチURLの処理が終わったら、IncCount()に移ります。この関数はアクセスカウンターの同名の関数と似たような実装をしています。データの入ったファイルを開いてロックを掛けるところまでと、ロックを外した後はほとんど同じです。fseek()がうまく動かないようです。この問題についての情報を知っている、もしくはプログラムバグが見つかったという方はぜひお知らせください!!)ロックした後は、まずUrlSearch()で同じURLがあるかチェックします。この関数はまずfscanf()で単語を取得していきます。「単語」とは「スペースか改行で区切られた文字列」のことです。この場合には「URL・カウント・URL・カウンター......」という順に取得されていきます。取得された単語はstrcmp()で一致するかチェックします。URLはUNIXのパスなので、大文字小文字を区別する必要があります。一致したらftell()で現在のファイルポインタの位置を取得します。fscanf()は単語ごとに読み、その都度ファイルポインタを進めていきます。000001であれば、最初のURLをfscanf()で読み込んだとき、ファイルポインタは間のスペース(/と0の間)に来ています。次に読み込んだら、最後の改行に来ます。ftell()はその「ファイルの先頭からのファイルポインタの位置」を取得します。このファイルポインタは、のちほどカウント数の書き込み時に利用します。ファイルポインタの位置を取得したら、もう一度fscanf()を使ってカウント数を読み込み、UrlSearch()から返ります。このとき、先ほど取得した「ファイルポインタの位置」を返します。第1引数の文字列を使ってカウント数を返します。検索に引っかかることなくファイルの最後まで来たときには、0を返してUrlSearch()から返ります。「桁数固定」のワケIncCount()に戻ってからはデータの書き込みです。UrlSearch()から0が返ってきたときには「URLが見つからなかった」ということなので、ファイルの最後にURLとカウントを追加します。fseek()はファイルポインタを移動する関数です。第2引数は移動する量、第3引数はフラグで、2をセットするとファイルの最後に移動します。ここでは第2引数は0なので、単にファイルの最後に移動するということになります。カウント数(改行)」と書き込みます。このとき、最初のカウント数は1になるわけですが、このプログラムでは「000001」という6桁の文字列にしています。前述しているように、このデータは必ず6桁の文字列として扱っています。この説明はもーちょっと待ってください。「URLが見つからなかった場合」にはこれでプログラムが終了します。「URLが見つかった場合」には、UrlSearch()で返されたカウント数とファイルポインタを用いてカウント数を更新します。カウント数の増加はIncTextCount()で行います。ここではカウント数を「文字列」のまま増やします。atoi()を使わない理由は、000001という値だとエラーが発生して0が返ってきてしまう、つまりちゃんと変換されないためです。カウントの増加は1桁目(文字列で言えば最後の文字)からチェックし、「くりあがり」がありかつ数字が9の時のみ0にして「くりあがり」をセット、それ以外はその文字に1を加えます(文字コードは0が0x30、1が0x31、2が0x32と並んでいるのでこういうことができるのです)。ちなみに最初の一桁には「くりあがり」をセットしておくことでプログラムを簡略化してます。カウントを増やしたら、ファイルに書き込む前にファイルポインタを移動させます。このとき、先ほど取得した「ファイルポインタのファイルの先頭からの位置」が役に立ちます。fseek()の第3引数に0をセットすると、「ファイルの先頭から」という意味になります。そこで第2引数に先ほどの「ファイルポインタの位置」を渡すことで、「URLとカウント数の間のスペース」にファイルポインタを移動できるわけです。カウント数(改行)」と書き込みます。最初のスペースに注意してください。ファイルポインタがスペースにあるので、そのスペースを上書きする必要があるというわけです。上書きしたら、これでプログラムが終了します。ここで「000001」の理由を説明しましょう。ファイルへの書き込みは、基本的に上書きです。挿入はできないというわけです。これは非常に大きな問題です。「ファイルへの挿入」を実現するのは非常に難しいことです。一時ファイルを作製してコピーしたり、データをすべて読み込んだり、ファイルの中のデータをひとつずつずらすといったことをしなければなりません。なると、プログラムの難易度が飛躍的にアップします。そこで、上書きでもOKな形にしようということで、桁数を固定にしたというわけです。この規則のために、数値計算を行わず文字列として処理し、ただの「1」も「000001」として書き込んでいたわけです。桁数は、START_COUNTでの0の数を変えることで簡単に変更できます。START_COUNT"001"なら3桁で処理されます。他の部分で手を加える必要はありません(もちろんデータファイルの形式は変わってしまうので、ずーっと同じファイルを使っている場合には問題が出てきますが)。応用範囲の広いCGIこのアクセスログ、何もアクセスログにだけ使う必要はありません。このCGIは「渡された文字列をカウントする」ものです。「文字列」はなにもURLである必要はありません。JAVAスクリプトと組み合わせることで様々なログを取ることができます。これについては次回に解説する予定です。今回のCGIはイメージのログを取ることができませんが、このCGIに直接イメージを表示させるようにすれば、イメージのログも取ることができます。画像ファイルのダウンロードをメインとしてるホームページはこういったCGIを作ってみてはいかがでしょう。