MOSA Multi-OS Software Artists

MOSAはソフトウェア開発者を支援します

  • iPhone/iPod touch アプリ紹介
  • MOSA掲示板
  • 活動履歴
  • About MOSA(English)

MOSA Developer News[MOSADeN=モサ伝]第252号

2007-05-22

目次

  • 「「Wonderful Server Life」    第47回    田畑 英和
  • 小池邦人の「Carbon API 徒然草」
  • ターミナルの向こうから      第2回  海上 忍 
  • 書籍紹介             エンジニアのための時間管理術

「Wonderful Server Life」  第47回  田畑 英和

  〜アカウント編〜

 それでは今回はアカウント編のしめくくりとして、コンピュータリストの応用を解説したいと思います。コンピュータリストには、コンピュータへのアクセスを制限する機能があり、この機能を利用すれば任意のコンピュータへのログインを一部のユーザだけに制限することができます。

◇コンピュータリストのアクセス制御
 アクセスを設定するには、「ワークグループマネージャ」を起動し、ツールバーから「アカウント」をクリックして、画面左側にコンピュータリストの一覧を表示します。
 次にアクセス制御を設定したいコンピュータリストを選択し、右側の画面で「アクセス」をクリックします。アクセス制御はグループ単位で行うため、あらかじめアクセスを許可したいユーザをまとめたグループを作成しておく必要があります。
 デフォルトの状態では「すべてのグループがコンピュータを使用できる」ように設定されているため、アクセス制御はなにも行われていません。アクセス制御を行うには「以下のグループに限定する」を選択し、アクセスを許可するグループを登録します。「+」ボタンをクリックすると登録済みのグループが画面端に一覧で表示されますので、ここからアクセスを許可したいグループをリストにドラッグ&ドロップします。

・アクセスを許可するグループの追加
http://homepage.mac.com/htabata/MXS10.3/img/WGM_Computer/WGM_Computer_06.png

 グループを追加したら、画面右下の「保存」ボタンをクリックします。これで、アクセスを制限したコンピュータリストに含まれるコンピュータには、追加したグループのメンバーしかアクセスができなくなります。
 なお、ここで実施させるアクセス制御はログインウインドウに対するアクセス制御です。つまり、アクセスを許可したグループに所属するユーザしか、ログインウインドウからログインできなくなります。一方、AFPやSSHによる接続はここでのアクセス制御の影響を受けませんので、これまでどおりネットワーク経由でのアクセスが可能です。

◇サービスのアクセス制御
 コンピュータリストのアクセス制御は、ログインウインドウに対するアクセス制御に限定されます。「サーバ管理」を使ってサービスのACLを設定すれば、各サービスごとのアクセス制御を実施することもできます。アクセス制御の設定が可能なサービスは次のとおりです。

  AFP、FTP、iChat、SSH、VPN、Web、Windows、
  Xgrid、ウェブログ、メール、ログインウインドウ

 設定方法ですが、「サーバ管理」で設定を行うサーバに接続し、左側のリストでホスト名をクリックした後、「設定(右下)」>「アクセス(右上)」の順でクリックします。
 まず、デフォルトの状態ですが、デフォルトではすべてのサービスに同じアクセス権が使用されるようになっており、かつすべてのユーザとグループにアクセスが許可されています。つまりいっさいサービスレベルでのアクセス制御は行われていないということです。

・サービスACLのデフォルト設定
http://homepage.mac.com/htabata/MXS10.3/img/SACL/SACL_ADMIN_01.png

 サービスごとに異なるアクセス制御を行いたい場合にはまず「すべてのサービスに同じアクセス権を使用する」のチェックを外します。次にアクセス制御を行いたいサービスを左のリストから選択し、「以下のユーザとグループのみを許可する」を選択します。
 あとは画面下の「+」ボタンでユーザとグループのリストを表示し、アクセスを許可したい、ユーザまたはグループを右側のリストに追加します。

・サービスACLの設定
http://homepage.mac.com/htabata/MXS10.3/img/SACL/SACL_ADMIN_02.png

 以上の設定を行えば、ユーザまたはグループ単位で各サービスへのアクセスを制御することができます。

 これで「ワークグループマネージャ」では、グループ単位でログインウインドウのアクセス制御が、「サーバ管理」では、ユーザ/グループ単位で各サービスのアクセス制御ができるようになりました。

 ところでサービスのACLで設定可能なサービスにもログインウインドウが含まれていますが、「ワークグループマネージャ」と「サーバ管理」で異なる設定をした場合どうなるでしょうか。
 例えば、「ワークグループマネージャ」では特定のグループのみのアクセスを許可し、「サーバ管理」では「ワークグループマネージャ」でアクセスを許可したグループには含まれないユーザに対してログインウインドウへのアクセスを許可したとします。この場合は、どちらかでアクセスが許可されていなければ、もう片方で許可しても、最終的にはアクセスが許可されないということになります。
 ルールとしては分っていても、混乱のもとになりやすいところですので、ログインウインドウのアクセス制御を行いたい場合は、どちらか片方のみで設定するのがよいでしょう。

 さて、これでアカウント編の解説は完了です。次回からは環境設定の管理について解説していきたいと思います。
つづく                               

小池邦人のCarbon API 徒然草(2007/05/18)

〜 Carbonモダンアプリケーションへの道(その16) 〜

今回は、ファイルのオープン(Open)とクローズ(Close)、ファイルへのデータ書き込み(Write)とファイルからの読み込み(Read)、ファイルの削除(Delete)やファイル名の変更(Rename)など、一般的なファイル処理を調べてみます。

最初はファイルのオープンです。Mac OS X 10.4になり、今までCarbonFrameworkで親しまれてきたFSpOpenDF()やFSpOpenRF()など、引数にFSSpec構造体を渡すAPIは、そのほとんどがDEPRECATED指定となりました。ヘッダーファイルFiles.hに記載されているコメントでも言及されていますが、現在は代わりにFSOpenFork()を利用します。

OSErr  FSOpenFork(

   const FSRef *ref,              // FSRefで対象ファイルを指示
   UniCharCount forkNameLength,   // フォーク名の長さ
   const UniChar *forkName,       // フォーク名(ユニコード文字列)
   SInt8 permissions,             // パーミッション(アクセス権)
   SInt16 *forkRefNum );          // ファイル固有のリファレンス番号

まずオープンしたいファイルをFSRefで指定します。次に対象となるフォーク名をユニコード文字列で指定します。Macintoshのファイルシステムでは、ファイル内部にデータフォークとリソースフォークの2つのデータ領域を持つことが可能です。この仕組みは、Mac OS Xでも存続しています(消えると言う噂もありましたが…)。通常のファイル処理ではデータフォークの方をオープンすることがほとんです。その場合には、ディフォルト値としてforkNameLengthにゼロを、forkNameにはNULLを渡せばOKです。もし、リソースフォークの方をオープンしたければ、FSGetResourceForkName()で得た名称を
ユニコード文字列として渡します。同様に、データフォーク名を得るためのFSGetDataForkName()というAPIも存在しています。

OSErr FSGetResourceForkName( HFSUniStr255 * resourceForkName );
OSErr FSGetDataForkName( HFSUniStr255 * dataForkName );


次のファイルパーミッション(アクセス権)については、以下の7種類から選択することが可能です。データの読み書きをする一般的なファイル処理では、fsRdWrPermを選択しておけば良いでしょう。ファイルオープンが成功すると、forkRefNumにはそのファイル固有のリファレンス番号が返されます。その後、このリファレンス番号を用いてファイルデータの読み書きを行うことになります。

enum {
       fsCurPerm    = 0x00,
       fsRdPerm     = 0x01,
       fsWrPerm     = 0x02,
       fsRdWrPerm   = 0x03,
       fsRdWrShPerm = 0x04,
       fsRdDenyPerm = 0x10,
       fsWrDenyPerm = 0x20
};


実際の作業では、ファイルをFSRefで指定するのではなく、ファイル名やパス名などで指定したい場合も多々あります。例えば、親ディレクトリ(フォルダ)のFSRefとファイル名(CFStringRef)を引数で渡すことで、対象ファイルをオープンするopenNameFile()ルーチンを作成すると以下のようになります。

OSErr openNameFile( FSRef *pfsref,CFStringRef cfstr,char perm,short *fref )
{
   UniChar         buf[256];
   FSRef           fsref;
   OSErr           err=1;
   UniCharCount    len;

   if( len=(UniCharCount)CFStringGetLength( cfstr ) ) // ファイル名の長さ
   {
       CFStringGetCharacters( cfstr,CFRangeMake(0,len),buf );  // ユニコード名
       if( ! FSMakeFSRefUnicode( pfsref,len,buf,kTextEncodingUnicodeDefault,
                                                                   &fsref ) )
                                                  // 対象ファイルのFSRefを得る
           err=FSOpenFork( &fsref,0,NULL,perm,fref );  // ファイルオープン
   }
   return( err );
}

ファイルからのデータの読み込みには、以下のFSReadFork()を利用します。

OSErr  FSReadFork(

   SInt16 forkRefNum,        // 対象ファイルのリファレンス番号
   UInt16 positionMode,      // 読み込みデータ位置を指示する方法
   SInt64 positionOffset,    // 読み込みデータ位置オフセット
   ByteCount requestCount,   // 読み込みデータバイト数
   void *buffer,             // データバッファの先頭アドレス
   ByteCount *actualCount ); // 実際に読み込まれたデータバイト数

読み込みデータ位置の意味は以下の4種類から選択することが可能です。ま
た、読み込みポジションはSInt64(64ビット整数)で指定できますが、一度に
読み込むデータ量はByteCount(32ビット整数)指定となり4G Byteに制限され
ています。

enum {

    fsAtMark        = 0,    // カレントポジション
    fsFromStart     = 1,    // ファイル(フォーク)の先頭からのオフセット
    fsFromLEOF      = 2,    // ファイル(フォーク)の最後からのオフセット
    fsFromMark      = 3     // カレントポジションからのオフセット
};

ファイルからのデータの書き込みには、以下のFSWriteFork()を利用します。
引数の内容は、FSReadFork()とほとんど同じです。

OSErr  FSWriteFork(

   SInt16 forkRefNum,        // 対象ファイルのリファレンス番号
   UInt16 positionMode,      // 書き込みデータ位置を指示する方法
   SInt64 positionOffset,    // 書き込みデータ位置オフセット
   ByteCount requestCount,   // 書き込みデータバイト数
   const void *buffer,       // データバッファの先頭アドレス
   ByteCount *actualCount ); // 実際に書き込まれたデータバイト数

アクセスが終了したファイルを閉じるのには、以下のFSCloseFork()にファイ
ルリファレンス番号を渡します。

OSErr  FSCloseFork( SInt16 forkRefNum );

またファイルやフォルダ(ディレクトリ)の削除は、FSDeleteObject()で行え
ます。対象がフォルダの場合には、その中にファイルや別フォルダが含まれた
ままだと削除ができませんので注意してください。

OSErr  FSDeleteObject( const FSRef *ref );

最後に紹介するのは、ファイルやフォルダ名を変更するための
FSRenameUnicode()です。引数のtextEncodingHintにkTextEncodingUnknownを
代入しておけば、ファイルシステムがディフォルトテキストエンコーディング
を利用してくれます。

OSErr  FSRenameUnicode(

   const FSRef *ref,              // 名称変更したいファイルかフォルダ
   UniCharCount nameLength,       // ファイルかフォルダ名の長さ
   const UniChar *name,           // ファイルかフォルダ名(ユニコード文字列)
   TextEncoding textEncodingHint, // テキストエンコーディング
   FSRef *newRef );               // 新規のFSRef(不必要ならNULL指定)

ところで先ほどリソースフォークの話題が出ましたので、ついでにリソースファイルに関する注意点をいくつか上げておきます。もし、GetResource()やGetIndResource()などでリソースファイル内部の個々のリソースデータ(PICTリソースなど)にアクセスしたい場合には、リソースファイルをオープンしてカレントリソースに設定しておく必要があります。つまり、単純にFSOpenFork()で対象ファイルのリソースフォークをオープンするだけではマズイということです。

昔からこの働きをしていたのは、Resources.hに定義されているFSpOpenResFile()でした。これは、引数にFSSpec構造体を渡しファイル指定する旧型APIですが、何か事情があるのか、まだDEPRECATED指定になっていません(不思議?)。問題は、このAPIを用いてもリソースフォークに保存されているリソースデータにしかアクセスできないことです。Mac OS Xから、アプリケーションバンドルのResourcesフォルダに保存されるリソースファイルなどは、データフォークにそのデータが保存されています(ややこしい)。よって、それらにアクセスするためには、FSpOpenResFile()の代わりに
FSOpenResourceFile()を使う必要があるわけです。

FSOpenResourceFile(

   cconst FSRef *    ref,             // FSRefで対象ファイルを指示
   cUniCharCount     forkNameLength,  // フォーク名の長さ
   cconst UniChar *  forkName,        // フォーク名(ユニコード文字列)
   cSInt8            permissions,     // パーミッション(アクセス権)
   cSInt16 *         refNum );        // ファイル固有のリファレンス番号

先ほど取り上げたFSOpenFork()と同様に、forkNameLengthにゼロを、forkName
にNULLを渡した時にディフォルト対象はデータフォークとなります。ディフォルトはリソースフォークではないので注意してください。こうしてオープンしたファイルをクローズするには、FSCloseFork()ではなくCloseResFile()を使いますので、こちらも注意が必要です。

次回は、色々なファイル処理の話題を集めてみたいと思います。ディレクトリ・カタログからファイルを抽出するような処理にもチャレンジしてみます。
                                
つづく

ターミナルの向こうから      第2回  海上 忍

〜Mac OS Xのディレクトリ構成(1)〜

 前回は、コマンドと聞いただけで身構えてしまう方のために、一種の心構えについて紹介させていただきました。今回はその先に横たわる”UNIXレイヤー”の理解を進める第一歩として、Mac OS Xのディレクトリ構成について解説を行います。

・すべては「/」から始まる
 Mac OS Xにかぎらず、UNIX系OSではファイルシステムの基点を「/」で表現します。読み方は「ルート(ディレクトリ)」、下位のディレクトリやファイルとの区切り記号としても利用されます。
 ファイルシステム上に存在するすべてのファイル/ディレクトリは、ボリュームやフォーマット種が異なっても、ディレクトリ階層が浅くても深くても、一律に「/」から始まる文字のら列(POSIXパス、単純に「パス」とも呼ばれる)で表現できます。以下に挙げる例は、日本語環境のファインダに表示されたファイルを、パスに置き換えたものです。

1) Macintosh HD→Developer→About Xcode Tools.pdf
= /Developer/About Xcode Tools.pdf
2) Macintosh HD→システム→ライブラリ(フォルダ)
= /System/Library
3) Macintosh HD→ユーザ→shinobu→Flower.jpg
= /Users/shinobu/Flower.jpg


・ファインダとPOSIXパスの関係
 上の例を見ればわかるように、ファインダに表示される情報とPOSIXパスには違いがあります。ファインダ上の「Macintosh HD」はPOSIXパスでは「/」に、「システム」は「System」に、「ユーザ」は「Users」に、それぞれ置き換えられていることがわかるはずです。
 なお、このパスの置換はCore Foundationの国際化により実現されました。Mac OS X 10.2(Jaguar)以降のシステムでは、特定のディレクトリを対象に「.localized」ファイルの有無を判定し、存在すれば(システム環境設定の)第一優先言語で定義されたディレクトリ名に置換し、存在しなければそのまま(英語≒POSIXパス)表示します。ユーザ権限で作成した一般のディレクトリも多言語対応させることが可能ですが、今回のテーマから大きく逸脱するため、具体的な方法はまたの機会にさせていただきます。

- – -
表1:システム標準で多言語対応するディレクトリの例

本来のディレクトリ名       日本語ローカライズ時
/Applications            アプリケーション
/Applications/Utilities  ユーティリティ
/Library                 ライブラリ
/Network                 ネットワーク
/System                  システム
/System/Library          ライブラリ
/Users                   ユーザ
/Users/Shared            共有
- – -

・ファインダに表示されない”隠しアイテム”
 「/」以下にはいくつかのディレクトリが設けられ、それぞれ用途に応じた使い分けが行われます。表1に挙げたディレクトリはその代表格で、Mac OS Xをインストールした時点で作成される”システム標準”です。重要な役割が割り当てられているため、安易に改変されないよう、管理権限を持たない一般ユーザによる変更は(アクセス権の設定によって)禁じられています。
 システム標準のディレクトリは、表1以外にも多数存在します。ファインダの機能により非表示に設定されているため、通常の設定では存在に気づきませんが、ターミナルから「ls」コマンドを実行(-aオプションが必要)すれば確認できます。どうしてもファインダで表示したければ、TinkerTool
(http://www.bresink.com/osx/TinkerTool.html)などユーティリティソフト
の力を借りる方法があります。

- – -
表2:ファインダに表示されないディレクトリ

ディレクトリ名    内容
/automount      自動マウント機能が使用する領域
/bin            最低限必要なコマンドが保存される領域
/cores          コアダンプが保存される領域
/dev            デバイスファイルが作成される領域
/etc            システム上重要な設定ファイルが保存される領域
/private        ローカルホストのみで使用される領域
/sbin           管理用コマンドが保存される領域
/usr            ユーザの共用領域
/tmp            一時使用のファイルなどが保存される領域
/var            頻繁な書き換えが予想されるファイル用の領域
- – -

 表2に挙げたディレクトリは、Mac OS XのUNIXとしての側面を語る際に不可欠の存在です。次回は、これらUNIX由来のディレクトリについて説明する予定です。

書籍紹介                エンジニアのための時間管理術

 解説担当:高橋政明

エンジニアのための時間管理術
  Thomas A. Limoncelli 著
  株式会社クイープ 訳
  オライリー・ジャパン ISBN4-87311-307-5  定価2,415円

 原書Time Management for System Administratorsの翻訳本です。冒頭に「本書の対象読者」の項があり『本書はプログラマを対象としていません。』とキッパリ書かれています。
 私がこの行を目にしたのは購入した後でしたが(だからこそ?)気にせず〔^_^;〕読み進みました。そうSystem Administrators(以下SA)向けの内容です。

 目次を見るとどの章も、あるいはいくつかは、興味をそそる項目ではないでしょうか? SA向けの内容と言っても紹介されている問題と対策がSAに最適化されているだけであって、ここに載っている様々な問題がプログラマやそのほかの技術者に無縁かと言えばまったくそのような事はありません。日本の書名を「エンジニアのための」とした事はなかなかの名訳ではないかと思います。

 私のようにSAでない方は気楽に本書を開き、斜め読みする事をおすすめします。組織の中で働くエンジニアに有用な事柄が多い印象ですが、私のような一匹狼にも役に立ちました。新製品の開発に加えて、出荷済み製品のバグ対応、ユーザー(や上司)のサポート、ウイルスチェックソフトの更新からスパムメール対策の設定などなど一手に引き受けている方にはなおさらでしょう。

 この本はとても読み易く書かれています。具体的なアドバイスもちりばめられています。各章ごとにまとめがあり、後日見直すのにも便利です。
 たくさんやらなければならない事がある場合に優先順位を付けて対処することは重要です。この本ではさらに一日の終わりに充実感を持つ事ができ、客観的に自分の仕事量を判断するためのテクニックを示してくれます。そのような良い習慣が幸せを呼ぶことになると自然に理解できます。

 SAのために最適化された本ですが、プログラマがざっと読むと時間管理のエッセンスを感じとる事ができ、じっくり読むとSAの苦労が理解できる本と言えるかも知れません。(エピソードが技術系の話であることを気にしなければどんな仕事の方にも参考になると思います)

 過労や心の病は個人にとっても企業にとっても重大な、そして厄介なことに差し迫った問題です。青い背表紙の『エンジニアのための時間管理術』が目に入ったら手を伸ばしてみてください。ちょっとした余裕を手に入れるきっかけになるかも知れません。

▼出版社のweb(詳しい目次とpdfのサンプルページが載っています)
http://www.oreilly.co.jp/books/4873113075/index.html

◇モサ伝編集部から◇
【ソースの訂正】
プログラミング指南の高橋真人です。

先週配信しましたMOSA Developer News第251号に掲載の「高橋真人のプログラミング指南」第112回に誤記がありました。詳しくは来週の第113回でフォローしますが、取り急ぎさしかえ内容を以下に掲載いたしますので、ご参照ください。

【誤】
OSStatus
MyApplication::HandleNew()
{
    OSStatus status = eventNotHandledErr;

    WindowRef theWindow = ::GetFrontWindowOfClass(kDocumentWindowClass, true);
    PPx::Window* win = PPx::Window::GetWindowObject(theWindow);
    if (win) {
        win->Close();
    }

    ::CFShow(CFSTR("HandleClose called."));

    return noErr;
}


【正】
OSStatus
MyApplication::HandleNew()
{
   PPx::Window* theWindow = PPx::NibDecoder::CreateWindowFromNib(
       CFSTR("main"), CFSTR("MainWindow"));
   if (theWindow) {
       ::RepositionWindow(theWindow->GetSysWindow(), nil, kWindowCascadeOnMainScreen);
       theWindow->Show();
   }

   return noErr;
}


【誤】
OSStatus
MyApplication::HandleClose()
{
    OSStatus status = eventNotHandledErr;

    WindowRef theWindow = ::GetFrontWindowOfClass(kDocumentWindowClass, true);
    if (theWindow) {
        PPx::EventUtils::SetMenuCommandStatus(kHICommandClose, true);
    }

    return noErr;
}


【正】
OSStatus
MyApplication::HandleClose()
{
   OSStatus status = eventNotHandledErr;

   WindowRef theWindow = ::GetFrontWindowOfClass(kDocumentWindowClass, true);
   PPx::Window* win = PPx::Window::GetWindowObject(theWindow);
   if (win) {
       win->Close();
   }

   ::CFShow(CFSTR("HandleClose called."));

   return noErr;
}


ご迷惑をおかけし、申し訳ありません。
高橋真人

◇MOSAからのお知らせと編集後記は割愛します◇

 

MOSA Developer News   略称[MOSADeN=モサ伝]
        配信停止 mailto:mosaden-ml@mosa.gr.jp
 記事内容に関するご意見 mailto:mosaden-toukou@mosa.gr.jp
      記事投稿受付 http://www.mosa.gr.jp/?page_id=850
Apple、Mac OSは米国アップル社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。このメールの再配信、および掲載された記事の無断転載を禁じます。
特定非営利活動法人MOSA  http://www.mosa.gr.jp/
Copyright (C)2007 MOSA. All rights reserved.