Cockatrice-2.1 オンラインマニュアル

はじめに

ここでは、C 言語用 CGI プログラミングライブラリ Cockatrice の使用方法について説明します。 デフォルトでのインストールでは、 必要なヘッダファイルとライブラリは以下のような構成で導入されます。

  /usr/local/include/cockatrice.h
  /usr/local/lib/libcgi.a
  /usr/local/lib/libcgi.so.2

  /usr/local/include/catoblepas.h
  /usr/local/lib/libcatoblepas.a
  /usr/local/lib/libcatoblepas.so.1

  /usr/local/include/basilisk.h
  /usr/local/lib/libbasilisk.a
  /usr/local/lib/libbasilisk.so.1

上記構成において、 Cockatrice が CGI プログラミング用ライブラリで、 Catoblepas と Basilisk が HTML 作成支援ライブラリです。 Catoblepas は HTML 4.01 を Basilisk が HTML 2.0 と 3.2 用です。 Cockatrice-2.0 以降、CGI プログラミング部分と HTML Authoring 支援機能を分離したので、上記のような構成となりました。

使用方法

基本的な使用方法におけるソースコード

Cockatrice のみを利用


  #include <stdio.h>
  #include <cockatrice.h>

  int main(int argc, char * argv[])
  {
    CGI * cgi;
	
    cgi = newCGI(CC_MODULE_STANDARD);
    cgi->header("text/plain");
    fprintf(stdout, "Hello, World!");
    cgi->done();

    return 0;
  }

Cockatrice と Catoblepas を利用


  #include <stdio.h>
  #include <cockatrice.h>
  #include <catoblepas.h>

  int main(int argc, char * argv[])
  {
    CGI * cgi;
    HTML * html;

    cgi  = newCGI(CC_MODULE_STANDARD);
    html = newHTML401(HTML4_Strict);

    cgi->header("text/html");

    html->html.begin();
      html->head.begin();
        html->title("WEB PAGE TITLE");
      html->head.end();
      html->body.begin();
	html->p.begin();
	  html->print("Hello, World!");
	html->p.end();
      html->body.end();
    html->html.end();

    html->done();
    cgi->done();

    return 0;
  }

Cockatrice の使用

CGI * newCGI(int modules);

Cockatrice を使用するには、必ず newCGI() を呼び出します。 引数 modules はライブラリで使用したい拡張モジュールを指定します。 現在、利用可能な拡張モジュールは次のいずれかの組み合わせです。

CC_MODULE_FILEファイルロック制御機能を提供
CC_MODULE_ENV環境変数アクセス機能を提供
CC_MODULE_DATE日付時刻取得機能を提供
CC_MODULE_CHECK文字列チェック機能を提供
CC_MODULE_SESSIONセッション管理機能を提供
CC_MODULE_SQLITE3SQLite3 データベース機能を提供
CC_MODULE_PGSQL8PostgreSQL データベース機能を提供
CC_MODULE_STANDARD標準機能のみを利用

  int main(int argc, char * argv[])
  {
    CGI * cgi;
    ...
    cgi = newCGI(CC_MODULE_DATE | CC_MODULE_SQLITE3);
    ...
    cgi->done();

    return 0;
  }

CGI パラメータの取得

char * cgi->param(char * name);

"name" で指定する CGI パラメータを取得します。 成功した場合は、値を文字列で返します。 失敗した場合は、NULL を返します。

たとえば、次のようなフォームを考えます。


  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  <html>
  <head>
  ...
  </head>
  <body>
    <form action="/cgi-bin/test.cgi" method="post">
      Name: <input type="text" name="name" value="Your Name">
      E-Mail: <input type="text" name="email" value="Your E-Mail">
      ...
    </form>
  </body>
  </html>

上記フォームではパラメータとして、名前と電子メールアドレスを記入してもらいます。

CGI ライブラリでは、次のようにしてパラメータを取得します。


  cgi->param("name");
  cgi->param("email");

つまり、input タグの name 属性で指定した名前を param() の引数として取り出すことができます。 この例では、POST メソッドを利用していますが、GET メソッドでも同様の方法です。

cgi->param() の返す値は、文字列ですので、


  fprintf(stdout, "Input value: %s\n", cgi->param("email"));

では、入力された電子メールアドレスが表示されます。

VList * cgi->params(char * name);

"name" で指定する CGI パラメータを取得します。 成功した場合は、VList へのポインタを返します。 失敗した場合は、NULL を返します。 checkbox などの複数の選択値を使用する場合に利用します。

たとえば、次のようなフォームを考えます。


  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  <html>
  <head>
  ...
  </head>
  <body>
    <form action="/cgi-bin/checkbox.cgi" method="post">
    <table border="0">
      <tr>
        <td><input type="checkbox" name="fruits" value="苺">いちご</td>
      </tr>
      <tr>
        <td><input type="checkbox" name="fruits" value="林檎">りんご</td>
      </tr>
      <tr>
        <td><input type="checkbox" name="fruits" value="蜜柑">みかん</td>
      </tr>
      <tr>
        <td><input type="checkbox" name="fruits" value="葡萄">ぶどう</td>
      </tr>
      <tr>
        <td><input type="checkbox" name="fruits" value="桃">もも</td>
      </tr>
      <tr>
        <td><input type="checkbox" name="fruits" value="梨">なし</td>
      </tr>
      <tr>
        <td><input type="checkbox" name="fruits" value="柿">かき</td>
      </tr>
    </table>
    ...
    </form>
  </body>
  </html>

上記フォームでは果物の名前を好きなだけ選択できます。 Cockatrice では、次のようにしてパラメータを取得します。


  VList * vp;

  for (vp = cgi->params("fruits"); vp != NULL; vp = vp->next) {
    fprintf(stdout, "Fruit: %s\n", vp->value);
  }

Cookie の使用

パラメータの取得

char * cgi->cookie->get(char * name);

"name" で指定した Cookie のパラメータ(NAME=VALUE)を取得します。 cgi->cookie->get("NAME") とすれば、 NAME に設定された VALUE を文字列として返します。

パラメータの設定

void cgi->cookie->setName(char * name, char * value);

Cookie の NAME=VALUE を設定します。 (例)cgi->cookie->setName("NAME", "阿部康一");

void cgi->cookie->setComment(char * name, char * comment);

Cookie のコメントを設定します。 デフォルトは、コメントなしです。 (例)cgi->cookie->setComment("NAME", "Cookie に関する説明");

void cgi->cookie->setDomain(char * name, char * domain);

Cookie のドメインを設定します。 デフォルトは、アクセスしたサーバのドメインになります。 (例)cgi->cookie->setDomain("NAME", "MysticWALL.COM");

void cgi->cookie->setMaxAge(char * name, unsigned int max_age);

Cookie の有効期限を設定します。 デフォルトは、即失効(つまり、キャッシュされない)になります。 引数は、秒です。以下の例は、10分間の有効期限を表します。 (例)cgi->cookie->setMaxAge("NAME", 600);

void cgi->cookie->setPath(char * name, char * path);

Cookie の有効パスを設定します。 デフォルトは、無指定(つまり、ブラウザにお任せ)になります。 (例)cgi->cookie->setPath("NAME", "/database");

void cgi->cookie->setSecure(char * name, bool secure);

Cookie が安全かを設定します。 デフォルトは、Non-Secure です。 (例)cgi->cookie->setSecure("NAME", true);

void cgi->cookie->setCommentURL(char * name, char * commentrURL);

Cookie 発行元に Cookie を使ったセッションの初期化や継続について指示する。 RFC 2965 で追加されたパラメータ。

void cgi->cookie->setDiscard(char * name, bool discard);

ユーザエージェント(つまり、ブラウザ)終了時、Cookie を破棄させるか設定する。 デフォルトは、破棄させない。 RFC 2965 で追加されたパラメータ。

void cgi->cookie->setPort(char * name, char * port);

Cookie が戻されるポートを制限します。 RFC 2965 で追加されたパラメータ。

アップロードファイルの操作

FORM の FILE タイプを利用したアップロードファイルの操作には、 cgi->upload->open()、cgi->upload->store()、 cgi->upload->digest() を利用します。

アップロードファイルのオープン

FILE * cgi->upload->open(char * filename);

アップロードされたファイルをオープンして、操作できます。 fclose() した場合は、その後のアクセスは不能となります。 成功した場合にはファイルポインタを、失敗した場合には NULL を返します。

アップロードファイルの保存

int cgi->upload->store(char * name, char * filename);

アップロードファイルを指定されたファイル名で保存します。 成功した場合には 0 を、失敗した場合には -1 を返します。 一般的な、ファイルアップロードのための HTML ファイルは、 以下のような構造となります。


  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  <html>
  <head>
  ...
  </head>
  <body>
    <form action="/cgi-bin/upload.cgi" method="post" type="multipart/form-data">
      Name: <input type="text" name="name" value="Your Name">
      E-Mail: <input type="text" name="email" value="Your E-Mail">
      File1: <input type="file" name="fname1" value="Attached Filename1">
      File2: <input type="file" name="fname2" value="Attached Filename2">
      ...
    </form>
  </body>
  </html>

CGI プログラムでは、 次のようにしてアップロードされたファイルにアクセスします。 アップロードされたファイルを保存するには、 次のようなコードを書きます。ただし、概要だけのコードです。


  #include <stdio.h>
  #include <cockatrice.h>

  int main(int argc, char * argv[])
  {
    CGI * cgi;

    cgi = newCGI(CC_MODULE_STANDARD);
    ...
    cgi->upload->store("fname1", "upload1.txt");
    cgi->upload->store("fname2", "upload2.txt");
    ...
    cgi->done();
    ...
    return 0;
  }

アップロードファイルのダイジェスト(MD5/SHA1/SHA256/RMD160)

char * cgi->upload->digest(char * filename, digest_t type);

アップロードファイルのダイジェストを計算します。 ファイルの整合性などの検査に利用できます。 digest_t には、次のいずれか一つを指定できます。

  • CC_DIGEST_MD5
  • CC_DIGEST_SHA1
  • CC_DIGEST_SHA256
  • CC_DIGEST_RMD160

成功した場合には指定したアルゴリズムでのダイジェストの値を、 失敗した場合には NULL を返します。

URI のエスケープ/アンエスケープ

char * cgi->uri->escape(char * uri);

URI に用いることができない記号や日本語を %nn の形式にエンコードします。

char * cgi->uri->unescape(char * uri);

URI エンコードされた文字列をデコードします。

例えば、"かべちゃん" は、"%A4%AB%A4%D9%A4%C1%A4%E3%A4%F3" に変換されます。 この例では、漢字コードは日本語 EUC コードです。


  cgi->uri->escape("かべちゃん");
  cgi->uri->unescape("%A4%AB%A4%D9%A4%C1%A4%E3%A4%F3");

文字列のダイジェスト(MD5/SHA1/SHA256/RMD160)

char * cgi->util->digest(char * string, digest_t type);

文字列のダイジェストを計算します。 ダイジェストを利用したパスワードの整合性などの検査に利用できます。 digest_t には、次のいずれか一つを指定できます。

  • CC_DIGEST_MD5
  • CC_DIGEST_SHA1
  • CC_DIGEST_SHA256
  • CC_DIGEST_RMD160

文字列のコードを日本語 EUC コードに変換

char * cgi->util->conv_any2euc(const char * inbuf, size_t insize, char * outbuf, size_t outsize);

任意の文字列の文字コードを日本語 EUC コード(EUC-JP)に変換します。 wkf をリンクしている場合は、 入力文字列は JIS, Shift-JIS, EUC-JP のいずれかを自動判断して変換します。 iconv をリンクしている場合は、 入力文字列は JIS, Shift-JIS, EUC-JP, UTF-8, UTF-16, UTF-32 のいずれかを自動判断して変換します。

モジュールによる機能拡張

文字列検査

利用する場合は、newCGI() で CC_MODULE_CHECK を指定する必要があります。


  CGI * cgi = newCGI(CC_MODULE_CHECK);

int cgi->check->empty(const char * string);
引数の文字列が空かどうかチェックします。 空文字列の場合は 0 を、そうでない場合は -1 を返します。
int cgi->check->digit(const char * string);
引数の文字列が数字かどうかチェックします。 数字の場合は 0 を、そうでない場合は -1 を返します。
int cgi->check->alphabet(const char * string);
引数の文字列がアルファベットかどうかチェックします。 アルファベットの場合は 0 を、そうでない場合は -1 を返します。
int cgi->check->username(const char * string);
引数の文字列がユーザ名かどうかチェックします。 ユーザ名の場合は 0 を、そうでない場合は -1 を返します。 ユーザ名は '^[a-z][a-z0-9]+$' の正規表現にマッチする文字列です。
int cgi->check->hostname(const char * string);
引数の文字列がホスト名かどうかチェックします。 ホスト名の場合は 0 を、そうでない場合は -1 を返します。 ホスト名は '^[a-zA-Z][a-zA-Z0-9]+$' の正規表現にマッチする文字列です。
int cgi->check->domainname(const char * string);
引数の文字列がドメイン名かどうかチェックします。 ドメイン名の場合は 0 を、そうでない場合は -1 を返します。 ドメイン名は '^[a-zA-Z0-9][a-zA-Z0-9-.]*[a-zA-Z0-9]+$' の正規表現にマッチする文字列です。
int cgi->check->email(const char * string);
引数の文字列がメールアドレスかどうかチェックします。 メールアドレスの場合は 0 を、そうでない場合は -1 を返します。 メールアドレスは '^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]+@<ドメイン名>' の正規表現にマッチする文字列です。
int cgi->check->range(const char * string, int min, int max);
cgi->check.range(param, 0, 100); のように使用し、引数 param が数字で、 かつその値が 0 〜 100 の間であるならば 0 を返します。 そうでない場合は、-1 を返します。 範囲の検査は、0 ≦ param ≦ 100 です。
int cgi->check->ipaddr(const char * string);
引数の文字列が IP アドレスかどうか調べます。IP アドレスの場合は 0 を、 そうでない場合は -1 を返します。 IP アドレスの形式は、aaa.bbb.ccc.ddd です。
int cgi->check->ipaddr2(const char * string);
引数の文字列がマスク長付き IP アドレスかどうか調べます。 マスク長付き IP アドレスの場合は 0 を、そうでない場合は -1 を返します。 マスク長付き IP アドレスの形式は、aaa.bbb.ccc.ddd/mm です。
int cgi->check->ipaddr3(const char * string);
引数の文字列がポート番号付き IP アドレスかどうか調べます。 ポート番号付き IP アドレスの場合は 0 を、そうでない場合は -1 を返します。 ポート番号付き IP アドレスの形式は、aaa.bbb.ccc.ddd:pp です。

日付と時刻

Cockatrice では、カレンダー作成を目的とした日付と時刻に関する API を提供します。 利用する場合は、newCGI() で CC_MODULE_DATE を指定する必要があります。


  CGI * cgi = newCGI(CC_MODULE_DATE);

char * cgi->date->today(void);
現在の日付を"2001/02/03(Sat)"形式で返します。
char * cgi->date->time(void);
現在の時刻を"23:58:10"形式で返します。
int cgi->date->year(void);
今日の西暦を返します。
int cgi->date->month(void);
今日の月を返します。
int cgi->date->day(void);
今日の日を返します。
int cgi->date->wday(void);
今日の曜日を "0" 〜 "6" の値でを返します。 日曜日は "0" で土曜日が "6" です。
bool cgi->date->isFestival(int year, int month, int day);
西暦、月、日を引数に取り、祝日であれば true を返します。 違う場合は、false を返します。 祝日は、2007年8月20日現在の日本国の祝日に限定されています。
char * cgi->date->getFestivalName(int year, int month, int day);
西暦、月、日を引数に取り、祝日であれば祝日の名称を返します。 違う場合は、NULL を返します。 祝日は、2007年8月20日現在の日本国の祝日に限定されています。
bool cgi->date->isHolidayInLieu(int year, int month, int day);
西暦、月、日を引数に取り、 振替休日であれば true を返します。違う場合は、false を返します。 振替休日は、2007年8月20日現在の日本国の祝日を元に計算されています。
int cgi->date->getDayOfTheWeek(int year, int month, int day);
西暦、月、日を引数に取り、 曜日を "0" から "6"の値で返します。 日曜日は "0" で土曜日が "6" です。
bool cgi->date->check(int year, int month, int day);
西暦、月、日を引数に取り、年月日として有効かを判断します。 有効な値の場合は、true を返します。無効の場合は、false を返します。
const char * cgi->date->getRokuyou(int year, int month, int day);
西暦、月、日を引数に取り、六曜を返します。 六曜は、"先勝", "友引", 先負", "仏滅", 大安", 赤口" です。
const char * cgi->date->get24Sekki(int year, int month, int day);

西暦、月、日を引数に取り、二十四節気を返します。 二十四節気は、"春分", "清明", "穀雨", "立夏", "小満", "芒種", "夏至", "小暑", "大暑", "立秋", "処暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至", "小寒", "大寒", "立春", "雨水", "啓蟄" です。

int cgi->date->getOldCalendar(int year, int month, int day, int * result);
西暦、月、日を引数に取り、result 変数に旧暦を返します。 旧暦の計算に成功した場合は、0 を返します。 それ以外は、-1 を返します。

環境変数の取得

利用する場合は、newCGI() で CC_MODULE_ENV を指定する必要があります。


  CGI * cgi = newCGI(CC_MODULE_ENV);

環境変数の取得には、 cgi->env->get("REMOTE_HOST"); のように char * cgi->env->get(char * name) を利用します。

また、ウェブサーバで設定される主な環境変数は、 次の関数によって取得可能です。 ただし、CGI スクリプト名だけは、cgi->script_name でもアクセスできます。

  • const char * cgi->env->server_software();
  • const char * cgi->env->server_name();
  • const char * cgi->env->gateway_interface();
  • const char * cgi->env->server_protocol();
  • int cgi->env->server_port();
  • const char * cgi->env->request_method();
  • const char * cgi->env->script_name();
  • const char * cgi->env->path_info();
  • const char * cgi->env->path_translated();
  • const char * cgi->env->remote_host();
  • const char * cgi->env->remote_addr();
  • int cgi->env->remote_port();
  • const char * cgi->env->auth_type();
  • const char * cgi->env->remote_user();
  • const char * cgi->env->remote_ident();
  • const char * cgi->env->accept();
  • const char * cgi->env->accept_encoding();
  • const char * cgi->env->accept_language();
  • const char * cgi->env->user_agent();
  • const char * cgi->env->referer();
  • const char * cgi->env->document_root();
  • const char * cgi->env->server_root();
  • const char * cgi->env->server_admin();

ファイルのロック

利用する場合は、newCGI() で CC_MODULE_FILE を指定する必要があります。


  CGI * cgi = newCGI(CC_MODULE_FILE);

電子掲示板システムなどのような、ファイルの書き込みを排他制御する 必要がある CGI プログラムで、ファイルをロックしたい場合には、 cgi->util->lock() / cgi->util->unlock() を利用します。

int cgi->util->lock(char * filename);
ロックに成功した場合に、0 を返します。失敗時には -1 を返します。
int cgi->util->unlock(char * filename);
ロックの解除に成功した場合に、0 を返します。失敗時には -1 を返します。

  cgi->util->lock("/home/kouichi/public_html/bbs.db");
  cgi->util->unlock("/home/kouichi/public_html/bbs.db");

セッション管理

Cockatrice では簡単なセッション管理機能を提供します。
利用する場合は、newCGI() で CC_MODULE_SESSION を指定する必要があります。


  CGI * cgi = newCGI(CC_MODULE_SESSION);

セッションID の生成と破棄

char * cgi->session->open(const char * name, long expiry);
Cockatrice のセッション管理を利用するには、cgi->session->open() を使ってセッションを開きます。 引数には、セッション名とセッションの有効期間(分単位)を指定します。 オープンに成功した場合は新しいセッションID を、失敗した場合には NULL を返します。
int cgi->session->close(const char * name, const char * id);
引数で指定したセッション名のセッションID を破棄します。 成功した場合には 0 を、失敗した場合には -1 を返します。

セッションIDの検査

int cgi->session->validate_id(const char * name, const char * id);
セッション名で管理されているセッションID が有効かどうかを検査します。 有効なセッションID の場合は 0 を、期限が切れた場合は 1 を、 そうでない場合は -1 を返します。

セッションIDの削除

int cgi->session->delete_id(const char * name, const char * id);
通常は、session->close() 時に自動的に削除されますが、 session->delete_id() を利用すれば有効期間内のセッションID を削除できます。 セッションIDの削除に成功した場合は 0 を、失敗した場合には -1 を返します。

セッションIDの有効期限の取得

long cgi->session->get_expire(const char * name, const char * id);
セッション名で管理されたセッションID の有効期限を取得します。 成功した場合は、1970-01-01 00:00:00 からの秒数で有効期限を返します。 エラーの場合は -1 を返します。

データベース操作機能

Cockatrice では SQLite3PostgreSQL を使った簡単なデータベース操作機能を提供します。 現在の実装では、同時に複数のデータベースを操作できません。
利用する場合は、newCGI() で CC_MODULE_SQLITE3 か CC_MODULE_PGSQL8 を指定する必要があります。


  CGI * cgi = newCGI(CC_MODULE_SQLITE3);

int cgi->database->open(const char * dbname);

SQLite の場合、 引数 dbname で指定した SQLite3 データベースをオープンします。 PostgreSQL の場合は、dbname で指定された文字列は、 PQconnectdb() への引数となります。 成功した場合は 0 を、失敗した場合は -1 を返します。


  CGI * cgi = newCGI(CC_MODULE_PGSQL8);
  ...
  cgi->database->open("dbname=access_log connect_timeout=10");

int cgi->database->close(void);

SQLite の場合は、データベースをクローズします。 PostgreSQL の場合は、サーバとの接続を切断します。

int cgi->database->exec(const char * sql_statement);

引数 sql_statement で指定した SQL 文を実行します。 INSERT や UPDATE 命令では、この API を利用します。 成功した場合は 0 を、失敗した場合は -1 を返します。

int cgi->database->query(const char * sql_statement);

引数 sql_statement で指定した SQL 文を実行します。 SELECT 命令では、この API を利用します。 成功した場合は 0 を、失敗した場合は -1 を返します。

int cgi->database->fetch(const char *** results);

cgi->database->query() が成功した場合、 本 API を呼び出すと引数 results に column 毎の結果が一式返ります。 成功した場合は 0 を、失敗した場合は -1 を返します。

char * cgi->database->quote(const char * sql_statement);

引数 sql_statement で指定した SQL 文の "single quote" を quote した結果を返します。 新たにメモリ領域を割り当てますので、 使用後は free(3) を使ってメモリ領域を解放してください。

その他

レスポンスヘッダの送信(データ送信)

void cgi->header(const char * content_type);
CGI ライブラリを利用して作成したデータを送信する場合は、 cgi->header() を利用します。Content-Type を引数に取ります。 cgi->header("text/html; charset=EUC-JP"); Cookie が設定されている場合は、 適切な HTTP ヘッダを生成してクライアントに送信します。

リダイレクト

void cgi->redirect(const char * url);

URL を引数に取り、レスポンスコード 302 の応答で、 Location フィールドを返します。


  cgi->redirect("http://www.MysticWALL.COM/index-j.html");

上記の出力は、


  Status: 302 Moved[CRLF]
  Location: http://www.MysticWALL.COM/index-j.html[CRLF]
  [CRLF]

となります。[CRLF] は明示的に表現しているだけです。

CGI ライブラリの使用終了

void cgi->done(void);

CGI ライブラリの使用を終了するには、done() を呼び出します。 ライブラリの終了時には、必ず呼び出すようにしてください。

また、シグナルハンドラの実装の際には、そこで即終了する場合は問題ないですが、 プログラムの実行を継続する場合には、必ず呼び出すようにしてください。

CGI プログラムのコンパイル

基本的な使い方は、ソースコードに次の一行を書き、
#include <cockatrice.h> コンパイル時に cockatrice と md ライブラリをリンクします。 漢字コード変換ライブラリ wkf を利用する場合は、 wkf ライブラリも一緒にリンクします。 文字コード変換ライブラリが導入されている環境では、 wkf ライブラリの代わりに iconv ライブラリをリンクします。

例えば、環境変数の一覧表示プログラムの場合は、 次のようなソースコードになります。ファイル名は、printenv.c とします。


  #include <stdio.h>
  #include <stdlib.h>
  #include <unistd.h>
  #include <string.h>
  #include <cockatrice.h>
  #include <catoblepas.h>

  int main(int argc, char * argv[])
  {
    CGI * cgi;

    cgi = newCGI(CC_MODULE_STANDARD);
    if (cgi) {
      HTML * html;

      html = newHTML401(HTML4_Transitional);
      if (html) {
        extern char ** environ;
        char ** ep;

        cgi->header("text/html");

        html->html.attr.lang = "ja";
        html->html.begin();
        html->head.begin();
        html->title("Environment Variables");
        html->head.end();

        html->body.begin();
        html->div.attr.trans.align = ALIGN_CENTER;
        html->div.begin();
          html->table.attr.border = 1;
          html->table.begin();
          for (ep = environ; *ep; ep++) {
            String key;
            String value;

            key = *ep;
            value = (String)strchr(key, '=');
            if (value != NULL) {
              *value++ = EOL;
            }
            html->tr.begin();
              html->td.begin();
                html->print(key);
              html->td.end();
              html->td.begin();
                html->printe(value);
              html->td.end();
            html->tr.end();
          }
          html->table.end();
        html->div.end();
        html->body.end();
        html->html.end();

        html->done();
      }
      cgi->done();
    }

    return 0;
  }

上記のソースコードのコンパイルは次のようにします。 '%' はシェルプロンプトです。

  % gcc -o printenv.cgi -I/usr/local/include -L/usr/local/lib printenv.c
    -lcockatrice -lcatoblepas -lwkf -lmd

コンパイル後の使用方法は、次のようになります。

  % w3m http://localhost/cgi-bin/printenv.cgi

以下は、表示例です。

PATH/bin:/usr/bin:/usr/local/bin
SERVER_SOFTWAREWyvern/2.0.8
GATEWAY_INTERFACECGI/1.1
SERVER_PROTOCOLHTTP/1.0
SERVER_PORT80
SERVER_ROOT/usr/local/wyvern
SERVER_NAMEswordfish.MysticWALL.COM
SERVER_ADMINkouichi@MysticWALL.COM
DOCUMENT_ROOT/home/kouichi/MysticWALL
REQUEST_METHODGET
SCRIPT_NAME/cgi-bin/printenv.cgi
QUERY_STRING
REMOTE_ADDR::ffff:127.0.0.1
REMOTE_PORT2379
AUTH_TYPEBasic
REMOTE_IDENTkouichi
HTTP_ACCEPTtext/*, image/*, video/*, application/*
HTTP_ACCEPT_ENCODINGgzip, compress, bzip, bzip2, deflate
HTTP_ACCEPT_LANGUAGEja
HTTP_USER_AGENTMozilla/5.0
Google