/*
 *   Copyright (c) 1996-1999 David Parsons. All rights reserved.
 *   
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
 *   are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. 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.
 *  3. All advertising materials mentioning features or use of this
 *     software must display the following acknowledgement:
 *     
 *   This product includes software developed by David Parsons
 *   (orc@pell.chi.il.us)
 *
 *  4. My name may not be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *     
 *  THIS SOFTWARE IS PROVIDED BY DAVID PARSONS ``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 DAVID
 *  PARSONS 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.
 */

static const char rcsid[] = "$Id: s.media.c 1.8 00/02/01 22:42:44-00:00 orc $";

/*
 * media: media description table.
 */

#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <sys/mount.h>
#include <linux/cdrom.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "util.h"
#include "media.h"
#include "pathnames.h"


#ifdef WORKING_NFS_MOUNT
extern int nfsmount(__const char *where, __const char *dir,
                    __const char *fstype, unsigned long flags,
		    __const void *x);
extern int nfsumount(__const char *dir);
#else
static int nfsmount(__const char *where, __const char *dir,
                    __const char *fstype, unsigned long flags,
		    __const void *x)
{
    die("NFS MOUNTING NOT YET SUPPORTED");
    return EOF;
}

static int nfsumount(__const char *dir)
{
    die("NFS MOUNTING NOT YET SUPPORTED");
    return EOF;
}
#endif


/*
 * cde() ejects a CD.
 */
int
cde(int fd)
{
    return ioctl(fd, CDROMEJECT);
} /* cde */


/*
 * cdl() closes the CD door.
 */
int
cdl(int fd)
{
    return ioctl(fd, CDROMCLOSETRAY);
} /* cdl */


/*
 * dummy() does nothing successfully
 */
int
dummy(int fd)
{
    return 0;
} /* dummy */


static struct media media[] = {
    { M_VOID,  "nil",    0, "nil",     "nil",
			 0,         0, dummy, dummy },
    { M_ZIP,   "ZIP",    0, "vfat",    "mode=365",
			mount,    umount,  dummy, dummy },
    { M_NFS,   "nfs",    0, "nfs",     "ro",
			nfsmount, nfsumount, dummy, dummy },
    { M_CDROM, "CD-ROM", 0, "iso9660", "mode=365",
			mount,       umount, cde,   cdl   },
    { M_DOS,   "DOS partition", 0, "vfat", "mode=365",
			mount,	umount, dummy, dummy },
    { M_FLOP,  "Floppy disk", 0,   "vfat", "mode=365",
			0, 0, dummy, dummy },
} ;

#define NR_MEDIA	(sizeof media / sizeof media[0])

void *
getmedia(enum mediatypes mtype)
{
    int i;

    for (i = 0; i < NR_MEDIA; i++)
	if (media[i].m_type == mtype)
	    return (void*) &media[i];
    return (void*)0;
} /* getmedia */


/*
 * open_media() attempts to mount the desired medium
 */
int
open_media(void *m)
{
    extern int mount_disk();

    if (m == 0) {
	errno = 0;
	Error("                CAN'T HAPPEN?\n"
	      "open_media() called with a null media descriptor?");
	return 0;
    }

    /* mount the install medium
     */
    switch (MEDIATYPE(m)) {
    case M_DOS:
    case M_ZIP:
    case M_CDROM:
		return mount_disk();
    default:
		errno = 0;
		Error("You're trying to install from something unknown");
		return 0;
    }
    return 1;
} /* open_media */


/*
 * close_media() detaches from the selected medium
 */
void
close_media(void *m)
{
    if (m)
	umount(TARGET);
} /* close_media */


/*
 * eject_media() spits out the selected medium, if possible
 */
void
eject_media(void *m)
{
    int fd;

    if ((fd = open(MEDIA(m), 0)) >= 0) {
	EJECT(m)(fd);
	close(fd);
    }
} /* eject_media */


/*
 * mediadesc() returns a string describing a given install medium
 */
char*
mediadesc(struct idiskinfo *x)
{
    static char bfr[40];
    char *typeofdisk = x->flags & ID_SCSI ? "SCSI" : "IDE";

    if (x->flags & ID_CDROM)
	snprintf(bfr, sizeof bfr, "%s CD-ROM", typeofdisk);
    else if (x->flags & ID_REMOVABLE)
	snprintf(bfr, sizeof bfr, "Removable %s disk", typeofdisk);
    else
	snprintf(bfr, sizeof bfr, "%s disk", typeofdisk);

    return bfr;
} /* mediadesc */
