# 画面設計書 18-配布ファイルダウンロード画面

## 概要

本ドキュメントは、FreeBSD bsdinstallインストーラにおける配布ファイルダウンロード画面の設計書である。ネットワーク経由で配布ファイル（base.txz、kernel.txz等）をダウンロードし、進捗をプログレスバーで表示するC言語実装の画面について記述する。

### 本画面の処理概要

この画面では、BSDINSTALL_DISTSITE環境変数で指定されたURLから配布ファイルをダウンロードし、リアルタイムでmixedgaugeプログレスバーに進捗を表示する。

**業務上の目的・背景**：ネットワークインストールにおいて、FreeBSDのベースシステムおよびオプションコンポーネントの配布ファイルをミラーサイトからダウンロードする必要がある。本画面はダウンロードの進捗を視覚的に表示し、エラー発生時には適切なメッセージを表示してユーザに状況を伝える。

**画面へのアクセス方法**：autoスクリプトのインストール実行フロー内で、未取得の配布ファイルが存在する場合にfetchmissingdistsから呼び出される。`bsdinstall distfetch` コマンドで実行される。

**主要な操作・処理内容**：
1. DISTRIBUTIONS環境変数から配布ファイル一覧をパースする
2. BSDINSTALL_DISTSITEとファイル名からダウンロードURLを構築する
3. 各ファイルについてfetchStatURLでサイズを事前取得し、全体の進捗計算に使用する
4. fetchXGetURLで各ファイルを順次ダウンロードし、4096バイトずつ読み書きする
5. bsddialog mixedgaugeで個別ファイルの進捗と全体の進捗を同時に表示する
6. ダウンロード完了または失敗時に結果を表示する

**画面遷移**：
- 遷移元：ミラーサイト選択後のインストール実行フロー
- 遷移先（成功）：チェックサム検証画面（No.19）
- 遷移先（失敗）：エラーメッセージ表示後、インストーラのエラーハンドリングへ

**権限による表示制御**：権限による表示制御はない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 91 | libfetch | 主機能 | libfetchを使用した配布ファイルのネットワークダウンロード・進捗表示 |
| 74 | パッケージ管理支援 | 補助機能 | 配布ファイルURLの解決とダウンロード先管理 |

## 画面種別

進捗表示（mixedgauge）

## URL/ルーティング

TUIベースのbsddialogインターフェース。URLは存在しない。
- 呼び出し：`bsdinstall distfetch`
- 実体バイナリ：`usr.sbin/bsdinstall/distfetch/distfetch.c` からコンパイル

## 入出力項目

本画面にユーザ入力項目はない。進捗表示のみ。

| 項目名 | 入出力 | 型 | 必須 | 初期値 | 説明 |
|--------|--------|------|------|--------|------|
| DISTRIBUTIONS | 入力（環境変数） | 文字列 | はい | - | ダウンロード対象の配布ファイル一覧（スペース区切り） |
| BSDINSTALL_DISTSITE | 入力（環境変数） | 文字列 | はい | - | ダウンロード元のベースURL |
| BSDINSTALL_DISTDIR | 入力（環境変数） | 文字列 | はい | - | ダウンロード先ディレクトリ |

## 表示項目

| 項目名 | 表示位置 | 説明 |
|--------|----------|------|
| バックタイトル | 画面上部 | "$OSNAME Installer" |
| タイトル | ダイアログタイトル | "Fetching Distribution" |
| メッセージ | mixedgauge内 | "Fetching distribution files..." |
| 全体進捗バー | mixedgauge | 全ファイルの合計進捗率 |
| 個別ファイル進捗 | mixedgaugeミニバー | 各配布ファイルの個別ダウンロード進捗 |
| 接続メッセージ | 初期表示 | "Connecting to server. Please wait..." |

## イベント仕様

### 1-ダウンロード処理（自動実行）

1. 「Connecting to server. Please wait...」を表示する（行148-149）
2. 全ファイルのサイズをfetchStatURLで事前取得する（行152-160）
3. 各ファイルについて以下を繰り返す：
   a. fetchXGetURLでHTTP/FTP接続を開く（行172）
   b. ローカルファイルをfopenで作成する（行185）
   c. 4096バイトずつfread/fwriteでデータを転送する（行197-226）
   d. 転送量に応じてmixedgaugeのプログレスバーを更新する（行221-225）
   e. 完了時にDONE、失敗時にFAILEDをミニバーに設定する（行228-243）
4. 全ダウンロード完了メッセージを表示する（行249-250）

### 2-エラー発生時

- URL取得エラー：エラーメッセージボックス表示（行174-178）
- ファイル作成エラー：エラーメッセージボックス表示（行187-191）
- 転送途中エラー：エラーメッセージボックス表示（行228-239）

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ダウンロード完了 | $BSDINSTALL_DISTDIR/{ファイル名} | WRITE | 配布ファイルの書き込み |

## メッセージ仕様

| 種別 | 条件 | メッセージ |
|------|------|-----------|
| 情報 | 接続中 | "Connecting to server. Please wait..." |
| 情報 | ダウンロード中 | "Fetching distribution files..." |
| 情報 | 完了 | "Fetching distribution completed" |
| エラー | URL取得失敗 | "Error (URL) while fetching {url}: {エラー文字列}" |
| エラー | ファイル作成失敗 | "Error (fopen) while fetching {url}: {エラー文字列}" |
| エラー | 転送途中失敗 | "Error (undone/libfetch) while fetching {url}: {エラー文字列}" |

## 例外処理

| 条件 | 動作 |
|------|------|
| DISTRIBUTIONS環境変数未設定 | errxで即座に終了 |
| メモリ不足 | errxで即座に終了 |
| BSDINSTALL_DISTDIRへのchdir失敗 | エラーメッセージ表示後EXIT_FAILURE |
| URL接続失敗 | 該当ファイルをFAILED表示し次のファイルへ |
| 転送途中切断 | 該当ファイルをFAILED表示し次のファイルへ |
| 全ファイル成功でない場合 | EXIT_FAILUREを返す |

## 備考

- C言語実装でlibfetch(3)ライブラリを使用している
- 転送ブロックサイズは4096バイト固定（行128）
- 進捗計算は2通り：全ファイルサイズが事前取得できた場合はバイト数ベース、できない場合はファイル数ベース
- mixedgaugeの最小幅は40文字に設定（行166）
- 失敗したファイルがあっても他のファイルのダウンロードは継続される

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | distfetch.c | `usr.sbin/bsdinstall/distfetch/distfetch.c` | main関数内のurls配列、ndists、minilabel/miniperc配列の構造を理解する |

**読解のコツ**: libfetchのfetchStatURL/fetchXGetURL APIとurl_stat構造体を把握すること。bsddialogのmixedgaugeはminilabel（ラベル配列）とminiperc（進捗率配列）で各ミニバーを制御する。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | distfetch.c | `usr.sbin/bsdinstall/distfetch/distfetch.c` | 行46-106のmain関数。環境変数からのパラメータ取得、URL配列構築、fetch_files呼び出し |

**主要処理フロー**:
1. **行57-64**: DISTRIBUTIONS環境変数をパースし配布ファイル数をカウント
2. **行80-84**: 各ファイルのURLを `{BSDINSTALL_DISTSITE}/{ファイル名}` で構築
3. **行86-94**: BSDINSTALL_DISTDIRへのchdir
4. **行96**: fetch_files関数の呼び出し
5. **行105**: 全ファイル成功判定

#### Step 3: ダウンロード処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | distfetch.c | `usr.sbin/bsdinstall/distfetch/distfetch.c` | 行108-255のfetch_files関数。サイズ事前取得、ファイル順次ダウンロード、進捗更新の処理 |

### プログラム呼び出し階層図

```
bsdinstall distfetch (usr.sbin/bsdinstall/distfetch/distfetch.c)
    |
    +-- main()
           |
           +-- bsddialog_init() / bsddialog_backtitle()
           +-- URL配列構築 (DISTRIBUTIONS + BSDINSTALL_DISTSITE)
           +-- chdir(BSDINSTALL_DISTDIR)
           |
           +-- fetch_files()
                  |
                  +-- fetchStatURL() (各ファイルサイズ取得)
                  +-- [ファイルループ]
                         +-- fetchXGetURL() (HTTP/FTP接続)
                         +-- fopen() (ローカルファイル作成)
                         +-- fread/fwrite ループ (4096バイト転送)
                         +-- bsddialog_mixedgauge() (進捗更新)
                         +-- fclose() (両ファイル閉じる)
```

### データフロー図

```
[入力]                       [処理]                          [出力]

DISTRIBUTIONS ---------> URL構築 ---------> urls配列
BSDINSTALL_DISTSITE -->                        |
                                               v
ネットワーク(ミラー) --> fetchXGetURL --> fread(4096B) --> fwrite --> ローカルファイル
                              |                                   ($BSDINSTALL_DISTDIR/)
                              v
                        bsddialog_mixedgauge --> TUI進捗表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| distfetch.c | `usr.sbin/bsdinstall/distfetch/distfetch.c` | ソース | 配布ファイルダウンロードのメインプログラム（256行） |
| opt_osname.h | `usr.sbin/bsdinstall/distfetch/opt_osname.h` | ヘッダ | OSNAMEマクロ定義（ビルド時生成） |
| auto | `usr.sbin/bsdinstall/scripts/auto` | ソース | fetchmissingdists経由での呼び出し元 |
| mirrorselect | `usr.sbin/bsdinstall/scripts/mirrorselect` | ソース | BSDINSTALL_DISTSITEの設定元 |
