CMSH.EXE

        Communication Shell 説明書


                                                (C) S.Suwa 1991. 1.15
                                                    update 1991. 6.29
                                                        1992.12.10
                                                           1993. 2.10

 CMSH.EXE は、通信用簡易言語で書かれたコマンドファイルを読み込み、書かれた命
令を逐次解釈しながら通信を自動的に実行する一種のコマンドインタプリタです. 用意
されているコマンド(命令)には通信処理用だけでなくファイルを取り扱うものも提供
されていますのでバッチファイルとしての応用も可能です.


    目  次
第1章 起動方法
第2章 cmshで扱う変数と定数
    変数
    疑似配列変数
    変数の型
    変数の宣言
    予約変数
    定数
第3章 cmshの変数の通用範囲
    大域変数と局所変数
第4章 cmshの式と演算子
    式
    演算子
    cmsh特有の演算子
第5章 cmshの実行制御文
    空白行
    コメント
    ラベル
    goto
    if, then, else, endif
    while, break, continue, endwh
    switch, case, default, break
    sub, return, endsub
    func, return, endfunc
    chain
第6章 cmshの組み込みコマンド
    call
    cls
    close
    code
    cd
    delay
    dtr
    exec
    exit
    fsend
    input
    local
    logclose
    logopen
    md
    monitor
    onexit
    open
    parameter
    print
    printf
    rd
    read
    remove
    rename
    rflush
    rscsflow
    rts
    send
    sendf
    timeout
    termcode
    terminal
    waitstr
    waittime
    write
    writef
    xflow
第7章 cmshの組み込み関数
    cnvstr()
    cnvval()
    eof()
    exists()
    getcts()
    getdate()
    getdcd()
    gettime()
    hasext()
    haswild()
    iinstr(),instr()
    isfile()
    leftstr()
    midstr()
    rightstr()
    strlen()
第8章 プログラムサンプル
    自動ログインを行う
    電子掲示板の連続読み出し
    文書アップロード
    ファイルダウンロード
    自動読み出し


第 1 章  起動方法

 DOSプロンプトから

    >cmsh commandfile [argument ... ] <cr>

で起動します。commandfile は、この後に述べる簡易言語文法に従って記述されたプ
ログラムファイルであるものとします. commandfile の実行を終わると特に指定がな
い限りDOSに戻ります. onexit コマンドの指定によりターミナルモードとするこ
ともできます. commandfile に続く argument は commandfile に引き渡すことがで
きます. 実行中のプログラムは ESC キーを押すことにより強制停止させることもで
きます. commandfile は約64Kbyteまでの大きさのものが実行できます. これを越
えるような場合には起動時にエラー表示を行いDOSに戻ります.


第 2 章  cmsh で扱う変数と定数

【変数】
 数値変数と文字列変数が使用できます。変数名は, 英数字と '_' 文字から構成さ
  れる16文字以内の識別子です. 最初の文字は '_' または英字でなければいけま
  せん. 16文字以上の変数名を使用することも可能ですが有効なのは最初の16文
  字です. 文字列変数は変数名の前に $ 記号をつけて表します. 
  変数名の後に ( 式 ) を付加するとその変数は疑似配列変数となります. この場合
  に有効な変数名は16文字よりも少なくなるので注意が必要です. 
    abc         ; 数値変数 abc を示します
    $abc        ; 文字列変数 abc を示します

【疑似配列変数】
 変数を添字式によって参照できるよう疑似配列というものが提供されています. 変
  数名に続けて () で式をくくることにより配列変数として扱うことができるように
  なります. 配列の要素数は -32767 から 32767 まで使用することができます. ま
  た特に配列としての宣言は不要です.
    tel_no(1)   ; 疑似数値配列変数 tel_no の 1 番目の要素を示します
    $id(-10)    ; 疑似文字列配列変数 id の -10 番目の要素を示します

【変数の型】
 数値変数は符号付きの整数型として扱われます. -32767 から 32767 までの数値を
  代入することができます. 文字列変数は 255 文字までの任意長の文字列を代入する
  ことができます. いずれの変数もその収容できる大きさを超える値が代入された場
  合には超えた分は切り捨てられます. オーバーフローなどのエラー検出は行ってい
  ません.

【変数の宣言】
 特に宣言をする必要はありません. 初めて現れる変数への明示的な代入式によって
  その変数が宣言(ならびに定義)されます. 代入式による初期化なしに変数を参照
  するとエラーとなります. なお, 例外として local コマンドによる局所変数の明示
  的な宣言を行う方法が提供されています. 疑似配列変数についても同様です.
    n = 10         ; 数値変数 n が宣言されるとともに値 10 で初期化されます.
    $id = "GUEST"  ; 文字列変数 id が宣言されるとともに "GUEST" 文字列で初期
           化されます.

【予約変数】
    次の3つの変数は予め cmsh の中に組み込まれているものです. システム変数と
    も呼びます.

        status  $status  $cwd  argc  $argv

    status や $status は cmsh の組み込みコマンドの実行結果が設定されます. 組
    み込みコマンドの多くは正常に実行できた場合には0を, 何らかの不具合が検出
    された場合には非0を status 変数に返します. $status にはいくつかのコマン
    ドが, コマンドの機能に応じてある種の文字列を設定します. $cwd は常に現在の
    カレントドライブ, カレントディレクトリを保存しています. argc, $argv は 
    cmsh 起動時のコマンドラインで渡された引数の個数, ならびに引数文字列が格納
    されています. $argv の中のそれぞれの引数はリスト要素の参照演算により抽出
    できます. これらのシステム変数は参照するだけでなく, 代入文によって変更す
    ることも可能です.

【定数】
    定数には数値定数と文字列定数が使用できます. 書式は次のとおりです.

  数値定数  10進数文字列からなる数値. 有効な範囲は -32768 から 32767 ま
                でとなります. &h や 0x などの16進定数や2進定数, 8進定数は
                現在のバージョンでは記述できません

  文字定数  ' で囲まれた文字. C言語の ' で囲む一文字の文字定数に同じです.
                cmsh では数値定数として扱います。

  文字列定数 " で囲まれた文字列です. 長さは255文字までです.

  エスケープ文字 文字定数, 文字列定数とも記述文字に \ 記号で始まるエスケー
                プ文字を使用することができます。 \x?? は ?? を16進文字とし
                て扱います.


第 3 章  cmsh の変数の通用範囲

【大域変数と局所変数】
    cmsh の変数は全て大域変数と局所変数の2つのうちのどちらかになります. 大域
    変数はコマンドファイルのどの部分からも代入や参照可能なものであり, 局所変
    数は sub 〜 endsub や func 〜 endfunc の中でのみ代入や参照可能なものです. 
    サブルーチンやユーザー定義関数以外の部分(以下メイン部分と呼びます)で代
    入式により宣言された変数が大域変数となります. サブルーチンやユーザー定義
    関数の仮引数やその中で代入式により初めて宣言される変数は局所変数となりま
    す. なお, local コマンドによって明示的に局所変数を宣言することもできます.


第 4 章 cmsh の式と演算子

【式】
    変数, 定数, 関数ならびにこれらに演算子を適用したものが式です. 代入演算子
    = による代入式はそれ単独で cmsh の一つの実行文となりますがその他の式は単
    独の実行文とすることはできません. 式の評価の型は数値と文字列の2種となり
    ます. 文字列と数値の混在した演算はできません. 次項で示す2項演算子におい
    て両辺の被演算子の型は同じでないとエラーとなります.
    代入式は C 言語と同様, それ自身が値を持ちます.

【演算子】
    使用できる演算子は次の表のとおりです. 表の上にあるものが優先順位が高いこ
    とを示します. [], .d 〜 .e の演算子は文字列専用です. 文字列に適用できる
    演算子はこれらの他に + の加算と <, >, ==, != 等の比較演算子のみです.

    記号           | 意味                                         
  -----------------+----------------------------------------------
    ( )            | 優先順位を変える                             
  -----------------+----------------------------------------------
    [ ]            | リスト要素の抽出                             
  ----------------------------------------------------------------
    .d             | ドライブ名抽出                               
    .p             | ディレクトリ名抽出                           
    .n             | ファイル名のベース抽出                       
    .e             | ファイル名の拡張子抽出                       
  -----------------+----------------------------------------------
    !  ~  -  +     | 論理否定  1の補数  負符号  正符号           
  -----------------+----------------------------------------------
    *  /  %        | 乗算  除算  剰余                             
  -----------------+----------------------------------------------
    +  -           | 加算  減算                                   
  -----------------+----------------------------------------------
    <<  >>         | 左シフト  右シフト                           
  -----------------+----------------------------------------------
    <  <=  =<      | 小さい  以下  以下                           
    >  >=  =<      | 大きい  以上  以上                           
  -----------------+----------------------------------------------
    ==  !=  <>  >< | 等しい  等しくない  等しくない  等しくない   
  -----------------+----------------------------------------------
    &              | ビット毎の論理積                             
  -----------------+----------------------------------------------
    ^              | ビット毎の排他的論理和                       
  -----------------+----------------------------------------------
    |              | ビット毎の論理和                             
  -----------------+----------------------------------------------
    &&             | 論理積                                       
  -----------------+----------------------------------------------
    ||             | 論理和                                       
  -----------------+----------------------------------------------
    =              | 代入                                         
  -----------------+----------------------------------------------

    ++, --, +=, *= 等の演算子は現在のバージョンでは提供されていません.

【cmsh 特有の演算子】
  cmsh 特有の文字列演算子について説明します. まず始めに [] のリスト要素の参
  照演算子です. 文字列内に, 空白, タブにより区切られる複数の語がある場合に
  [] 内に記述された式の値に応じた順番で語を抽出することができます. 次のよう
  な記述の場合,
        $test = "abc def 123"
        $first = $test[1]
    $first には "abc" が代入されます. 参照式の値が要素数以上であったり負数で
    あった場合には抽出結果は "" となります.
    次に . 演算子です. これは被演算子である文字列を有効なパス名とした時, その
    パス名を分解抽出するものです. ドライブ名の取り出しには .d , ディレクトリ
    名の取り出しには .p , ファイル名のベース名の取り出しには .n を, そして拡
    張子の取り出しには .e を記述します. 例えば次のような場合,
        $path = "b:\\user\\cmsh\\cmsh.exe"  ; \ 記号は \\ としなければ
        $drv = $path.d                      ; いけません.
        $dir = $path.p
        $name = $path.n
        $ext = $path.e
    $drv は "b" に, $dir は "\user\cmsh" に, $name は "cmsh" に, $ext は
    "exe" となります.


第 5 章 cmsh の実行制御文

    cmsh におけるコマンド実行の流れを制御するものについて, その書式, 機能を使
    用例とともに以下に示します. (現バージョンでは for 〜 endfor, do 〜 while
    構文が未提供です. これらは while, if によって記述してください.)


 空白行
------------------------------------------------------------------------------
【書式】 (なし)
【機能】
  改行だけからなる空白行は実行時読み飛ばされます. 適宜空白行を記述し見やす
    いプログラムとなるようにしてください.


 ; (セミコロン)
------------------------------------------------------------------------------
【書式】 ; コメント文字列
【機能】
     ; 以降, 行の終わりまでをコメントとして読み飛ばします. ; は行の先頭, 途中
    どこからでも始めることができます.
【使用例】
     send   "\r"    ; キャリッジリターンを送信する.


 * (または label)
------------------------------------------------------------------------------
【書式】 * ラベル名 (または label ラベル名)
【機能】
  ラベルを定義します. ラベルの定義に続けてコマンドを記述する場合にはラベル
    名の後に : を記述します.
【使用例−1】
    *read_mail              ; read_mail という名前のラベルを定義する
【使用例−2】
    label skip: send "\x1b" ; skip という名前のラベル定義に続けて send コマン
                 ドを記述


 goto
------------------------------------------------------------------------------
【書式】 goto  ラベル
【機能】
  ラベルで指定する行へジャンプしてそこから実行します. ラベルの指定には文字
    列式を参照することが可能です.
【使用例−1】
    *read:
            コマンド
            ・・・
            goto read               ; 直接ラベルを指定
【使用例−2】
        $jump = "read write quit"   ; n の値(1〜3)によって read, write, quit
        ・・・                         ; のどれかにジャンプします.
        input n 
        goto $jump[n]
        ・・・
    *read:
        ・・・
    *write:
        ・・・
    *quit:
        ・・・
【注意】
    指定したラベルが未定義の場合にはエラーとなります. また, ラベルにサブルー
    チン名やユーザ定義関数名を指定するとそこへジャンプしますが次のコマンドの
    実行に移った時点でエラーとなります. goto によって while, swich, if の制
    御ループ内にジャンプすると以後の実行が正しく行われません. なお, これらの
    ループからの脱出は問題ありません. sub, func の定義ブロック内への飛び込み,
    ならびに定義ブロック内からのブロック外へのジャンプもできません.


 if, then, else(elseif, elif), endif
------------------------------------------------------------------------------
【書式】 (1) if 式 コマンド
         (2) if 式 then
                コマンド
                ・・・
             else
                コマンド
                ・・・
             endif
         (3) if 式 then
                コマンド
                ・・・
             elseif 式 then
                コマンド
                ・・・
             elseif 式 then
                コマンド
                ・・・
             else
                コマンド
                ・・・
             endif
【機能】
    式を評価しその値が真(非0)ならば then ブロックを,偽(0)ならば else ブ
    ロックのコマンドを実行します. 書式(1) では真ならば式の後に記述されたコマ
    ンドを, 偽ならば次の行以降を実行します. 書式(3) は if, elseif の連鎖です.
    書式 (2),(3) とも else ブロックを省略することができます.
【使用例】
    書式(1) if(mnp_flg == OFF) send "\x1b"      ; MNP非接続なら ESC を送信
    書式(2) if(argc < 2) then
                print   "Usage: cmsh atlas.cmd id password <cr>"
                exit    FAIL
            else
                $id = $argv[1]
                $paswd = $argv[2]
            endif
    書式(3) if(status == 1) then
                goto read_mail
            elseif(status == 2) then
                goto sysop_msg
            elseif(status == 3) then
                goto user_msg
            elseif(status == 4) then
                goto skip_picture
            else
                call sequence_error()
            endif
【注意】
    式に文字列式を記述した場合はエラーとなります. 書式(1) のコマンドには for,
    while, switch, if のコマンドを記述することはできません. else, elseif, 
    endif は行の最初のコマンドとして認識できる位置に記述する必要があります. 
    これらの後に別のコマンドを記述しても無視されます. 書式(3) の elseif は 
    else と if の間に空白を入れてはいけません. なお, elseif は elif とも書く
    ことができます.


 while, break, continue, endwh
------------------------------------------------------------------------------
【書式】 while 式
            コマンド
            ・・・
            break
            ・・・
            continue
            ・・・
         endwh
【機能】
  式の値が真(非0)である間, endwh までのコマンドを繰り返し実行します. 式
    の値が偽(0)になればあるいは最初から偽の場合には endwh 以降にスキップし
    ます. break によりループの途中から脱出することができます. continue を記述
    すればループの途中からループの最初の式評価に戻ります. break や continue 
    は通常は if コマンドの中に記述してループの実行を制御します.
【使用例−1】
    n = 0
    while(n < 10)
        print   "n = ", n
        n = n + 1
    endwh
【使用例−2】
    while(1)                ; 無限ループを示します
        input n             ; キーボードから 変数 n に数値を入力
        if(n == 999) then   ; 999 が入力されるとループを脱出します
            break
        endif
        print "n = ", n
    endwh
【使用例−3】
    while(1)                        ; "?) ->" が受信される度に N\r の送信を
        waitstr "?) ->", "E) ->"    ; 繰り返します. "E) ->" が受信された時
        if(status == 1) then        ; に Q\r を送信し, ログの書き込みを終了
            send    "N\r"           ; してプログラムの実行を終了します.
            continue
        endif
        logclose
        send    "Q\r"
        exit    0
    endwh
【注意】
    式に文字列式を記述した場合はエラーとなります. while, endwh は行の最初のコ
    マンドとして認識できる位置に記述する必要があります. これらの後に別のコマ
    ンドを記述しても無視されます. break や continue をループ内以外で記述する
    とエラーになります.


 switch, case, default, break, endsw
------------------------------------------------------------------------------
【書式】    switch 式
            case 式:
                コマンド
                ・・・
                break
            case 式:
                コマンド
                ・・・
                break
            ・・・
            default:
                コマンド
                ・・・
            endsw
【機能】
  switch に続く式の値が case に続く式の値と一致するところから break または
  endsw までの間を実行します. break がない場合には endsw まで実行します. 
    break により endsw までをスキップします(switch ブロックの脱出). 値が一
    致する case がない場合に, default が定義されていればそこから実行します.
【使用例】
    send    "ATDP0785815610\r"
    waitstr "BUSY", "NO DIALTONE", "NO CARRIER", "CONNECT"
    switch(status)
    case 1:
        print   "話中です。"
        break
    case 2:
        print   "ダイヤルトーンが検出できません。"
        break
    case 3:
        print   "相手呼出し中に回線が切断しました。"
        break
    default:
        print   "接続できました。"
    endsw
【注意】
  case の式の後ならびに default の後には必ず : を記述しなければいけません.
  switch の続く式が文字列式ならば case に続く式はすべて文字列式でなければい
  けません. case や default は単独のコマンドとして認識できる位置にかかれて
  いなければなりません. if コマンドの中に記述すると正しく実行されません. ま
  た default は最後に記述しなければいけません. 必要な case コマンドより先に
  default が記述された場合 default 以降に記述された case はすべて無効になり
  ます.


 sub, return, endsub
------------------------------------------------------------------------------
【書式】    sub サブルーチン名 ( 仮引数変数名, ... )
                コマンド
                ・・・
                return 式
                コマンド
                ・・・
            endsub
【機能】
    プログラム中にサブルーチンを定義します. サブルーチン名は sub に続けて記述
    します. 呼出しもとから引数を受け取る場合には () 内に受け取る仮引数変数名
    を "," で並べて記述します. サブルーチン定義は endsub までとなります. プロ
    グラム実行中に sub キーワードに遭遇した場合には endsub まで読み飛ばされま
    す. 
    これによりサブルーチン定義はプログラム内のどこにでも記述することが可能で
    す. サブルーチンは call コマンドによる呼び出しによってのみ実行されます.
    call コマンドによってサブルーチンが実行された場合, endsub に到達した時点
    で呼び出しもとに戻りますが, もし return コマンドがあればそこから呼び出し
    もとに強制復帰します. return に続く式は省略可能ですが, 記述されていた場合
    にはその評価値がシステム変数の status または $status (文字列式の場合)に
    セットされます. 仮引数変数は5個まで記述できます. 仮引数変数はすべてその
    サブルーチン内でのみ有効な局所変数となります. 引数は数値, 文字列とも値渡
    しで呼び出されます. サブルーチンは再帰呼び出しが可能です.
【使用例】
    call login("ATL00XXX", "PSWPSW")
    if(status == 0) then
        print   "ログイン失敗"
    else
        print   "ログイン成功"
    endif
    ・・・
    ・・・
    sub login($id, $psw)                ; 自動ログインサブルーチン
        waitstr "NO CARRIER", "ID =" 
        if(status < 2) then             ; $id, $psw で渡された ID, PASSWORD
            return 0                    ; を使用してログイン処理を行います.
        else                            ; 回線断の検出や期待文字列が受信でき
            send    $id                 ; なかった場合には status に 0 をセ
        endif                           ; ットして retern します. 成功した場
        witstr  "NO CARRIER", "PSW ="   ; 合には 1 をセットして戻ります.
        if(status < 2) then
            return 0
        else
            send    $psw
        endif
        status = 1
    endsub
    ・・・
    ・・・
【注意】
    サブルーチン名にはラベル名, ユーザー定義関数名, 変数名と同じものを使用す
    ることはできません. 仮引数がない場合でもサブルーチン名に続く () は記述し
    なければいけません. サブルーチン内から別のサブルーチンやユーザー定義関数
    を呼び出すことはもちろん可能ですが, 呼び出しのネストが深くなると スタック
    オーバーフロー となることがあります. sub, endsub は記述される行の最初のコ
    マンドとして認識できる位置に書かれなければなりません. サブルーチン定義内
    での別サブルーチンの定義やユーザー関数の定義は許されません. サブルーチン
    定義内で, 定義ブロックを飛び出すような goto を記述した場合ジャンプ可能で
    すが, ジャンプ先以降の実行が正しく行われません. なお,サブルーチン内に限っ
    た局所的なジャンプは問題ありません.


 func, return, endfunc
------------------------------------------------------------------------------
【書式】    func ユーザー関数名 ( 仮引数変数名, ... )
                コマンド
                ・・・
                return 式
                コマンド
                ・・・
            endfunc
【機能】
    プログラム中にユーザー関数を定義します. ユーザー関数名は func に続けて記
    述します. 呼出しもとから引数を受け取る場合には () 内に受け取る仮引数変数
    名を "," で並べて記述します. ユーザー関数の定義は endfunc までとなります.
    プログラム実行中に func キーワードに遭遇した場合には endfunc まで読み飛ば
    されます. これによりユーザー関数の定義はプログラム内のどこにでも記述する
    ことが可能です. ユーザー関数は任意の式の中で ユーザー関数名(実引数, ... 
    )と記述されることにより呼び出され実行されます. ユーザー関数が実行された
    場合, endfunc に到達した時点で呼び出しもとに戻りますが, もし return コマ
    ンドがあればそこから呼び出しもとに強制復帰します. return に続く式によりそ
    の式の評価値を関数の値として返します. なお, 式は省略可能です. 式が省略さ
    れた場合にはその時点での status または $status(文字列関数の場合)の値が
    返されます. 仮引数変数は5個まで記述できます. 仮引数変数はすべてその関数
    内でのみ有効な局所変数となります. 引数は数値, 文字列とも値渡しで呼び出さ
    れます. ユーザー関数は再帰呼び出しが可能です.
【使用例】
    func factorial(n)               ; n の階乗を求める関数
        if(n == 0) then 
            return( 1 )
        else
            return( n * factorial(n -1) ) ; 再帰呼び出しにより計算
        endif
    endfunc
    ...
    ...
    print   "N を入力してください."
    printf  "  N = "                ; 改行させないために printf を使用
    input   N
    printf  "%d の階乗は %d です", N, factorial(N)
    ...
    ...
【注意】
    ユーザー定義関数名にはラベル名,サブルーチン名, 変数名と同じものを使用する
    ことはできません. 仮引数がない場合でも関数名に続く () は記述しなければい
    けません. 関数内から別のユーザー定義関数やサブルーチンを呼び出すことはも
    ちろん可能ですが, 呼び出しのネストが深くなると スタックオーバーフロー と
    なることがあります. func, endfunc は記述される行の最初のコマンドとして認
    識できる位置に書かれなければなりません. ユーザー関数の定義内での別関数の
    定義やサブルーチンの定義は許されません. ユーザー関数定義内で, 定義ブロッ
    クを飛び出すような goto を記述した場合ジャンプ可能ですが, ジャンプ先以降
    の実行が正しく行われません. なお,関数内に限った局所的なジャンプは問題あり
    ません.


 chain                (予定機能です. 現バージョンでは未サポートです)
------------------------------------------------------------------------------
【書式】    chain コマンドファイル名, 実行開始ラベル, 引数, ...
【機能】
    現在実行中のコマンドファイルを chain に続けて記述された コマンドファイル
    に置き換えるとともに, 新しいコマンドファイルを指定されたラベル位置から実
    行します. 元のコマンドファイルに戻ることはありません. コマンドファイル名
    と実行開始ラベルは文字列式の参照が可能です. 引数は任意の式並びです. 引数
    は チェーンされたコマンドファイルの argc, $argv に値がセットされます. 数
    値引数は argv にセットする時に文字列化されます.
【使用例】
    $file = "DOWN.CMD UP.CMD LOGIN.CMD" ; チェーンするファイル名のセット
    $start(1) = "down_load"             ; 実行開始ラベルのセット
    $start(2) = "up_load"
    $start(3) = ""                      ; ファイルの先頭より開始
    ;
    while(1)
        print
        print   " 1: 自動ダウンロード"
        print   " 2: 自動アップロード"
        print   " 3: 自動ログイン"
        print
        printf  "処理を番号で選択してください. =>"
        input   n
        if(n < 1 || n > 3) then
            print   "選択された番号が誤っています"
        else
            cls
            chain   $file[n], $start(n), $id, $psw
        endif
    endwh
【注意】
  チェーンするコマンドファイルがカレントディレクトリにない場合にはそれが存
  在するパス名を付けなければいけません. ファイルが見つからない場合にはエラ
  ーとなります. チエーンされたファイルに, 指定された実行開始ラベルが定義さ
  れていない場合にもエラーとなります. 渡す引数の数に制限はありませんがすべ
  ての引数を文字列連結した長さは 120 文字以内でなければなりません. 実行開始
  ラベル以降の記述は省略できます. ただし, 引数を記述する場合には実行開始ラ
  ベルは省略できません. この場合, ファイルの先頭から実行するのであれば "" 
  を指定してください. 実行開始ラベルに "" が指定されると先頭から実行します.



第 6 章 cmsh の組み込みコマンド

    cmsh の組み込みコマンドは次のとおりです.


 call
------------------------------------------------------------------------------
【書式】    call サブルーチン名 ( 実引数式, ... )
【機能】
    サブルーチン名で示すサブルーチンを呼び出します. () 内には実引数を記述しま
    す. 引数の型は サブルーチン定義行(sub)で宣言された仮引数と同じ型でなけ
    ればなりません. 実引数が仮引数の数よりも少ないとエラーとなりますが多い分
    については単に余分な引数は無視されます. この場合に実引数と仮引数の対応は
    前からとなっていますので後ろのものが無視されることになります.
【使用例】
    call login("ATL00XXX", "PSWPSW")
    if(status == 0) then
        print   "ログイン失敗"
    else
        print   "ログイン成功"
    endif
    ・・・
    ・・・
    sub login($id, $psw)                ; 自動ログインサブルーチン
        waitstr "NO CARRIER", "ID =" 
        if(status < 2) then             ; $id, $psw で渡された ID, PASSWORD
            return 0                    ; を使用してログイン処理を行います.
        else                            ; 回線断の検出や期待文字列が受信でき
            send    $id                 ; なかった場合には status に 0 をセ
        endif                           ; ットして retern します. 成功した場
        witstr  "NO CARRIER", "PSW ="   ; 合には 1 をセットして戻ります.
        if(status < 2) then
            return 0
        else
            send    $psw
        endif
        status = 1
    endsub
    ・・・
    ・・・


 cls
------------------------------------------------------------------------------
【書式】    cls
【機能】
    スクリーンを消去します(標準出力に ESC[2J を出力しています).
【使用例】
    cls
    ...
    ...


 close
------------------------------------------------------------------------------
【書式】    close   ファイル番号
【機能】
    open コマンドによってオープンされているファイル番号で示されるファイルをク
    ローズします. ファイル番号は数値式です. ファイル番号の誤り等によりクロー
    ズ処理に失敗した場合にはシステム変数 status に非0を, 正常にクローズでき
    た場合には0が設定されます.
【使用例】
    open    3, "userid.dat", 2
    while( !eof(3) )
        read 3, $id
        print   $id
    endwh
    close   3


 code
------------------------------------------------------------------------------
【書式】    code    SI/SO制御指定 , 漢字コード指定
【機能】
    通信に使用するコードを制御します. 最初の引数は SI/SO によるカナコード制御
    を行うかどうかを指定します. 次の引数では漢字コードをシフトJISで扱うの
    かJISで取り扱うのかを指定します. それぞれ数値式で参照します. 引数式の
    評価値により次のとおりの指定となります.
        0      SI/SO 制御をしない, シフトJIS漢字を使用する.
        非0    SI/SO 制御を行う, JIS漢字を使用する.
【使用例】
  SCONT = JISKANJI = 1
    code    SCONT, JISKANJI ; SI/SO 制御有り, JIS 漢字を使用
    ...
    code    0, 0            ; SI/SO 制御なし, シフトJIS 漢字を使用
    ...
【注意】
    通信ポートのデータビット長の値に係わらず制御を行います. また SI/SO 制御と
    漢字コードは独立して制御されます. 通信ポートが8データビット長であっても
    SI/SO 制御を行ったり, JIS 漢字コードによる通信を行うことができます.


 cd
------------------------------------------------------------------------------
【書式】    cd  ドライブ:パス
【機能】
    カレントドライブ, カレントディレクトリを変更します. command.com に組み込
    みの cd コマンドではドライブとディレクトリを同時に変更することはできませ
    んがこの cd コマンドでは可能となっています. ドライブ, パスの指定には文字
    列式を参照することができます. コマンドの実行結果はシステム変数 status, 
    $cwd に設定されます. status が 0 なら正しく変更されたことを示し, 非0な
    らエラーがあったことを示します. そして変更後のカレントドライブ, カレント
    ディレクトリ名が $cwd に格納されます.
【使用例】
    cd  "b:atlas"
    if(status) then
        print   "ディレクトリの変更ができません."
    else
        printf  "ディレクトリを変更しました. 現在 %s です.\n", $cwd
    endif
    ...


 delay
------------------------------------------------------------------------------
【書式】    delay   遅延時間(msec)
【機能】
    コマンドの実行を指定時間遅延します. 時間指定には数値式を参照します. 単位
    はミリ秒です. この遅延時間中に通信ポートより受信された文字は, 受信バッフ
    ァに格納されたまま何も処理されません. delay コマンドの実行終了とともに処
    理されます.
【使用例】
    parameter   2400,8,1,0,1    ; 通信ポートの条件設定の後,
    delay   100                 ; 100 msec の遅延を行いモデ
    send    "ATZ\r"             ; ムを初期化します.
    ...


 dtr
------------------------------------------------------------------------------
【書式】    dtr 数値式
【機能】
    通信ポートの DTR(ER) を ON, OFF 制御します. 数値式の評価値が非0なら ON,
    0なら OFF に制御します.
【使用例】
    if(dcd()) then              ; 回線が接続されたままなら
        dtr     0               ; dtr を OFF にして回線切断
        waittime    1           ; してプログラムの実行を終
    endif                       ; 了します.
    exit
    ...
    ...


 exec
------------------------------------------------------------------------------
【書式】    exec    外部コマンド名 , コマンド引数 , ...
【機能】
    外部コマンドを実行します. 外部コマンド名に続けて必要な引数を列記すること
    により, 外部コマンドに引数を渡すことができます. 外部コマンド名や引数は全
    て文字列でなければいけません. 文字列式による参照も可能です. 外部コマンド
    の実行結果はシステム変数である status に設定されます. なお, 外部コマンド
    が見つからない場合には status には -1 が設定されます. 外部コマンドの検索
    には環境変数 path を参照します.
【使用例】
    ...
    exec "ft", "-rab"       ; ファイル転送プログラム(FT.EXE)を起動します.
    exec "lha","-e","game.lzh"  ; 受信した game.lzh を解凍します.
    ...


 exit
------------------------------------------------------------------------------
【書式】    exit    [ 数値式 ]
【機能】
    コマンドファイルの実行を終了します. exit に続く数値式は省略可能です. 数値
    式が記述されていればその評価値が cmsh の実行結果として DOS に渡されます.
    記述されていなかった場合には 0 を実行結果とします.
【使用例】
    ...
    ...
    exit    1
【注意】
    exit コマンド実行後は2とおりの動作をさせることができます. 一つ目は直ちに
    cmsh を終了して DOS に戻る, 二つ目にはターミナルモードとして動作すること
    です. これら2とおりのどちらの動作を行わせるかは onexit コマンドで指定す
    ることができます. デフォルトの動作は DOS に戻るです.


 fsend
------------------------------------------------------------------------------
【書式】    fsend   ファイル名 , 行間待ち時間
【機能】
    ファイル名で指定されたファイルを無手順にてアップロードします. 行末送信時
    の待ち時間はミリ秒で指定します. 指定されたファイルが存在しない場合等のエ
    ラー情報は, fsend コマンドの実行によってシステム変数 status に設定されま
    す. status に設定される値は次のとおりです.
        0:  正常終了
        1:  指定されたファイルがオープンできない.
        2:  読み込みエラーを起こした.
        3:  転送途中で回線断が発生した.
        4:  オペレータストップによる中断(ESCキー押下)
    ファイル名は文字列式で, 待ち時間は数値式で記述します.
【使用例】
    ...
    send    "W\r"               ; ボードの書き込みを選択
    waitstr "->"
    fsend   "board.msg", 100    ; ファイル(board.msg)をアップロード 
    send    ".E\r"              ; 書き込み終了を送信
    ...
    ...


 input
------------------------------------------------------------------------------
【書式】    input   変数名 , ...
【機能】
    標準入力(通常キーボード)から一行読み込みを行い, 指定された変数名に代入
    します. 変数名に文字列変数が指定されている場合には行全体がそのまま代入さ
    れますが, 数値変数の場合には入力された行の最初の語が数値化されて代入され
    ます. 変数名が複数指定されている場合には指定されている数だけ入力処理が行
    われます. 入力プロンプトなどは表示されません. printf 等を使用して表示させ
    てください.
【使用例】
    printf  "名前と年齢を入力してください. ->"      ; 改行しません.
    input   $name, age
    printf  "%s さんは %d 歳です.\n", $name, age

  (実行結果)
    名前と年齢を入力してください. -> SYSOP <cr>
    38 <cr>                         ~~~~~~~~~~~~~~~~~
    ~~~~~~~~
    SYSOP さんは 38 歳です.


 local
------------------------------------------------------------------------------
【書式】    local   変数名 , ...
【機能】
    局所変数の使用を宣言します. 指定された変数は局所変数として宣言されるだけ
    でなく同時に文字列変数なら ""に, 数値変数なら 0 に初期値が設定されます. 
    サブルーチンやユーザー定義関数の中でメイン部分との変数の重複を避けるため
    に使用すると便利です. 局所変数は,この宣言を行った sub や func ブロックの
    実行終了とともに消去されます. なお, メイン部分で local により変数宣言を行
    いますとその変数は sub や func からは見えない変数となります.
【使用例】
    ...
    i = 100
    print   i                   <-----+
    ...                               |
    ...                               |
    func  search_id($id)              |
        local   i               <-----+-- i は別の変数です.
        while( i < 10 )
            if( $memb(i) == $id ) then
                return  i
            endif
            i = i + 1
        endwh
        return -1
    endfunc


 logclose
------------------------------------------------------------------------------
【書式】    logclose
【機能】
    logopen コマンドにて開始されていたログの採取を終了します. logopen コマン
    ドを使用しないで logclose を行ってもエラーとはなりません.
【使用例】
    logopen getdate(2)+".log", 0    ; 上書きモードでファイル(yymmdd.log)に
    ...                             ; ダウンロードする.
    ...
    logclose                        ; ダウンロードを終了してホストからログオ
    send    "Q\r"                   ; フする.
    ...


 logopen
------------------------------------------------------------------------------
【書式】    logopen ログファイル名 [,モード指定]
【機能】
    指定されたログファイル名で通信ログの採取を開始します. 指定されたファイル
    が既に存在する場合, モード指定に従いオーバーライトもしくはアペンドされま
    す. ログファイル名は文字列式, モード指定は数値式で指定します. 指定可能な
    モードは次のとおりです.
        0 オーバーライト
        1 アペンド
    モード指定は省略可能です. この場合にはアペンドモードとなります.
【使用例】
    logopen     "board3.log", 1     ; ボード3をダウンロードします
    send        3, "\r"
    ....
    ....
    logclose
    logopen     "board4.log", 1     ; ボード4をダウンロードします
    send        4, "\r"
    ....
    ....
    logclose


 md
------------------------------------------------------------------------------
【書式】    md  パス名, ...
【機能】
    指定されたパス名のサブディレクトリを作成します. パス名は文字列式で指定し
    ます. パス名にはドライブ指定を含めることもできます. 複数のパス名を "," で
    区切って指定することもできます.
【使用例】
    md  "log", "b:\\log\\" + getdate(2)
        ; カレントディレクトリに log というサブディレクトリを, B ドライブの log という
        ; サブディレクトリ上に yymmdd というサブディレクトリを作成します.
        ; yymmdd はシステム日付です.


 monitor
------------------------------------------------------------------------------
【書式】    monitor  スウィッチ
【機能】
    スウィッチの値に従って通信回線から受信する文字を画面に表示するかしないか
    を制御します. スウィッチは数値式で指定します. スウィッチの評価値が0なら
    非表示に, 非0なら表示となります. monitor は logopen によるログ採取へ影響
    を及ぼすことはありません.
【使用例】
    ; ホストとの回線が接続するまでは画面表示しないようにします.
        monitor     0
        send    "ATZ\r"
        waittime    2
        send    "ATDP078-5815610\r"
        waitstr "CONNECT"
        monitor     1


 onexit
------------------------------------------------------------------------------
【書式】    onexit  数値式
【機能】
    コマンドファイルの実行終了時やコマンドファイル内のエラー検出時, ならびに
    ESC キーによる強制中止時の cmsh の動作を指定します.
    数値式の評価値が0なら cmsh を終了し DOS に戻ることを指定します. 非0なら
    terminal コマンドを実行することを指定します.
【使用例】
    onexit  1
    ...
    ...
【注意】
    ホストへの自動アクセスなどのプログラムをデバッグする時には, プログラムの
    先頭で onexit 1 と記述しておけば, プログラムにエラーがあった場合でも回線
    が切断されませんので便利です. cmsh をバッチ処理として使用するような場合に
    は onexit コマンドは使用しない方がいいでしょう.


 open
------------------------------------------------------------------------------
【書式】    open    ファイル番号, ファイル名, モード
【機能】
    ファイル名で指定されたファイルを指定のモードでオープンします. オープンに
    成功すると指定されたファイル番号とファイルが結び付けられます. 同時にオー
    プンできるファイル数は 3 個までです. また指定するファイル番号も 1 〜 3 の
    いずれかでなければなりません. ファイル名は文字列式, ファイル番号, モード
    は数値式で指定します. 指定できるモードは次のとおりです.
        0  書き込み(オーバーライト)
        1  書き込み(アペンド)
        2  読み込み
    存在しないファイルの読み込みオープンや, 指定されたファイル番号に既にファ
    イルが割り当てられていた場合にはエラーとして status に非0の値が設定され
    ます. open コマンドで扱うファイルはモードの種別にかかわりなくテキストファ
    イルのみです. バイナリファイルを取り扱うことはできません.
【使用例】
    ; infile の内容を outfile にコピーします.
    open    1, "infile", 2
    open    2, "outfile", 0
    while(!eof(1))
        read    1, $line        ; 一行を文字列変数 line に読み込む.
        write   2, $line        ; line の内容をファイルに書きだす.
    endwh
    close 1
    close 2


 parameter
------------------------------------------------------------------------------
【書式】    parameter   通信速度, データ長, ストップ長, パリティ種別, ポート番号
【機能】
    通信回線の通信速度等の通信パラメータを設定します. 全て数値式で指定します.
    それぞれ指定できる値は次のとおりです.
        通信速度    300 〜 19200
        データ長    7, 8
        ストップ長     1, 2
        パリティ    0(無し), 1(奇数), 2(偶数)
        ポート番号    1(PC_9801), 1 〜 2(PC/AT, PS55, PanacomM, FMR, J3100)
    ポート番号 1 は本体内蔵ポート, 2 は拡張ポートとなります. ただし, ハードウェア上
    の設定によっては必ずしもこのとおりとは限りませんので注意が必要です.
【使用例】
    code        0, 0
    parameter   9600, 8, 1, 0, 1    ; 9600 bps, N81XN シフトJIS で受信待機する
    send    "ATX3S0=3\r"
    timeout 1
    while(1)                        ; 着信を待つ.
        waitstr "CONNECT"
        if(status) break
    endwh

    ; 着信したモデム速度に変更
    if( instr($status, "4800") ) then       ; 4800 bps で着信した?
        parameter 4800, 8, 1, 0, 1
    elseif( instr($status, "2400") ) then   ; 2400 bps で着信した?
        parameter 2400, 8, 1, 0, 1
    elseif( instr($status, "1200") ) then   ; 2400 bps で着信した?
        parameter 1200, 8, 1, 0, 1
    elseif( instr($status, "300") ) then    ; 2400 bps で着信した?
        parameter 300, 8, 1, 0, 1
    endif
【注意】
    本コマンドは通信用 LSI を直接制御します. この為に瞬時ではありますが DTR 
    が OFF となります. この時間は通常接続されているモデムの DTR の断検出時間
    より十分短いものであり, 回線接続中に本コマンドにてパラメータ変更を行って
    も回線が切断されるような事はありません. もし切断されるような場合にはモデ
    ムの DTR 断検出時間の調整を行ってください.


 print
------------------------------------------------------------------------------
【書式】    print   [文字列式 | 数値式, ...  ]
【機能】
    式の評価結果を画面に表示します. print コマンドは必ず最後に改行を出力しま
    す. 改行出力を抑制する方法はありません. 式が記述されていなければ改行動作
    のみ行います. さらに式の評価結果の間に空白を出力することもありません. 空
    白で区切ったり改行を抑制したりする場合には printf コマンドを使用します.
【使用例】
    cls                         ; 画面消去
    print                       ; 改行します.
    print   "これからATLASにアクセスします."
    print   "本日は ", getdate(2), " です."
    print   "ただ今の時刻は ", gettime(0), " です."


 printf
------------------------------------------------------------------------------
【書式】    printf  書式指定文字列式 [, 文字列式 | 数値式, ...  ]
【機能】
    書式付きで式の評価結果を画面に表示します. 式は 10 個まで記述できます. 書
    式指定文字列の記述方法は C 言語の printf()関数における書式指定に準じます.
    実際のところ CMSH ではこの printf コマンドの処理は printf() 関数で直接処
    理を行っています. そのため書式指定は C と同じというわけです. ただし, long
    や float, double の型を持つ変数は CMSH では扱えませんのでこれらの型に関す
    る書式指定を行った場合にはその結果は保証の限りではありません.
【使用例】
    n = 10
    $msg = "N の値は"
    printf  "%s %d です.\n", $msg, n

    N の値は 10 です.  のように表示されます.
   ~~~~~~~~~~~~~~~~~~
【注意】
    書式指定によって変換された全体の長さは 512 文字を超えないようにプログラム
    してください. これは CMSH での制限であって C 言語上の printf()関数の制約
    ではありません. CMSH で使用している C コンパイラは 一般的なものです.


 rd
------------------------------------------------------------------------------
【書式】    rd  パス名, ...
【機能】
    指定されたパス名のサブディレクトリを削除します. パス名は文字列式で指定し
    ます. パス名にはドライブ指定を含めることもできます. 複数のパス名を "," で
    区切って指定することもできます.
【使用例】
    rd  "log", "b:\\log\\" + getdate(2)
        ; カレントディレクトリの log というサブディレクトリと, B ドライブの log という
        ; サブディレクトリ上の yymmdd というサブディレクトリを削除します.
        ; yymmdd はシステム日付です.
【注意】
    rd コマンドは DOS コマンドの RD の機能と同じです. 指定したディレクトリが空でな
 いと削除しません. また下位のサブディレクトリを削除することもありません.


 read
------------------------------------------------------------------------------
【書式】    read    ファイル番号, 文字列変数 [,文字列変数, ... ]
【機能】
    open コマンドにて読み込みモードでオープンされた指定番号のファイルから, 指
    定の文字列変数に一行読み込みを行います. 文字列変数はこのコマンドの実行以
    前に宣言しておく必要はありません. read コマンドの実行により変数が割当られ
    ます. もちろん先に宣言された変数に読み込む事も可能です.
    文字列変数が複数記述されてある場合には, 一度に変数の数だけ読み込みを行い
    ます. ファイルの末尾を越えて読み込みを行おうとした時には status 変数に非
    0が返されます. 読み込みがうまくできた場合には, status は 0 となります.
【使用例】
    ファイル(idtable.dat)の内容が次のとおりだったとします.
    1: ATL00000  SYSOP
    2: ATL00001  GUEST
    3: ATL00002  愛蘭
    4: ATL00003  xxxxxxx
    5:     .
    6:     .
    7:     .
    $id = "ATLxxxxx"
    flg = 0
    open    1, "idtable.dat", 2
        while( !eof(1) )
            read 1, $member
            if( $member[1] == $id ) then
                printf "Found. %s のハンドル名は %s です.\n", $id, $member[2]
                flg = 1
                break
            endif
        endwh
        if( !flg ) then
            printf  "Not Found %s. 会員ではありません.\n", $id
        endif
    close   1
【注意】
    read は一行単位に読み込みを行いますが, 文字列変数が取り得る可能な最大文字
    数(255)を越える行については, 255文字毎に分割して読み込みを行います.
    ファイル内の行末の \r\n は, 読み込みの時に削除されます.


 remove
------------------------------------------------------------------------------
【書式】    remove  ファイル名, ...
【機能】
    指定されたファイルを削除します. ファイル名は絶対パス, 相対パスいずれでも
    かまいません. 存在しないファイルを指定した場合や削除に失敗した場合には 
    status 変数に非0が, 削除できた場合には0が返されます.
【使用例】
    remove  "910113.log", "910114.log", "910115.log"
                ; 91 年 1 月 13 日から 15 日までのログファイルを削除します.
【注意】
    ファイル名指定にワイルド文字を使用することはできません.


 rename
------------------------------------------------------------------------------
【書式】    rename  旧ファイル名, 新ファイル名
【機能】
    旧ファイル名で指定されたファイルの名前を新ファイル名に変更します. ファイ
    ル名にはパスを含むことができます. rename コマンドではファイルを1つのディ
    レクトリから別のディレクトリに移動することもできます. ただし, 異なるドラ
    イブ間での移動はできません.
    旧ファイルが存在しない場合や新ファイルが既に存在する場合, その他の理由に
    より変更に失敗した場合には status 変数に 非0が, うまく変更できた場合には
    0が返されます.
【使用例】
    rename  "atlas.log", getdate(2) + ".log"
                            ; atlas.log を本日日付のファイル名に変更します.
    rename  "atlas.log", "log\atlas.log"
                            ; atlas.log を サブディレクトリ(log) に移動します.
【注意】
    ファイル名指定にワイルド文字を使用することはできません.


 rflush
------------------------------------------------------------------------------
【書式】    rflush
【機能】
    通信回線の内部受信バッファをクリアします. 受信バッファの大きさは約4Kbyte
    が確保されています.


 rscsflow
------------------------------------------------------------------------------
【書式】    rscsflow    スウィッチ
【機能】
    通信回線の RTS/CTS によるフロー制御を設定します. スウィッチは数値式で指定
    しますが, その評価値が非0なら 制御有り, 0なら 制御無し に設定します.
【使用例】
    ON  = 1
    OFF = 0
    rscsflow    ON
      .
      .
      .
    rscsflow    OFF
【注意】
    現バージョンではこのコマンドは何も機能しません. 常に RTS/CTS フロー制御有
    りに設定されています. 制御有りの状態であっても何ら通信に影響を及ぼすよう
    なことはありません. 接続されているモデムが RTS/CTS フロー制御をサポートし
    ていない場合に仮に RTS が オフの状態になったとしてもモデムは受信動作を止
    めるようなことはありません.


 rts
------------------------------------------------------------------------------
【書式】    rts     スウィッチ
【機能】
    通信回線の RTS を ON, OFF 制御します. スウィッチは数値式で指定しますが,
    その評価値が非0なら ON , 0なら OFF に制御します.
【使用例】
    ON  = 1
    OFF = 0
    rts     ON
      .
      .
      .
    rts     OFF
【注意】
    本コマンドは RTS/CTS フローによる RTS 信号の状態に係わらず強制的に ON,
    OFF 制御できてしまいます. このため MNP など RTS/CTS フロー制御を用いた通
    信を行っている場合には実行しない方がいいでしょう. 
    このコマンドはあまり使用する必要のないものの一つです.


 send
------------------------------------------------------------------------------
【書式】    send    [文字列式 | 数値式, ...  ]
【機能】
    式の評価結果を通信回線に送出します. send コマンドは print コマンドとよく
    似たコマンドです. print コマンドが画面を対象としているのに対し, send コマ
    ンドは通信回線を対象としていることです. ただし, send コマンドは print コ
    マンドのように最後に改行を出力するようなことはありません. このため send 
    だけ記述した場合には何も行いません.
【使用例】
    $dialno = "078-581-5610"
    print   "これからATLASにアクセスします."
    send    "atz\r"             <--- \r で 改行を送出します.
    waittime    2
    send    "atdp", $dialno, "\r"
    waitime     1
    rflush
    waitstr "BUSY", "NO CARRIER", "CONNECT"


 sendf
------------------------------------------------------------------------------
【書式】    sendf   書式指定文字列式 [, 文字列式 | 数値式, ...  ]
【機能】
    書式付きで式の評価結果を通信回線に送出します. sendf コマンドは printf コ
    マンドとよく似たコマンドです. printf コマンドが画面を対象としているのに対
    し, sendf コマンドは通信回線を対象としていることです. 書式指定その他の制
    限事項は printf の項を参照してください.
【使用例】
    ; ボード #2 から #8 までを順じ P コマンドで読み出します.
    boardno = 1
    while( (boardno = boardno + 1) <= 8 )
        waitstr     "Q|?) ->"
        sendf       "C%d\r", boardno
        waitstr     "Q|?) ->"
        sendf       "P\r"       <-- send の代わりに sendf でも同じです.
    endwh


 timeout
------------------------------------------------------------------------------
【書式】    timeout     タイムアウト時間(秒)
【機能】
    waitstr コマンドによる文字列待ちの許容待ち時間を秒単位で設定します. デフ
    ォルト値は 60 秒です.
【使用例】
    timeout 60                  ; モデムからの接続待ちを 60 秒に設定します.
    send    "atdp078-5815610\r"
    waitstr "BUSY", "NO CARRIER", "CONNECT"
    ...
    ...
    timeout 600                 ; ボード読み出し中の次のプロンプト待ちを
    waitstr "Q|?) ->"           ; 10 分に設定します.
    ...
    ...


 termcode
------------------------------------------------------------------------------
【書式】    termcode    送信行末スウィッチ, 受信行末スウィッチ
【機能】
    送信行末, 受信行末のコード設定を行います. 指定するスウィッチの値とコード
    の対応は次のとおりです.
      値    対応コード
        0       CR
        1       LF
        2       CR+LF
    現バージョンでは, CR,LF,CR+LF 以外のコードを設定することはできません.
【使用例】
    termcode    0, 2    ; 送信行末 CR, 受信行末 CR+LF に設定します.
    ...
    ...
【注意】
    send や sendf では, 設定された送信行末コードの種別に関係なく '\r' のみを
    使用してください. '\r' が回線に送出される時に自動的に設定されたコードに変
    換されるようになっています. fsend によるファイル送信においてはディスクフ
    ァイル内の行末の '\r\n' が設定されたコードに自動的に変換されて送出されま
    す. 
    送信行末設定が LF になっている時,
        send    "\r\n"
    とすると LF,LF が回線に送出されることとなります. この場合には,
        send    "\r"
    と
        send    "\n"
    は結果として同じこととなります.('\n' は変換対象ではないのでそのまま出力
    されてしまう.)


 terminal
------------------------------------------------------------------------------
【書式】    terminal
【機能】
    ターミナルモードに切換えます. 打鍵した文字は直ちに通信回線に送出され, 通
    信回線から受信した文字は直ちに画面に表示されます. ターミナルモードから抜
    けるには, Ctrl + \ を打鍵します.
    ターミナルモードに切換わった時その旨の表示等は何も画面に表示されません.
    抜けた時も同様です.
【使用例】
    ; ホストに自動接続し, 文書入力となった時点でターミナルモードに切換えます.
    waitstr "->"
    print   "文書入力状態となりました. 文書入力してください."
    terminal
【注意】
    terminal コマンドが終了すると monitor コマンドの設定に係わらず,以後画面
    表示の状態となります. logopen コマンドによりログ採取されている場合には,
    ターミナルモードでの画面表示はすべてログファイルに記録されます.


 waitstr
------------------------------------------------------------------------------
【書式】    waitstr     文字列式 [, 文字列式, ...]
【機能】
    指定された文字列並びの中のいずれかの文字列が受信できるまで待ちます. 文字
    列が受信できた場合には, 受信した文字列の文字列並びの中の位置番号を status
    変数に返します. さらに受信した文字列を含む受信文字列行全体を $status に返
    します. timeout コマンドによって指定された時間以内にいずれの文字列も受信
    できない場合には status に 0 が返されます. この時の $status の内容は不定
    です. 文字列は 10 個まで指定できます.
【使用例】
    ; モデムからのリザルトにより処理を分岐します.
    ; 接続した場合には MNP接続 かどうか表示します.
    waitstr "BUSY", "NO CARRIER", "NO DIALTONE", "CONNECT"
    switch( status )
    case 1:
        print   "話中です."
        goto    retry
    case 2:
        print   "回線接続失敗です."
        goto    retry
    case 3:
        print   "電話回線がつながっていません."
        exit
    case 4:
        if( instr($status, "REL") ) then
            printf  "MNP"        <-- 改行しないために printf を使用
        else
            printf  "非MNP"
        print   "モードで接続しました."
        break
    default:                        <-- case 0: に同じ
        print   "タイムアウトです."
        goto    retry
    endsw
【注意】
    waitstr コマンドは次のタイミングで指定文字列の受信検査を行っています.
     (1) 通信回線から一行受信した.
     (2) 通信回線から 255文字の文字列を受信した.
     (3) 通信回線から文字受信中, (1),(2)の条件が成り立つまでの間に約 1 秒間次
         の文字が受信できない.
    このため受信文字列が行間にまたがるような文字列の受信や受信行末コードが 
    255 文字以内にないような場合には期待したとおりに受信できませんので注意し
    てください. さらに受信待ち指定文字列の中に制御コードを指定したような場合
    にもうまく受信できない場合があります.

    waitstr コマンドで待つ文字列を受信できる時間が長くかかるような場合には, 
    timeout コマンドでのタイムアウトを長めに設定するようにしてください. そう
    でないと waitstr がタイムアウトとなり以後のプログラムの動作シーケンスに不
    具合が発生します. さもなくば,タイムアウト発生時の適切な処理をプログラム中
    で記述しておかなければいけません.


 waittime
------------------------------------------------------------------------------
【書式】    waittime    停止時間(秒)
【機能】
    コマンドの実行を指定時間停止します. 時間指定には数値式を参照します. 単位
    は秒です. この停止時間中に通信回線から受信された文字は処理されます. delay
    コマンドでは処理されずに受信バッファに格納されたままでしたが, 本コマンド
    では受信バッファからの読み出し動作は停止せずに実行されます.
【使用例】
    parameter   2400,8,1,0,1
    delay       100
    send        "ATZ\r" 
    waittime    2               ; ATZ のモデム初期化が確実に終了するよう 2 秒
    send        "ATDP ..."      ; 待ってからダイアルします.


 write
------------------------------------------------------------------------------
【書式】    write   ファイル番号, [文字列式 | 数値式, ...  ]
【機能】
    式の評価結果を指定ファイル番号のファイルに出力します. write コマンドは必
    ず最後に改行を出力します. 改行出力を抑制する方法はありません. 式が記述さ
    れていなければ改行のみ出力します. さらに式の評価結果の間に空白を出力する
    こともありません. 空白で区切ったり改行を抑制したりする場合には writef コ
    マンドを使用します.
【使用例】
    ; ボード読み出し中にタイトル行のみを header.msg ファイルに出力します.
    open    1, "header.msg", 1
    while(1)
        waitstr "Title", "E|Q) ->"
        if(status == 2) break
        if(status == 1) write   1, $status
    endwh
    close   1
【注意】
    出力された改行('\n')はディスクファイル上では '\r\n' となります.


 writef
------------------------------------------------------------------------------
【書式】    writef  ファイル番号, 書式指定文字列式 [,文字列式|数値式, ...]
【機能】
    書式付きで式の評価結果をファイルに出力します. writef コマンドは printf コ
    マンドとよく似たコマンドです. printf コマンドが画面を対象としているのに対
    し, writef コマンドはファイルを対象としていることです. 書式指定その他の制
    限事項は printf の項を参照してください.


 xflow
------------------------------------------------------------------------------
【書式】    xflow       スウィッチ
【機能】
    通信回線の XON/XOFFフロー制御を設定します. スウィッチは数値式で指定します
    が, その評価値が非0なら 制御有り, 0なら 制御無し に設定されます.
【使用例】
    ON  = 1
    OFF = 0
    xflow   ON
      .
      .
      .
    xflow   OFF
【注意】
    XON/XOFF フロー制御と RTS/CTS フロー制御は互いに独立したものです. 両フロ
    ーを設定することもできますし, どちらか一方だけを設定することも可能です.
    ただし, 現バージョンでは rscsflow のところで記述していますように RTS/CTS
    フロー制御は常に働いており XON/XOFF のみが設定された状態というものはあり
    ません.


第 7 章 cmsh の組み込み関数

    cmsh に組み込みの内部関数を示します.


 cnvstr()
------------------------------------------------------------------------------
【書式】    cnvstr( 数値式 )
【機能】
    数値式の評価値を10進数文字列に変換します. 数値式の値が負の場合には文字列
    先頭に '-' 符号が付加されます. 正の場合には何も付加されません.
【使用例】
    $date = cnvstr(  m * 100 + d )


 cnvval()
------------------------------------------------------------------------------
【書式】    cnvval( 文字列式 )
【機能】
    文字列式の評価値を数値に変換します. 文字列式の評価結果は10進数文字列でな
    ければ変換後の値は無意味なものとなります. 文字列先頭に +,- の符号を置くこ
    とは可能です.
【使用例】
    $d = "15"
    n = cnvval( "01" + $d )


 eof()
------------------------------------------------------------------------------
【書式】    eof( ファイル番号 )
【機能】
    open コマンドによってオープンされているファイルが終わりに達しているか検査
    し, 検査結果を返します. 指定ファイルが EOF なら非0が, EOF でなければ0で
    す.
【使用例】
    open 1, "test", 2
    while( !eof(1) )
        read $a
        print   $a
    endwh
    close 1


 exists()
------------------------------------------------------------------------------
【書式】    exists( パス名 )
【機能】
    パス名に合致するファイルまたはディレクトリが存在するか検査します. 存在す
    る場合には非0が, そうでない場合には0が返されます. パス名にはワイルド文
    字を含めることができます.
【使用例】
    if( exists( "log" ) ) then
        print "log という名前のファイルまたはディレクトリが存在します."
    endif


 getcts()
------------------------------------------------------------------------------
【書式】    getcts()
【機能】
    通信ポートの CTS 信号の状態を返します. モデムからの CTS が ON なら非0が,
    そうでない場合には0が返されます. 
【使用例】
    if( getcts() == 0 ) then
        print "モデムの準備ができていません. 確認してください."
        exit
    endif


 getdate()
------------------------------------------------------------------------------
【書式】    getdate( スウィッチ )
【機能】
    システム日付をスウィッチの値によって次の3形式のいずれかの文字列で返しま
    す.
      Switch  String Valu
        0       "Date Month DD YY"
        1       "YY/MM/DD"
        2       "YYMMDD"
【使用例】
    システム日付が 91年01月15日 の場合
        print   getdate(0)
        print   getdate(1)
        print   getdate(2)
    を実行すると,
        Tue Jan 15 91
        91/01/15
        910115
    となります.


 getdcd()
------------------------------------------------------------------------------
【書式】    getdcd()
【機能】
    通信ポートの DCD 信号の状態を返します. モデムからの DCD が ON なら非0が,
    そうでない場合には0が返されます. 
【使用例】
    if( getdcd() == 0) then
        print   "回線が切断されました."
    endif


 gettime()
------------------------------------------------------------------------------
【書式】    gettime( スウィッチ )
【機能】
    システム時刻をスウィッチの値によって次の3形式のいずれかの文字列で返しま
    す.
      Switch  String Valu
        0       "hh:mm AM/PM"
        1       "hh:mm:ss"
        2       "hhmmss"
【使用例】
    システム時刻が 15時23分36秒 の場合
        print   gettime(0)
        print   gettime(1)
        print   gettime(2)
    を実行すると,
        03:23 PM
        15:23:36
        152336
    となります.


 hasext()
------------------------------------------------------------------------------
【書式】    hasext( パス名 )
【機能】
    パス名の末尾に拡張子がついているか検査します. 拡張子がある場合には非0が,
    そうでない場合には0が返されます.
【使用例】
    printf  "%d %d", hasext("test"), hasext("test.exe")
    を実行すると
        0  1
    となります.


 haswild()
------------------------------------------------------------------------------
【書式】    haswild( パス名 )
【機能】
    パス名中にワイルド文字である '?','*' が含まれているか検査します. 含まれて
    いる場合には非0が, そうでない場合には0が返されます.
【使用例】
    $path = "test??.*"
    if( haswild( $path ) ) then
        print   "ワイルド文字があります."
    endif


 iinstr(), instr()
------------------------------------------------------------------------------
【書式】    iinstr( 文字列式1, 文字列式2 )
             instr( 文字列式1, 文字列式2 )
【機能】
    文字列式1中に文字列式2が含まれているか検査します. 含まれている場合には
    その開始位置が返されます. 含まれていない場合には 0 が返されます.
    iinstr() は大文字小文字の区別をせずに検査しますが, instr() は区別をしま
    す.
【使用例】
    printf  "%d  %d",iinstr("AbcDef", "BCD"), instr("AbcDef", "BCD")
    を実行すると
        2  0
    となります.


 isfile()
------------------------------------------------------------------------------
【書式】    isfile( ファイル名 )
【機能】
    ファイル名で指定するファイルが存在すれば非0を, 存在しない場合には0を返
    します.
【使用例】
    if( ! isfile("910101.log") ) then
        print   "ファイルがありません."
    endif


 leftstr()
------------------------------------------------------------------------------
【書式】    leftstr( 文字列式, 長さ )
【機能】
    文字列式を評価した結果の文字列の先頭より, 指定長さ分の文字列を返します.
【使用例】
    print   leftstr( "ABCDEFGH", 4 )
    を実行すると
        ABCD
    となります.


 midstr()
------------------------------------------------------------------------------
【書式】    midstr( 文字列式, 開始位置, 長さ )
【機能】
    文字列式を評価した結果の文字列の開始位置から始まる文字位置から指定長さ分
    の文字列を返します.
【使用例】
    print   midstr( "ABCDEFGH", 3, 4 )
    を実行すると
        CDEF
    となります.


 rightstr()
------------------------------------------------------------------------------
【書式】    rightstr( 文字列式, 長さ )
【機能】
    文字列式を評価した結果の文字列の末尾より, 指定長さ分の文字列を返します.
【使用例】
    print   rightstr( "ABCDEFGH", 4 )
    を実行すると
        EFGH
    となります.


 strlen()
------------------------------------------------------------------------------
【書式】    strlen( 文字列式 )
【機能】
    文字列式を評価した結果の文字列の長さを返します.
【使用例】
    print   strlen("ABC")
    を実行すると
        3
    となります.


第 8 章  プログラムサンプル

    BBS 『ATLAS』 への自動アクセスを題材にプログラム例を示します. プ
    ログラム例中のID, パスワード, やモデム制御の部分を自分のものに置き換え
    ればそのまま使用できます. エディタで切り出してご利用ください.

    『ATLAS』は, 私が個人運営している草の根BBSのネット名です。このB
    BSに興味をお持ちの方はこのドキュメント末尾に案内がありますので一度ゲス
    トアクセスしてくださると幸いです.


【1】  自動ログインを行う

    ;
    ;   ATLAS 自動ログイン
    ;
    ;-------------------------------------------------------------------------
    ;   定数変数の設定
    ;-------------------------------------------------------------------------

        OFF = SUCCESS = SJIS = CR = 0
        ON = FAIL  = JIS = !OFF
        CRLF = 2

    ;-------------------------------------------------------------------------
    ;   ID, PASSWORD 等の設定(この部分を書き換えて利用する)
    ;-------------------------------------------------------------------------

        speed = 2400
        port = 1
        $mdminit = "atz\r"
        $mdmset = "atx4\\n3\r"
        $dial = "atdp 0785815610\r"
        $atlasid = "ATL00xxx\r"
        $atlaspsw = "xxxxxxxx\r"

    ;-------------------------------------------------------------------------
    ;   通信ポート等の設定
    ;-------------------------------------------------------------------------

        parameter speed, 8, 1, 0, port  ; 8bit, 1stop, non_parity
        xflow   ON                      ; XON/XOFF flow controle on
        rscsflow ON                     ; RTS/CTS flow controle on
        code    ON, SJIS                ; S controle off, Using Sjis kanji
        termcode CR, CRLF               ; terminate charactor type setting
        monitor ON                      ; display monitoring on

    ;-------------------------------------------------------------------------
    ;   モデムの準備チェック
    ;-------------------------------------------------------------------------

        if( getcts() == 0 ) then
            print   "モデムが準備できていません. 確認をしてください."
            while( !getcts() )      ; モデムレディになるまでループ
            endwh
        endif

    ;-------------------------------------------------------------------------
    ;   接続リトライ回数等の設定
    ;-------------------------------------------------------------------------

        retrys = 3                      ; リトライ回数 3 回
        retrytime = 5                   ; リトライ間隔 5 秒

    ;-------------------------------------------------------------------------
    ;   ホストへアクセス
    ;-------------------------------------------------------------------------

        print   "ATLASに接続します."

        while( (retrys = retrys -1) >= 0 )

            send    $mdminit            ; モデム初期化
            waittime    2
            send    $mdmset             ; モデム設定
            waittime    2
            send    $dial               ; ダイヤリング

            ; 回線接続待ち
            timeout     60
            waitstr     "BUSY", "NO CARRIER", "NO DIALTONE", "CONNECT"
            if(status == 4) then
                if(instr($status, "REL")) then
                    mnp = ON
                else
                    mnp = OFF
                endif
            else
                switch( status )
                case 1:
                    print   "話中です."
                    break
                case 2:
                    print   "接続失敗です."
                    break
                case 3:
                    print   "NTT からのダイヤルトーンが検出できません."
                    break
                default:
                    print   "タイムアウトです."
                endsw
                waittime    retrytime
                continue
            endif

            ; ログイン手続き
            timeout 5
            waitstr "User ID ="
            if( status ) then
                send    $atlasid
                waitstr "PASSWORD="
                if( status  ) then
                    send    $atlaspsw
                    break
                endif
            endif

            print   "ログイン失敗です."
            dtr     OFF                 ; 回線強制切断
            waittime    retrytime
            dtr     ON
            continue

        endwh

        if(retrys < 0) then
            print   "規定回数リトライしましたが全て失敗です."
            exit    FAIL
        else
            print   "ログインしました."
        endif

    ;-------------------------------------------------------------------------
    ;  マニュアル操作に切換え
    ;-------------------------------------------------------------------------

        terminal
        exit    SUCCESS

    ;--- End of Sample Program #1 --------------------------------------------


【2】 「一般ボード」,「SIG」,「電子会議」の連続読み出し
    トップメニューから, 「一般ボード」,「SIG」,「電子会議」の全ボードを
    P コマンド を使って連続読み出しを行います. ここでは サブルーチンを使用して
    みます.

    ;-------------------------------------------------------------------------
    ;   トップメニューのコマンド入力のところから始まるものとします.
    ;   (ホストから "Top menu select (1-8,Q,?) ->"の文字列を受信した状態)
    ;-------------------------------------------------------------------------

        logopen "atlas.log", 1

        timeout 600             ; タイムアウトを大きく設定
        call    read_board(3, "0 1 1 1 1 1 1 1 ")   ; 一般ボード
        call    read_board(4, "0 1 1 0 0 0 0 0 ")   ; SIG
        call    read_board(5, "0 1 0 0 0 0 0 0 ")   ; 電子会議

        logclose

        send    "Q\r"
        exit    SUCCESS

    ;-------------------------------------------------------------------------
    ;
    ;   sub read_bord(no, $board)
    ;
    ;       一掲示板の連続読み出しサブルーチン
    ;
    ;  (引数)
    ;     no        掲示板の種類
    ;                   3  一般ボード
    ;                   4  SIG
    ;                   5  電子会議
    ;     $board    掲示板内の各ボードの読み出し実行フラグ
    ;               "1 1 1 1 1 1 1 1" .... 8 個のボード全部読み出す
    ;               "0 0 1 0 0 0 0 0" .... 3 番目のボードだけ読み出す
    ;
    ;   (注意)
    ;     ・ トップメニューが表示されている時点で呼び出すこと.
    ;     ・ このルーチンから戻った時はトップメニューの状態である.
    ;     ・ タイムアウトの検査は省略している.
    ;-------------------------------------------------------------------------

    sub read_board(no, $board)
        local   n

        ;
        ; Top menu から掲示板を選択
        ;
        send    cnvstr(no), "\r"
        waitstr "(1-8,E,Q,?) ->"        ; 個別のボード選択のプロンプト待ち

        ;
        ; 最初のボードの読み出し
        ;
        n = 1
        while(n <= 8)
            if($board[n] != "0") then   ; $boardのリスト要素を検査
                break
            endif
            n = n +1
        endwh
        send    cnvstr(n), "\r"
        waitstr "|S|E|Q|? ) ->"
        send    "P\r"               ; P コマンド送信
        waitstr "|S|E|Q|? ) ->"

        ;
        ; 次のボードから最後のボードまで読み出し
        ;
        n = n +1
        while(n <= 8)
            if($board[n] == "0") then
                n = n + 1
                continue
            endif
            sendf   "C%d\r", n          ; 次のボードへ切換え
            waitstr "|S|E|Q|? ) ->"
            send    "P\r"               ; P コマンド送信
            waitstr "|S|E|Q|? ) ->"
        endwh

        ;
        ;   読み出し終了
        ;
        send    "E\r"
        waitstr "(1-8,Q,?) ->"      ; Top menu 待ち

    endsub

    ;--- End of Sample Program #2 --------------------------------------------


【3】 文書アップロード
    掲示板への書き込みや電子メールの文書をファイルアップロードするサブルーチ
    ンです.

    ;-------------------------------------------------------------------------
    ;
    ;   sub up_load($filename)
    ;
    ;       文書自動アップロードサブルーチン
    ;
    ;  (引数)
    ;     $filename     アップロードする文書ファイル名
    ;
    ;   (注意)
    ;     ・ 掲示板なら W コマンド, 電子メールなら S コマンド 送信直後に呼び出す.
    ;     ・ タイムアウトの検査は省略している.
    ;-------------------------------------------------------------------------

    sub up_load($filename)

        if( exists($filename) == 0 ) return     ; file doesn't exist ?

        waitstr "全角24文字以内"
        waitstr "->"                ; 入力開始プロンプト待ち

        fsend   $filename, 0        ; 行間ウェイト 0msec にてアップ
        send    ".E\r"              ; 入力終了送信

        waitstr "( Y or N )->"      ; 修正・編集を行いますか。 
        send    "N\r"
        waitstr "( Y or N )->"      ; 確認表示を行いますか。
        send    "N\r"
        waitstr "( Y or N ) ->"     ; よろしいですか?
        send    "Y\r"

    endsub

    ;--- End of Sample Program #3 --------------------------------------------


【4】 ファイルダウンロード
    フリーソフトウェアをダウンロードするサブルーチンです.

    ;-------------------------------------------------------------------------
    ;   トップメニューのコマンド入力のところから始まるものとします.
    ;   (ホストから "Top menu select (1-8,Q,?) ->"の文字列を受信した状態)
    ;
    ;   予め prgrm.nmb というファイルに, ダウンロードしたいプログラム番号が
    ;   次のように書き込まれているものとします.
    ;
    ;   prgrm.nmb
    ;    1: 200 220 221  <--- 番号を空白で区切って一行に書いておく
    ;    2: 100 128      <--- 複数行に分けて書いてあってもよい.
    ;
    ;   ホストとの接続は MNP により行われるものとし, FT.EXE(ATLAS 専用転送
    ;   プログラム)が カレントディレクトリ または PATH 指定された ディレクトリ にあるもの
    ;   とします. 受信ファイルは カレントディレクトリ に作成されますが, ダウンロード
    ;   するファイルと同名のファイルが カレントディレクトリ には存在しないものとしま
    ;   す.
    ;
    ;-------------------------------------------------------------------------

        mnpflg = 1          ; MNP 接続状態フラグ
        result  = -1
        if( exists("prgrm.nmb")) then
            open 1, "prgrm.nmb", 2
                while( !eof(1) )
                    read 1, $no
                    if( (result = prgrm_download($no)) == -1 )
                        break
                endwh
            close 1
        endif

        if(result == 0) then
            exit    SUCCESS
        else
            exit    FAIL
        endif

    ;-------------------------------------------------------------------------
    ;
    ;   func    prgrm_download(mnp, $no)
    ;
    ;       プログラムファイルをダウンロードする
    ;
    ;   (引数)
    ;       mnp     MNP 接続なら 非0, 非MNP なら 0
    ;       $no     ダウンロードするファイル番号リスト
    ;
    ;   (注意)
    ;      ・ 外部プログラム FT.EXE により MNP 接続なら ymodem_g_batch にて,
    ;        非MNP 接続なら ymodem_batch にて カレントディレクトリ にダウンロードする.
    ;      ・ 失敗なら -1 を, 成功なら 0 を返す.
    ;      ・ トップメニューの状態から呼び出され, トップメニューの状態に戻る.
    ;        ただし, エラー発生時はこの限りでない.
    ;
    ;-------------------------------------------------------------------------

    func prgrm_down_load(mnp, $no)

        send    "6\r"       ; ライブラリーを選択
        waitstr "(L,U,D,F,E,Q,?) ->"

        send    "D ", $no, "\r"         ; ダウンロードプログラム指定

        waitstr "(L,U,D,F,E,Q,?) ->", "使用するプロトコル ->"

        if( status <= 1 ) then          ; ダウンロードできない時間帯であった.
            send    "E\r"               ; トップメニューに戻る
            waitstr "(1-8,Q,?) ->"      ; Top menu 待ち
            return  -1
        endif

        if( mnp ) then
            send    "6\r"               ; ymodem_g_batch
        else
            send    "4\r"               ; ymodem_batch
        endif

        waitstr     "(Y or N) ->"       ; 受信準備確認
        send        "Y\r"

        waitstr     "送信してください"
        if( mnp ) then
            exec    "ft.exe", "-rygb"       ; FT.EXE の起動(yg_batch)
        else
            exec    "ft.exe", "-ryb"        ; FT.EXE の起動(y_batch)
        endif

        waittime    2
        send        "\r"
        waitstr     "(L,U,D,F,E,Q,?) ->"
        send    "E\r"               ; トップメニューに戻る
        waitstr "(1-8,Q,?) ->"      ; Top menu 待ち
        return  0

    endfunc

    ;--- End of Sample Program #4 --------------------------------------------


【5】 自動読み出し
    ATLASにアクセスし, 全ボードを読み出すプログラムです. ただし,「お知ら
    せ」や「オンラインマニュアル」は除きます. また 「プログラムライブラリー」
    については プログラムリストの最新一ページだけをダウンロードします.
    atlas.log というログファイルが生成されます.

    ;
    ;   ATLAS 自動ダウンロード
    ;
    ;   定数変数の設定
        OFF = SUCCESS = SJIS = CR = 0
        ON = FAIL  = JIS = !OFF
        CRLF = 2

    ;   ID, PASSWORD 等の設定(この部分を書き換えて利用する)
        speed = 2400
        port = 1
        $mdminit = "atz\r"
        $mdmset = "atxxxxxxxxxxxxxx\r"
        $dial = "atdp 0785815610\r"
        $atlasid = "ATL00xxx\r"
        $atlaspsw = "xxxxxxxx\r"

    ;   通信ポート等の設定
        parameter speed, 8, 1, 0, port  ; 8bit, 1stop, non_parity
        xflow   ON                      ; XON/XOFF flow controle on
        rscsflow ON                     ; RTS/CTS flow controle on
        code    ON, SJIS                ; S controle off, Using Sjis kanji
        termcode CR, CRLF               ; terminate charactor type setting
        monitor ON                      ; display monitoring on

    ;   モデムの準備チェック
        if( getcts() == 0 ) then
            print   "モデムが準備できていません. 確認をしてください."
            while( !getcts() )      ; モデムレディになるまでループ
            endwh
        endif

    ;   接続リトライ回数等の設定
        retrys = 3                      ; リトライ回数 3 回
        retrytime = 5                   ; リトライ間隔 5 秒

    ;   ホストへアクセス
        print   "ATLASに接続します."
        while( (retrys = retrys -1) >= 0 )
            send    $mdminit            ; モデム初期化
            waittime    2
            send    $mdmset             ; モデム設定
            waittime    2
            send    $dial               ; ダイヤリング
            timeout     60
            waitstr     "BUSY", "NO CARRIER", "NO DIALTONE", "CONNECT"
            if(status == 4) then
                if(instr($status, "REL")) then
                    mnp = ON
                else
                    mnp = OFF
                endif
            else
                switch( status )
                case 1:
                    print   "話中です."
                    break
                case 2:
                    print   "接続失敗です."
                    break
                case 3:
                    print   "NTT からのダイヤルトーンが検出できません."
                    break
                default:
                    print   "タイムアウトです."
                endsw
                waittime    retrytime
                continue
            endif
            remove  "atlas.log"         ; この行は必ずしも必要ではない
            logopen "atlas.log", 0      ; ログ(over write モード)の書き込み
            timeout 10                  ; 開始
            waitstr "User ID ="
            if( status ) then
                send    $atlasid
                waitstr "PASSWORD="
                if( status  ) then
                    send    $atlaspsw
                    break
                endif
            endif
            print   "ログイン失敗です."
            dtr     OFF                 ; 回線強制切断
            waittime    retrytime
            dtr     ON
            continue
        endwh
        if(retrys < 0) then
            logclose
            print   "規定回数リトライしましたが全て失敗です."
            call abort_exit
        endif

    ;   「受信メール」や「簡易お知らせ」等の読み出し
    *opening
        waitstr "行いますか?", "SYSOP", "会員の方", "□□□"
        if(status == 1) then
            goto read_mail
        elseif(status == 2) then
            goto sysop_msg
        elseif(status == 3) then
            goto user_msg
        elseif(status == 4) then
            goto skip_picture
        else
            call abort_exit()
        endif

    ;   メールを読み出す. バイナリメールが送られてきていてもバイナリの読
    ;   み出しは行わない.
    ;   自動返信用のメールファイル(REPLY.TXT)がカレントディレクトリに
    ;   準備されていれば返信を行う.
    *read_mail
        send    "Y\r"           ; メール読み出し
        while(1)
            waitstr "ファイルを","よろしいですか?","送信しますか?","SYSOP","会員の方","□□□"
            switch(status)
            case 1:             ; バイナリ読み出し問い合わせ
                send    "N\r"   ; 読み出さないでスキップ
                continue
            case 2:             ; 削除問い合わせ
                send    "N\r"   ; メールの削除はしないで保存しておく
                continue
            case 3:             ; 返信問い合わせ
                if( exists("REPLY.TXT") ) then  ; 返信用ファイルの準備検査
                    send    "Y\r"
                    call up_load("REPLY.TXT")   ; 返信メールアップロード
                    waitstr "同封しますか"
                    send    "N\r"               ; バイナリ同封をしない
                    waitstr "よろしいですか"
                    send    "Y\r"               ; 返信の送信
                    waitstr "確かに"            ; 送信確認を待つ
                else
                    send    "N\r"       ; 返信ファイルがないので返信しない
                endif
                continue
            case 4:
                goto sysop_msg
            case 5:
                goto user_msg
            case 6:
                goto skip_picture
            default:
                call abort_exit()
            endsw
        endwh

    ;   SYSOPからのお知らせを読み出す
    *sysop_msg
        send    "Y\r"
        while(1)
            waitstr "<More>", "会員の方", "□□□"
            switch(status)
            case 1:
                send    " "
                break
            case 2:
                goto user_msg
            case 3:
                goto skip_picture
            default:
                call abort_exit()
            endsw
        endwh

    ;   会員からのお知らせを読み出す
    *user_msg
        send    "Y\r"
        while(1)
            waitstr "<More>", "□□□"
            switch(status)
            case 1:
                send    " "
                break
            case 2:
                goto skip_picture
            default:
                call abort_exit()
            endsw
        endwh

    ;   ESC を送信してエスケープ画の表示をスキップする. ただし,
    ;   MNP接続されている時はスキップが効かないために ESC 送
    ;   信は行わない.
    *skip_picture
        if(mnp == OFF) send "\x1b"
        waitstr "Push return key"
        send    "\r"

    ;   トップメニュー
    *top_menu
        timeout 600         ; 文字列待ちタイムアウトタイマーを10分に設定
        waitstr "メニュー"
        if(mnp == OFF) send "\x1b"
        waitstr "(1-8,Q,?) ->"      ; トップメニューのコマンドプロンプト待ち

    ;   掲示板読み出し
        call    read_board(3, "0 1 1 1 1 1 1 1 ")   ; 一般ボード
        call    read_board(4, "0 1 1 0 0 0 0 0 ")   ; SIG
        call    read_board(5, "0 1 0 0 0 0 0 0 ")   ; 電子会議

    ;   ライブラリーフォーラムの読み出し
        send    "6\r"
        waitstr "?) ->"             ; ライブラリーのコマンドプロンプト待ち
        send    "F\r"               ; フォーラムを選択
        waitstr "Q|? ) ->"          ; フォーラムのコマンドプロンプト待ち
        send    "P\r"               ; 未読読み出し
        waitstr "Q|? ) ->"
        send    "E\r"               ; フォーラムを終了
        waitstr "?) ->"             ; ライブラリーのコマンドプロンプト待ち

    ;   ライブラリーリストの読み出し(最新の1頁のみ)
        send    "L\r"               ; L コマンドの投入
        waitstr "<more>"            ; <more> プロンプト待ち
        send    "\x1b"              ; ESC の投入
        waitstr "?) ->"             ; ライブラリーのコマンドプロンプト待ち

    ;   ログアウト
    *quit
        logclose
        send    "Q\r"
        waittime    1
        exit    SUCCESS

    sub abort_exit()
        print
        print   "自動シーケンスに異常が発生しました."
        print   "通信を強制終了します."
        logclose
        onexit  0
        exit    FAIL
    endsub

    sub read_board(no, $board)
        local   n
        send    cnvstr(no), "\r"
        waitstr "(1-8,E,Q,?) ->"        ; 個別のボード選択のプロンプト待ち
        n = 1
        while(n <= 8)
            if($board[n] != "0") then   ; $boardのリスト要素を検査
                break
            endif
            n = n +1
        endwh
        send    cnvstr(n), "\r"
        waitstr "|S|E|Q|? ) ->"
        send    "P\r"               ; P コマンド送信
        waitstr "|S|E|Q|? ) ->"
        n = n +1
        while( n <= 8 )
            if($board[n] == "0") then
                n = n + 1
                continue
            endif
            sendf   "C%d\r", n          ; 次のボードへ切換え
            waitstr "|S|E|Q|? ) ->"
            send    "P\r"               ; P コマンド送信
            waitstr "|S|E|Q|? ) ->"
        endwh
        send    "E\r"
        waitstr "(1-8,Q,?) ->"      ; Top menu 待ち
    endsub

    sub up_load($filename)
        if( exists($filename) == 0 ) return     ; file doesn't exist ?
        waitstr "全角24文字以内"
        waitstr "->"                ; 入力開始プロンプト待ち
        fsend   $filename, 0        ; 行間ウェイト 0msec にてアップ
        send    ".E\r"              ; 入力終了送信
        waitstr "( Y or N )->"      ; 修正・編集を行いますか。 
        send    "N\r"
        waitstr "( Y or N )->"      ; 確認表示を行いますか。
        send    "N\r"
        waitstr "( Y or N ) ->"     ; よろしいですか?
        send    "Y\r"
    endsub

    ;--- End of Sample Program #5 --------------------------------------------



-- 『ATLAS』の紹介 ------------------------------------------------------

   アクセス番号:078−XXX−XXXX
   入会金,会費 :無 料
   入会方法  :オンラインサインアップ
   通信パラメータ :N81XN
   ゲストアクセス: ID = GUEST, PASSWORD = ATLAS
   ファイル転送プロトコル:XMODEM(SUM, CRC), YMODEM(batch, g, g_batch)
                   MLINK, ATLAS_LINK(オリジナル)
   サービス内容:電子掲示板、電子メール、電子会議、ソフトウェアライブラリ
   ホストプログラム:オリジナル
   会員数(92.12 現在):1100名

--------------------- End of CMSH.DOC ----------------------------------------