/* The program allows the user to send a trespass command to change the
 * LUN ownership from one Service-Processor to this one on an EMC
 * CLARiiON and potentially other devices.
 *
 * Copyright (C) 2004-2015 Lars Marowsky-Bree <lmb@suse.de>
 *
 * Based on sg_start.c; credits from there also apply.
 * Minor modifications for sg_lib, D. Gilbert 2004/10/19
 *
 *  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; either version 2, or (at your option)
 *  any later version.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_pr2serr.h"


static const char * version_str = "0.20 20141219";

static int debug = 0;

#define TRESPASS_PAGE           0x22

static int do_trespass(int fd, int hr, int short_cmd)
{
        unsigned char long_trespass_pg[] =
                { 0, 0, 0, 0, 0, 0, 0, 0x00,
                  TRESPASS_PAGE,        /* Page code */
                  0x09,                 /* Page length - 2 */
                  0x81,                 /* Trespass code + Honor reservation
                                         * bit */
                  0xff, 0xff,           /* Trespass target */
                  0, 0, 0, 0, 0, 0      /* Reserved bytes / unknown */
        };
        unsigned char short_trespass_pg[] =
                { 0, 0, 0, 0,
                  TRESPASS_PAGE,        /* Page code */
                  0x02,                 /* Page length - 2 */
                  0x81,                 /* Trespass code + Honor reservation
                                         * bit */
                  0xff,                 /* Trespass target */
        };
        int res;
        char b[80];

        if (hr) {       /* override Trespass code + Honor reservation bit */
                short_trespass_pg[6] = 0x01;
                long_trespass_pg[10] = 0x01;
        }
        if (short_cmd)
                res = sg_ll_mode_select6(fd, 1 /* pf */, 0 /* sp */,
                                 short_trespass_pg, sizeof(short_trespass_pg),
                                 1, (debug ? 2 : 0));
        else
                res = sg_ll_mode_select10(fd, 1 /* pf */, 0 /* sp */,
                                 long_trespass_pg, sizeof(long_trespass_pg),
                                 1, (debug ? 2 : 0));

        switch (res) {
        case 0:
                if (debug)
                        pr2serr("%s trespass successful\n",
                                short_cmd ? "short" : "long");
                break;
        case SG_LIB_CAT_INVALID_OP:
        case SG_LIB_CAT_ILLEGAL_REQ:
                pr2serr("%s form trepass page failed, try again %s '-s' "
                        "option\n", short_cmd ? "short" : "long",
                        short_cmd ? "without" : "with");
                break;
        case SG_LIB_CAT_NOT_READY:
                pr2serr("device not ready\n");
                break;
        case SG_LIB_CAT_UNIT_ATTENTION:
                pr2serr("unit attention\n");
                break;
        default:
                sg_get_category_sense_str(res, sizeof(b), b, debug);
                pr2serr("%s trespass failed: %s\n",
                        (short_cmd ? "short" : "long"), b);
                break;
        }
        return res;
}

void usage ()
{
        pr2serr("Usage:  sg_emc_trespass [-d] [-hr] [-s] [-V] DEVICE\n"
                "  Change ownership of a LUN from another SP to this one.\n"
                "  EMC CLARiiON CX-/AX-family + FC5300/FC4500/FC4700.\n"
                "    -d : output debug\n"
                "    -hr: Set Honor Reservation bit\n"
                "    -s : Send Short Trespass Command page (default: long)\n"
                "         (for FC series)\n"
                "    -V: print version string then exit\n"
                "     DEVICE   sg or block device (latter in lk 2.6 or lk 3 "
                "series)\n"
                "        Example: sg_emc_trespass /dev/sda\n");
        exit (1);
}

int main(int argc, char * argv[])
{
        char **argptr;
        char * file_name = 0;
        int k, fd;
        int hr = 0;
        int short_cmd = 0;
        int ret = 0;

        if (argc < 2)
                usage ();

        for (k = 1; k < argc; ++k) {
                argptr = argv + k;
                if (!strcmp (*argptr, "-d"))
                        ++debug;
                else if (!strcmp (*argptr, "-s"))
                        short_cmd = 1;
                else if (!strcmp (*argptr, "-hr"))
                        hr = 1;
                else if (!strcmp (*argptr, "-V")) {
                        printf("Version string: %s\n", version_str);
                        exit(0);
                }
                else if (*argv[k] == '-') {
                        pr2serr("Unrecognized switch: %s\n", argv[k]);
                        file_name = 0;
                        break;
                }
                else if (0 == file_name)
                        file_name = argv[k];
                else {
                        pr2serr("too many arguments\n");
                        file_name = 0;
                        break;
                }
        }
        if (0 == file_name) {
                usage();
                return SG_LIB_SYNTAX_ERROR;
        }

        fd = open(file_name, O_RDWR | O_NONBLOCK);
        if (fd < 0) {
                pr2serr("Error trying to open %s\n", file_name);
                perror("");
                usage();
                return SG_LIB_FILE_ERROR;
        }

        ret = do_trespass(fd, hr, short_cmd);

        close (fd);
        return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
}
