/* ----------------------------------------------------------------------- *
 *
 *   Copyright 2010 Intel Corp. - All Rights Reserved
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
 *   Boston MA 02111-1307, USA; either version 2 of the License, or
 *   (at your option) any later version; incorporated herein by reference.
 *
 * ----------------------------------------------------------------------- */

/*
 * syslxcom.c
 *
 * common functions for extlinux & syslinux installer
 *
 */
#define  _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <getopt.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mount.h>
#include <sys/vfs.h>

#include "linuxioctl.h"
#include "syslxrw.h"
#include "syslxcom.h"
#include "syslxfs.h"

const char *program;

int fs_type;

#ifdef DEBUG
# define dprintf printf
#else
# define dprintf(...) ((void)0)
#endif

#define SECTOR_SHIFT	9

/*
 * Set and clear file attributes
 */
void clear_attributes(int fd)
{
    struct stat st;

    if (!fstat(fd, &st)) {
	switch (fs_type) {
	case EXT2:
	{
	    int flags;

	    if (!ioctl(fd, FS_IOC_GETFLAGS, &flags)) {
		flags &= ~FS_IMMUTABLE_FL;
		ioctl(fd, FS_IOC_SETFLAGS, &flags);
	    }
	    break;
	}
	case VFAT:
	{
	    uint32_t attr = 0x00; /* Clear all attributes */
	    ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &attr);
	    break;
	}
    case NTFS:
        break;
	default:
	    break;
	}
	fchmod(fd, st.st_mode | S_IWUSR);
    }
}

void set_attributes(int fd)
{
    struct stat st;

    if (!fstat(fd, &st)) {
	fchmod(fd, st.st_mode & (S_IRUSR | S_IRGRP | S_IROTH));
	switch (fs_type) {
	case EXT2:
	{
	    int flags;

	    if (st.st_uid == 0 && !ioctl(fd, FS_IOC_GETFLAGS, &flags)) {
		flags |= FS_IMMUTABLE_FL;
		ioctl(fd, FS_IOC_SETFLAGS, &flags);
	    }
	    break;
	}
	case VFAT:
	{
	    uint32_t attr = 0x07; /* Hidden+System+Readonly */
	    ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &attr);
	    break;
	}
    case NTFS:
        break;
	default:
	    break;
	}
    }
}

/* New FIEMAP based mapping */
static int sectmap_fie(int fd, sector_t *sectors, int nsectors)
{
    struct fiemap *fm;
    struct fiemap_extent *fe;
    unsigned int i, nsec;
    sector_t sec, *secp, *esec;
    struct stat st;
    uint64_t maplen;

    if (fstat(fd, &st))
	return -1;

    fm = alloca(sizeof(struct fiemap)
		+ nsectors * sizeof(struct fiemap_extent));

    memset(fm, 0, sizeof *fm);

    maplen = (uint64_t)nsectors << SECTOR_SHIFT;
    if (maplen > (uint64_t)st.st_size)
	maplen = st.st_size;

    fm->fm_start        = 0;
    fm->fm_length       = maplen;
    fm->fm_flags        = FIEMAP_FLAG_SYNC;
    fm->fm_extent_count = nsectors;

    if (ioctl(fd, FS_IOC_FIEMAP, fm))
	return -1;

    memset(sectors, 0, nsectors * sizeof *sectors);
    esec = sectors + nsectors;

    fe = fm->fm_extents;

    if (fm->fm_mapped_extents < 1 ||
	!(fe[fm->fm_mapped_extents-1].fe_flags & FIEMAP_EXTENT_LAST))
	return -1;

    for (i = 0; i < fm->fm_mapped_extents; i++) {
	if (fe->fe_flags & FIEMAP_EXTENT_LAST) {
	    /* If this is the *final* extent, pad the length */
	    fe->fe_length = (fe->fe_length + SECTOR_SIZE - 1)
		& ~(SECTOR_SIZE - 1);
	}

	if ((fe->fe_logical | fe->fe_physical| fe->fe_length) &
	    (SECTOR_SIZE - 1))
	    return -1;

	if (fe->fe_flags & (FIEMAP_EXTENT_UNKNOWN|
			    FIEMAP_EXTENT_DELALLOC|
			    FIEMAP_EXTENT_ENCODED|
			    FIEMAP_EXTENT_DATA_ENCRYPTED|
			    FIEMAP_EXTENT_UNWRITTEN))
	    return -1;

	secp = sectors + (fe->fe_logical >> SECTOR_SHIFT);
	sec  = fe->fe_physical >> SECTOR_SHIFT;
	nsec = fe->fe_length >> SECTOR_SHIFT;

	while (nsec--) {
	    if (secp >= esec)
		break;
	    *secp++ = sec++;
	}

	fe++;
    }

    return 0;
}

/* Legacy FIBMAP based mapping */
static int sectmap_fib(int fd, sector_t *sectors, int nsectors)
{
    unsigned int blk, nblk;
    unsigned int i;
    unsigned int blksize;
    sector_t sec;

    /* Get block size */
    if (ioctl(fd, FIGETBSZ, &blksize))
	return -1;

    /* Number of sectors per block */
    blksize >>= SECTOR_SHIFT;

    nblk = 0;
    while (nsectors) {
	blk = nblk++;
	if (ioctl(fd, FIBMAP, &blk))
	    return -1;

	sec = (sector_t)blk * blksize;
	for (i = 0; i < blksize; i++) {
	    *sectors++ = sec++;
	    if (! --nsectors)
		break;
	}
    }

    return 0;
}

/*
 * Produce file map
 */
int sectmap(int fd, sector_t *sectors, int nsectors)
{
    if (!sectmap_fie(fd, sectors, nsectors))
	return 0;

    return sectmap_fib(fd, sectors, nsectors);
}

/*
 * SYSLINUX installs the string 'SYSLINUX' at offset 3 in the boot
 * sector; this is consistent with FAT filesystems.  Earlier versions
 * would install the string "EXTLINUX" instead, handle both.
 */
int syslinux_already_installed(int dev_fd)
{
    char buffer[8];

    xpread(dev_fd, buffer, 8, 3);
    return !memcmp(buffer, "SYSLINUX", 8) || !memcmp(buffer, "EXTLINUX", 8);
}
