/*
 * Copyright (C) 2008 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <pathconf.h>
#include <sys/vfs.h>
#include <sys/limits.h>
#include <errno.h>

/* these may not be defined yet by our headers */
#ifndef _POSIX_VDISABLE
#define _POSIX_VDISABLE  -1
#endif

#ifndef _POSIX_SYNC_IO
#define _POSIX_SYNC_IO  -1
#endif

#ifndef _POSIX_PRIO_IO
#define _POSIX_PRIO_IO  -1
#endif

#ifndef _POSIX_ASYNC_IO
#define _POSIX_ASYNC_IO  -1
#endif


static long
__filesizebits( struct statfs*  s )
{
#define   EOL_MAGIC   0x0000U

    /* list of known 64-bit aware filesystems */
    static const uint32_t  known64[] = {
        EXT2_SUPER_MAGIC,
        UFS_MAGIC,
        REISERFS_SUPER_MAGIC,
        XFS_SUPER_MAGIC,
        SMB_SUPER_MAGIC,
        UDF_SUPER_MAGIC,
        JFS_SUPER_MAGIC,
        NTFS_SB_MAGIC,
        VXFS_SUPER_MAGIC,
        EOL_MAGIC
    };
    int  nn = 0;

    for (; known64[nn] != EOL_MAGIC; ++nn) {
        if (known64[nn] == s->f_type) {
            return 64;
        }
    }
    return 32;
}


static long
__link_max( struct statfs*  s )
{
    // These constant values were taken from kernel headers.
    // They're not available in uapi headers.
    static const struct { uint32_t  type; int  max; }  knownMax[] =
    {
        { EXT2_SUPER_MAGIC, 32000 },
        { EXT3_SUPER_MAGIC, 32000 },
        { MINIX_SUPER_MAGIC, 250 },
        { MINIX2_SUPER_MAGIC, 65530 },
        { REISERFS_SUPER_MAGIC, 0xffff - 1000 },
        { UFS_MAGIC, 32000 },
        { EOL_MAGIC, 0 }
    };
    int   nn = 0;

    for (; knownMax[nn].type != EOL_MAGIC; ++nn) {
        if (knownMax[nn].type == s->f_type) {
            return knownMax[nn].max;
        }
    }
    return LINK_MAX;
}

static long
__2_symlinks( struct statfs*  s )
{
    /* list of know filesystems that don't support symlinks */
    static const uint32_t  knownNoSymlinks[] = {
        ADFS_SUPER_MAGIC, BFS_MAGIC, CRAMFS_MAGIC,
        EFS_SUPER_MAGIC, MSDOS_SUPER_MAGIC, NTFS_SB_MAGIC,
        QNX4_SUPER_MAGIC,
        EOL_MAGIC
    };
    int  nn = 0;

    for (; knownNoSymlinks[nn] != EOL_MAGIC; ++nn) {
        if (knownNoSymlinks[nn] == s->f_type) {
            return 0;
        }
    }
    return 1;
}

static long
__name_max( struct statfs*  s )
{
    return s->f_namelen;
}

long
pathconf(const char *path, int name)
{
    struct statfs  buf;
    int            ret = statfs( path, &buf );

    if (ret < 0)
        return -1;

    switch (name) {
    case _PC_FILESIZEBITS:
        return __filesizebits(&buf);

    case _PC_LINK_MAX:
        return __link_max(&buf);

    case _PC_MAX_CANON:
        return MAX_CANON;

    case _PC_MAX_INPUT:
        return MAX_INPUT;

    case _PC_NAME_MAX:
        return __name_max(&buf);

    case _PC_PATH_MAX:
        return PATH_MAX;

    case _PC_PIPE_BUF:
        return PIPE_BUF;

    case _PC_2_SYMLINKS:
        return __2_symlinks(&buf);

#if 0  /* don't know what to do there, the specs are really weird */
    case _PC_ALLOC_SIZE_MIN:
    case _PC_REC_INCR_XFER_SIZE:
    case _PC_REC_MAX_XFER_SIZE:
    case _PC_REC_MIN_XFER_SIZE:
    case _PC_REC_XFER_ALIGN:
#endif

    case _PC_SYMLINK_MAX:
        return -1;  /* no limit */

    case _PC_CHOWN_RESTRICTED:
        return _POSIX_CHOWN_RESTRICTED;

    case _PC_NO_TRUNC:
        return _POSIX_NO_TRUNC;

    case _PC_VDISABLE:
        return _POSIX_VDISABLE;

    case _PC_ASYNC_IO:
        return _POSIX_ASYNC_IO;

    case _PC_PRIO_IO:
        return _POSIX_PRIO_IO;

    case _PC_SYNC_IO:
        return _POSIX_SYNC_IO;

    default:
        errno = EINVAL;
        return -1;
    }
}

long fpathconf(int fildes, int name)
{
    struct statfs  buf;
    int            ret = fstatfs(fildes, &buf);

    if (ret < 0)
        return -1;

    switch (name) {
    case _PC_FILESIZEBITS:
        return __filesizebits(&buf);

    case _PC_LINK_MAX:
        return __link_max(&buf);

    case _PC_MAX_CANON:
        return MAX_CANON;

    case _PC_MAX_INPUT:
        return MAX_INPUT;

    case _PC_NAME_MAX:
        return __name_max(&buf);

    case _PC_PATH_MAX:
        return PATH_MAX;

    case _PC_PIPE_BUF:
        return PIPE_BUF;

    case _PC_2_SYMLINKS:
        return __2_symlinks(&buf);

#if 0  /* don't know what to do there, the specs are really weird */
    case _PC_ALLOC_SIZE_MIN:
    case _PC_REC_INCR_XFER_SIZE:
    case _PC_REC_MAX_XFER_SIZE:
    case _PC_REC_MIN_XFER_SIZE:
    case _PC_REC_XFER_ALIGN:
#endif

    case _PC_SYMLINK_MAX:
        return -1;  /* no limit */

    case _PC_CHOWN_RESTRICTED:
        return _POSIX_CHOWN_RESTRICTED;

    case _PC_NO_TRUNC:
        return _POSIX_NO_TRUNC;

    case _PC_VDISABLE:
        return _POSIX_VDISABLE;

    case _PC_ASYNC_IO:
        return _POSIX_ASYNC_IO;

    case _PC_PRIO_IO:
        return _POSIX_PRIO_IO;

    case _PC_SYNC_IO:
        return _POSIX_SYNC_IO;

    default:
        errno = EINVAL;
        return -1;
    }
}
