1
0
Files
irix-657m-src/eoe/include/mediaclient.h
2022-09-29 17:59:04 +03:00

275 lines
10 KiB
C

/*-*-C-*-******************************************************************
* *
* Copyright (C) 1995, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#ifndef mediaclient_included
#define mediaclient_included
/*
* This is the media client interface. The basic idea is that a
* client creates a port to monitor a system's removable media
* devices, then at asynchronous intervals it is notified that the
* system's device state has changed.
*
* A system's state has three parts: volumes, devices and partitions.
* A volume is the backing store behind a (potential) file system.
* A device is a hardware device such as a CD-ROM drive.
* A partition is a section of a device's media that may be part of a volume.
*
* Each volume is made up of one or more partitions. Each device, if
* its media is present, has zero or more partitions. Each partition
* is part of exactly one device.
*/
#include <sys/invent.h> /* for inventory_t, __uint64_t */
#include <sys/time.h> /* for time_t */
#if defined(__cplusplus)
extern "C" {
#endif
# define MC_IX_WHOLE -1 /* partition index for whole disk */
/* device formats, aka types. */
# define MC_FMT_RAW "raw" /* raw data */
# define MC_FMT_EFS "efs" /* SGI Extent File System */
# define MC_FMT_XFS "xfs" /* SGI "x" File System */
# define MC_FMT_DOS "dos" /* Microsoft DOS filesystem */
# define MC_FMT_HFS "hfs" /* Apple Hierarchical File System */
# define MC_FMT_ISO9660 "iso9660" /* ISO std. 9660 (CD-ROM) */
# define MC_FMT_MUSIC "music" /* Audio (DAT) */
# define MC_FMT_CDDA "cdda" /* Compact Disc Digital Audio */
/* Subformats. In (mc_volume *)->mcv_subformat. */
# define MC_SBFMT_PHOTOCD "photocd"/* Photo CD */
# define MC_SBFMT_INST "inst" /* SGI installation volume */
# define MC_DEV_NOTIGNORED (1 << 0)
# define MC_DEV_SUSPENDED (1 << 1)
/* MC_VOL_FORCE_UNMOUNT is used to overload a boolean (mcv_mounted)
* to indicate as part of MCE_FORCEUNMOUNT events which volume is
* going to be unmounted.
*/
# define MC_VOL_FORCEUNMOUNT (1 << 1)
typedef int mc_bool_t;
typedef void *mc_closure_t;
typedef void *mc_port_t;
typedef struct mc_device mc_device_t;
typedef struct mc_partition mc_partition_t;
typedef struct mc_system mc_system_t;
typedef struct mc_volume mc_volume_t;
typedef struct mc_event mc_event_t;
typedef struct mc_what_next mc_what_next_t;
struct mc_system {
unsigned int mcs_n_volumes; /* number of volumes in system */
unsigned int mcs_n_devices; /* number of devices in system */
unsigned int mcs_n_parts; /* number of partitions in system */
mc_volume_t *mcs_volumes; /* ptr to array of volumes */
mc_device_t *mcs_devices; /* ptr to array of devices */
mc_partition_t *mcs_partitions; /* ptr to array of partitions */
};
struct mc_volume {
char *mcv_label; /* volume label, if any */
char *mcv_fsname; /* e.g., /dev/dsk/dks... */
char *mcv_dir; /* mount point */
char *mcv_type; /* volume type (format), MC_FMT_xxx */
char *mcv_subformat; /* volume subformat, MC_SBFMT_xxx */
char *mcv_mntopts; /* mount options */
mc_bool_t mcv_mounted; /* is volume mounted? */
mc_bool_t mcv_exported; /* is volume exported? */
unsigned int mcv_nparts; /* number of partition ptrs */
mc_partition_t **mcv_parts; /* points to array of part. ptrs */
};
struct mc_device {
char *mcd_name; /* device's short name */
char *mcd_fullname; /* device's printable name */
char *mcd_ftrname; /* device's name as used in FTRs */
char *mcd_devname; /* name of some special file that
refers to device. */
inventory_t mcd_invent; /* device's H/W inventory record */
mc_bool_t mcd_monitored; /* is mediad monitoring it? */
/* Actually, mcd_monitored is two flag bits, MC_DEV_NOTIGNORED
* and MC_DEV_SUSPENDED. It's declared as a bool for
* pseudocompatibility with IRIX 6.3.
*/
mc_bool_t mcd_media_present; /* is media present? */
mc_bool_t mcd_write_protected; /* is device write-locked? */
mc_bool_t mcd_shared; /* is device shared? */
unsigned int mcd_nparts; /* number of partition ptrs */
mc_partition_t **mcd_parts; /* points to array of part. ptrs */
};
struct mc_partition {
mc_device_t *mcp_device; /* device of which this is part */
char *mcp_format; /* partition format, MC_FMT_xxx */
int mcp_index; /* partition # or MC_IX_WHOLE */
unsigned int mcp_sectorsize;/* size of sector in bytes */
__uint64_t mcp_sector0; /* starting sector number */
__uint64_t mcp_nsectors; /* number of sectors in part. */
};
typedef enum mc_event_type {
MCE_NO_EVENT, /* no event. */
MCE_NO_DEVICES, /* no devices in system */
MCE_CONFIG, /* device config changed */
/* Device events */
MCE_INSERTION, /* media was inserted in device */
MCE_EJECTION, /* media was ejected from device */
MCE_SUSPEND, /* monitoring was suspended */
MCE_RESUME, /* monitoring was resumed */
/* Volume events */
MCE_MOUNT, /* volume was mounted */
MCE_DISMOUNT, /* volume was dismounted */
MCE_EXPORT, /* volume was exported */
MCE_UNEXPORT, /* volume was unexported */
MCE_FORCEUNMOUNT /* forced dismount pending */
} mc_event_type_t;
struct mc_event {
mc_event_type_t mce_type;
int mce_volume;
int mce_device;
};
/*
* An mc_port is the object through which everything is accessed.
*
* mc_create_port() creates a port and returns an opaque pointer
* to it. Pass in the IP address of the host to be monitored
* (INADDR_LOOPBACK from <netinet/in.h> to monitor the local system)
* and a callback function. The function is called whenever
* the system's media state changes.
*
* mc_destroy_port() destroys a port and all its resources.
* N.B., if the application has allocated resources on mc's
* behalf, e.g., timeouts or selection mask bits, it's the app's
* job to clean those up.
*
* mc_execute() should be called at various times. Call it once
* after creating an mc_port. It returns an mc_what_next
* structure describing when it should be called again.
* mc_what_next specifies that mc_execute should be called when a
* file descriptor is readable or writable (as determined by
* select(2)) or after a timeout of some number of seconds'
* duration.
*
* mc_system_state() returns an mc_system structure describing
* the current state of that system. It may be called at any
* time. It returns NULL if mediad on that system has not yet
* been reached.
*
* The mc_port will contact mediad on the given machine. If the
* machine is down, or if mediad is not responding, the mc_port
* will repeatedly try to connect. Once it connects, it will
* receive messages from mediad asynchronously. For these
* reasons, it needs scheduling support from the application.
*/
typedef void (*mc_event_proc_t)(mc_port_t,
mc_closure_t,
const mc_event_t *);
typedef enum mc_what {
MC_IDLE, /* never seen */
MC_INPUT, /* wait for input */
MC_OUTPUT, /* wait for output */
MC_TIMEOUT /* wait for timeout */
} mc_what_t;
typedef enum mc_failure_code {
MCF_SUCCESS, /* no problem, man! */
MCF_SYS_ERROR, /* system error - check errno */
MCF_NO_HOST, /* can't contact host */
MCF_NO_MEDIAD, /* can't contact mediad */
MCF_INPUT_ERROR /* error parsing an event */
} mc_failure_code_t;
struct mc_what_next {
mc_what_t mcwn_what; /* N.B. MC_IDLE never seen */
int mcwn_fd; /* descriptor for select */
time_t mcwn_seconds; /* timeout duration */
mc_failure_code_t mcwn_failcode;
};
mc_port_t mc_create_port(__uint32_t IPaddress,
mc_event_proc_t, mc_closure_t);
void mc_destroy_port(mc_port_t);
/*
* register to receive "forced unmount" events before getting killed
* via fuser -k
*/
void mc_forced_unmounts(mc_port_t);
const mc_what_next_t *mc_execute(mc_port_t);
const mc_system_t *mc_system_state(mc_port_t);
/*
* An alternate way to connect to mediad is to use mc_port_connect().
* mc_port_connect blocks until it has connected to mediad, then
* it returns the descriptor on which the caller should block
* on input. The caller would look like this.
*
* mc_port_t p = mc_create_port(whatever...);
* int fd = mc_port_connect(p);
* // ...
* // live a full, happy life,
* // and select on fd for reading for as long as mc_execute()
* // returns MC_INPUT
* // ...
* mc_destroy_port(p);
*
* If mediad is not running or is not accepting connections when
* mc_port_connect is * called, mc_port_connect returns -1.
*/
int mc_port_connect(mc_port_t);
/*
* Convenience functions.
*
* mc_dup_system() duplicates an mc_system and all its subordinate
* structures. Think of it as a copy constructor.
*
* mc_destroy_system() destroys an mc_system returned by mc_dup_system().
*/
mc_system_t *mc_dup_system(const mc_system_t *);
void mc_destroy_system(mc_system_t *);
#if defined(__cplusplus)
} // end extern "C"
#endif
#ifdef JOKE
/*
* mc_system, mc_device, mc_partition, and mc_volume are registered
* trademarks of McDonald's, Inc.
*/
#endif /* JOKE */
#endif /* !mediaclient_included */