C言語入門(35) 実際にプログラムを読んで理解を深めよう ls編(9)

Posted: 2013年04月11日

前回は、printlong関数を解説してきました。
今回はprintlong関数がアクセスコントロール(ACL)属性取得処理に用いている各種aclmode関数を解説していきます。

print.c aclmode関数です。

プログラムプログラム:

static void
aclmode(char *buf, const FTSENT *p)
{
    char name[MAXPATHLEN + 1];
    int ret, trivial;
    static dev_t previous_dev = NODEV;
    static int supports_acls = -1;
    static int type = ACL_TYPE_ACCESS;
    acl_t facl;

    /*
     * XXX: ACLs are not supported on whiteouts and device files
     * residing on UFS.
     */
    if (S_ISCHR(p->fts_statp->st_mode) || S_ISBLK(p->fts_statp->st_mode) ||
        S_ISWHT(p->fts_statp->st_mode))
        return;

    if (previous_dev == p->fts_statp->st_dev && supports_acls == 0)
        return;

    // 省略
}

解説解説:

各モードのチェックでは、コメント通り
ACLをサポートしていないファイルについて無視をしています。

また、その次のif文では、
同様のデバイスで且つ、ACLをサポートしていない場合は、無視をします。

前回値は、static変数が記憶させます。
つまり、間違えた使い方をすると前回値ではなくゴミが入った状態で処理がされる場合があるという事です。

    if (p->fts_level == FTS_ROOTLEVEL)
        snprintf(name, sizeof(name), "%s", p->fts_name);
    else
        snprintf(name, sizeof(name), "%s/%s",
            p->fts_parent->fts_accpath, p->fts_name);

    if (previous_dev != p->fts_statp->st_dev) {
        previous_dev = p->fts_statp->st_dev;
        supports_acls = 0;

        ret = lpathconf(name, _PC_ACL_NFS4);
        if (ret > 0) {
            type = ACL_TYPE_NFS4;
            supports_acls = 1;
        } else if (ret < 0 && errno != EINVAL) {
            warn("%s", name);
            return;
        }
        if (supports_acls == 0) {
            ret = lpathconf(name, _PC_ACL_EXTENDED);
            if (ret > 0) {
                type = ACL_TYPE_ACCESS;
                supports_acls = 1;
            } else if (ret < 0 && errno != EINVAL) {
                warn("%s", name);
                return;
            }
        }
    }
    if (supports_acls == 0)
        return;

解説解説:

ファイルパスを作成後
そのファイルのファイル属性をlpathconf関数にて取得します。

ACLのサポートしている判断としては、
_PC_ACL_NFS4と_PC_ACL_EXTENDEDです。
それぞれの意味は、

タイプ 意味
_PC_ACL_NFS4 NFS(Filesytem)のACLがサポートされていることを表します
_PC_ACL_EXTENDED 通常のACL情報が取得可能なことを表します。

サポートしていない場合は、ここで無視されます。

static void
    facl = acl_get_link_np(name, type);
    if (facl == NULL) {
        warn("%s", name);
        return;
    }
    if (acl_is_trivial_np(facl, &trivial)) {
        acl_free(facl);
        warn("%s", name);
        return;
    }
    if (!trivial)
        buf[10] = '+';
    acl_free(facl);

解説解説:

ここでは、実際の値をacl_get_link_np関数にて取得します。

trivalについても
確認をしています。

trivalとは、
通常のACLモード(1)を表します。
特殊なモード(0)の場合は、+を追加して表現しています。

最後は、解放処理
私だったらacl_is_trivial_npのreturnで解放漏れしそう

カテゴリー: プログラム, 入門 | タグ: , , | コメント無し »

コメント