pslaboが試したことの記録

はてなダイヤリーからはてなブログに引っ越してきました

この日記は現在実行中の減量記録を含む個人的なメモとして始めましたが、最近はコンピュータやガジェット、ハック、セキュリティネタのほうがメインになっております。

はてなダイヤリー時代はカテゴリ分けが適当だったのですが、これはそのうち直します。


UNC と UNIX上のパスをsmb.confや/etc/passwdを参照して汎用的に相互変換する

以前に「samba の機材に ssh でログインして UNC で cd」したり、あるいは「ssh 接続時のカレントディレクトリのUNCを取得する」という誰得なネタを書いていたのですが、これらの実装は汎用性がない手抜き実装でした。

pslabo.hatenablog.com

pslabo.hatenablog.com


そこで上記の処理を汎用的に行えるための下準備として「UNC と UNIX上のパスを smb.conf や /etc/passwd を参照して汎用的に相互変換する」処理を書いてみました。

この実装では、標準入力から与えられたUNCやディレクトリのフルパスに対して以下の結果を返します。

  • 標準入力からUNCを渡すとUNIXのパスを返します。
  • UNIXのパスを渡せばUNCを返します。

バックスラッシュの処理がキレイじゃないけど、まあ自分用のスクリプトなのでこんなものかと。

この処理を前述の2つの実装に反映させれば機材の設定によらず汎用的に使えるので色々捗ります。

なお、実際に用いる場合は、スクリプト内の smbserver と config_smb だけは実際の環境に合わせて調整する必要があります。smbserver は smb.conf の "netbios name" またはシェル変数の HOSTNAME から取得してもよいのですが、今の実装はそのようにはしていません。

より汎用的に使えるようにするならば「config_smb や smbserver は -v でスクリプト外から指定できるようにする」と良いのかも。

#!/usr/bin/awk -f

BEGIN {

        smbserver="[sambaサーバのホスト名]"

        config_passwd="/etc/passwd"
        config_smb="/etc/samba/smb.conf"

        # samba の設定ファイル読み込み
        while ( getline < config_smb ) {
                if ( $1 ~ /^\[/ ) {
                        unc_path = gensub( /[\[\]]/, "", "g" )
                        unc_path1 = "\\\\"     smbserver "\\"   unc_path
                        unc_path2 = "\\\\\\\\" smbserver "\\\\" unc_path
                }

                # unc_path が homes の場合は、ホームディレクトリ共有が有効なので
                # /etc/passwd を解析して username と ホームディレクトリの関連付けも作る
                if ( unc_path == "homes" ) {
                        use_homedirectory_share=1
                }

                # 共有ディレクトリを取得する
                if ( $1 == "path" ) {
                        directory=$3
                }

                # 共有ディレクトリおよびunc_pathのいずれも空文字ではない場合は
                # 変換用のハッシュ配列に値を格納する
                if ( directory != "" && unc_path != "" ) {
                        unc2directory[unc_path2]=directory
                        directory2unc[directory]=unc_path1

                        unc_path=""
                        directory=""
                }
        }

        # /etc/passwd の内容から Username とホームディレクトリをマッピングする。
        if ( use_homedirectory_share == 1 ) {
                FS_BACKUP=FS
                FS=":"
                while ( getline < config_passwd ) {
                        unc_path  = $1
                        unc_path1 = "\\\\"     smbserver "\\"   unc_path
                        unc_path2 = "\\\\\\\\" smbserver "\\\\" unc_path
                        directory=$6

                        unc2directory[unc_path2]=directory
                        directory2unc[directory]=unc_path1
                }
                FS=FS_BACKUP
        }
}

{
        # UNC を UNIX のパスに変換する
        for ( unc_path in unc2directory ) {
                regexp= "^(" unc_path ")(\\\\(.*))?"
                if ( match( $1, regexp, array ) ) {
                        path_result=unc2directory[unc_path] array[2]
                        gsub( "\\\\", "/", path_result )
                        print path_result
                        next
                }
        }

        # UNIX を UNC のパスに変換する
        for ( directory in directory2unc ) {
                regexp= "^(" directory ")(/(.*))?"
                if ( match( $1, regexp, array ) ) {
                        path_result=directory2unc[directory] array[2]
                        gsub( "/", "\\", path_result )
                        print path_result
                        next
                }
        }
}