diff options
author | joerg <joerg@FreeBSD.org> | 1997-03-06 15:30:06 +0000 |
---|---|---|
committer | joerg <joerg@FreeBSD.org> | 1997-03-06 15:30:06 +0000 |
commit | 22817fb6a16c5bff9c668d25b4bdc66c40524051 (patch) | |
tree | 3d5750a1edb527388a3ec3932a1a7073c03e0988 /bin | |
parent | c7d5f60d3a7e2e3c4da23b157c62504667344438 (diff) | |
download | FreeBSD-src-22817fb6a16c5bff9c668d25b4bdc66c40524051.zip FreeBSD-src-22817fb6a16c5bff9c668d25b4bdc66c40524051.tar.gz |
Import Jason Thorpe's contribution for an updated SCSI media changer
device (now, finally!).
Diffstat (limited to 'bin')
-rw-r--r-- | bin/chio/Makefile | 9 | ||||
-rw-r--r-- | bin/chio/chio.1 | 202 | ||||
-rw-r--r-- | bin/chio/chio.c | 663 | ||||
-rw-r--r-- | bin/chio/defs.h | 57 | ||||
-rw-r--r-- | bin/chio/pathnames.h | 35 |
5 files changed, 966 insertions, 0 deletions
diff --git a/bin/chio/Makefile b/bin/chio/Makefile new file mode 100644 index 0000000..73c1aa1 --- /dev/null +++ b/bin/chio/Makefile @@ -0,0 +1,9 @@ +# $Id: $ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= chio +SRCS= chio.c +BINOWN= root +BINMODE=4555 + +.include <bsd.prog.mk> diff --git a/bin/chio/chio.1 b/bin/chio/chio.1 new file mode 100644 index 0000000..22696f4 --- /dev/null +++ b/bin/chio/chio.1 @@ -0,0 +1,202 @@ +.\" $NetBSD: $ +.\" +.\" Copyright (c) 1996 Jason R. Thorpe <thorpej@and.com> +.\" 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 acknowledgements: +.\" This product includes software developed by Jason R. Thorpe +.\" for And Communications, http://www.and.com/ +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +.\" +.Dd April 2, 1996 +.Dt CHIO 1 +.Os +.Sh NAME +.Nm chio +.Nd medium changer control utility +.Sh SYNOPSIS +.Nm chio +.Op Fl f Ar changer +.Ar command +.Ar arg1 +.Ar arg2 +.Oo +.Ar arg3 Oo ... +.Oc +.Oc +.Sh DESCRIPTION +.Nm Chio +is used to control the operation of medium changers, such as those found +in tape and optical disk jukeboxes. +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl f Ar changer +Use the device +.Pa changer +rather than the default device +.Pa /dev/ch0 . +.El +.Pp +The default changer may be overridden by setting the environment variable +.Nm CHANGER +to the desired changer device. +.Pp +A medium changer apparatus is made up of +.Pa elements . +There are four element types: +.Pa picker +(medium transport), +.Pa slot +(storage), +.Pa portal +(import/export), and +.Pa drive +(data transfer). In this command description, the shorthand +.Nm ET +will be used to represent an element type, and +.Nm EU +will be used to represent an element unit. For example, to represent +the first robotic arm in the changer, the ET would be +.Dq picker +and the EU would be +.Dq 0 . +.Pp +.Sh SUPPORTED COMMANDS +.Nm chio move +.Ar <from ET> <from EU> <to ET> <to EU> +.Op Ar inv +.Pp +Moves the media unit from +.Pa <from ET/EU> +to +.Pa <to ET/EU> . +If the optional modifier +.Pa inv +is specified, the media unit will be inverted before insertion. +.Pp +.Nm chio exchange +.Ar <src ET> <src EU> <dst1 ET> <dst1 EU> +.Op Ar <dst2 ET> <dst2 ET> +.Op Ar inv1 +.Op Ar inv2 +.Pp +Performs a media unit exchange operation. The media unit in +.Pa <src ET/EU> +is moved to +.Pa <dst1 ET/EU> +and the media unit previously in +.Pa <dst1 ET/EU> +is moved to +.Pa <dst2 ET/EU> . +In the case of a simple exchange, +.Pa <dst2 ET/EU> +is omitted and the values +.Pa <src ET/EU> +are used in their place. +The optional modifiers +.Pa inv1 +and +.Pa inv2 +specify whether the media units are to be inverted before insertion into +.Pa <dst1 ET/EU> +and +.Pa <dst2 ET/EU> +respecitively. +.Pp +Note that not all medium changers support the +.Nm exchange +operation; The changer must have multiple free pickers or emulate +multiple free pickers with transient storage. +.Pp +.Nm chio position +.Ar <to ET> <to EU> +.Op Ar inv +.Pp +Position the picker in front of the element described by +.Pa <to ET/EU> . +If the optional modifier +.Pa inv +is specified, the media unit will be inverted before insertion. +.Pp +Note that not all changers behave as expected when issued this command. +.Pp +.Nm chio params +.Pp +Report the number of slots, drives, pickers, and portals in the changer, +and which picker unit the changer is currently configured to use. +.Pp +.Nm chio getpicker +.Pp +Report which picker unit the changer is currently configured to use. +.Pp +.Nm chio setpicker +.Ar <unit> +.Pp +Configure the changer to use picker +.Pa <unit> . +.Pp +.Nm chio status +.Op Ar <type> +.Pp +Report the status of all elements in the changer. If +.Pa <type> +is specified, report the status of all elements of type +.Pa <type> . +.Pp +The status bits are defined as follows: +.Bl -tag -width indent +.It Nm FULL +Element contains a media unit. +.It Nm IMPEXP +Media was deposited into element by an outside human operator. +.It Nm EXCEPT +Element is in an abnormal state. +.It Nm ACCESS +Media in this element is accessible by a picker. +.It Nm EXENAB +Element supports passing media (exporting) to an outsite human operator. +.It Nm INENAB +Element supports receiving media (importing) from an outside human operator. +.El +.Pp +.Sh EXAMPLES +.Nm chio move slot 3 drive 0 +.Pp +Moves the media in slot 3 (fourth slot) to drive 0 (first drive). +.Pp +.Nm chio setpicker 2 +Configures the changer to use picker 2 (third picker) for operations. +.Pp +.Sh FILES +/dev/ch0 - default changer device +.Sh SEE ALSO +.Xr mt 1 , +.Xr mount 8 . +.Sh AUTHOR +The +.Nm chio +program and SCSI changer driver were written by Jason R. Thorpe +<thorpej@and.com> for And Communications, http://www.and.com/ diff --git a/bin/chio/chio.c b/bin/chio/chio.c new file mode 100644 index 0000000..51a84e9 --- /dev/null +++ b/bin/chio/chio.c @@ -0,0 +1,663 @@ +/* $Id: $ */ + +/* + * Copyright (c) 1996 Jason R. Thorpe <thorpej@and.com> + * 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 acknowledgements: + * This product includes software developed by Jason R. Thorpe + * for And Communications, http://www.and.com/ + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <sys/param.h> +#include <sys/ioctl.h> +#include <sys/chio.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "defs.h" +#include "pathnames.h" + +extern char *__progname; /* from crt0.o */ + +static void usage __P((void)); +static void cleanup __P((void)); +static int parse_element_type __P((char *)); +static int parse_element_unit __P((char *)); +static int parse_special __P((char *)); +static int is_special __P((char *)); +static char *bits_to_string __P((int, const char *)); + +static int do_move __P((char *, int, char **)); +static int do_exchange __P((char *, int, char **)); +static int do_position __P((char *, int, char **)); +static int do_params __P((char *, int, char **)); +static int do_getpicker __P((char *, int, char **)); +static int do_setpicker __P((char *, int, char **)); +static int do_status __P((char *, int, char **)); + +/* Valid changer element types. */ +const struct element_type elements[] = { + { "picker", CHET_MT }, + { "slot", CHET_ST }, + { "portal", CHET_IE }, + { "drive", CHET_DT }, + { NULL, 0 }, +}; + +/* Valid commands. */ +const struct changer_command commands[] = { + { "move", do_move }, + { "exchange", do_exchange }, + { "position", do_position }, + { "params", do_params }, + { "getpicker", do_getpicker }, + { "setpicker", do_setpicker }, + { "status", do_status }, + { NULL, 0 }, +}; + +/* Valid special words. */ +const struct special_word specials[] = { + { "inv", SW_INVERT }, + { "inv1", SW_INVERT1 }, + { "inv2", SW_INVERT2 }, + { NULL, 0 }, +}; + +static int changer_fd; +static char *changer_name; + +int +main(argc, argv) + int argc; + char **argv; +{ + int ch, i; + char *cp; + + while ((ch = getopt(argc, argv, "f:")) != -1) { + switch (ch) { + case 'f': + changer_name = optarg; + break; + + default: + usage(); + } + } + argc -= optind; + argv += optind; + + if (argc == 0) + usage(); + + /* Get the default changer if not already specified. */ + if (changer_name == NULL) + if ((changer_name = getenv(CHANGER_ENV_VAR)) == NULL) + changer_name = _PATH_CH; + + /* Open the changer device. */ + if ((changer_fd = open(changer_name, O_RDWR, 0600)) == -1) + err(1, "%s: open", changer_name); + + /* Register cleanup function. */ + if (atexit(cleanup)) + err(1, "can't register cleanup function"); + + /* Find the specified command. */ + for (i = 0; commands[i].cc_name != NULL; ++i) + if (strcmp(*argv, commands[i].cc_name) == 0) + break; + if (commands[i].cc_name == NULL) + errx(1, "unknown command: %s", *argv); + + /* Skip over the command name and call handler. */ + ++argv; --argc; + exit ((*commands[i].cc_handler)(commands[i].cc_name, argc, argv)); +} + +static int +do_move(cname, argc, argv) + char *cname; + int argc; + char **argv; +{ + struct changer_move cmd; + int val; + + /* + * On a move command, we expect the following: + * + * <from ET> <from EU> <to ET> <to EU> [inv] + * + * where ET == element type and EU == element unit. + */ + if (argc < 4) { + warnx("%s: too few arguments", cname); + goto usage; + } else if (argc > 5) { + warnx("%s: too many arguments", cname); + goto usage; + } + bzero(&cmd, sizeof(cmd)); + + /* <from ET> */ + cmd.cm_fromtype = parse_element_type(*argv); + ++argv; --argc; + + /* <from EU> */ + cmd.cm_fromunit = parse_element_unit(*argv); + ++argv; --argc; + + /* <to ET> */ + cmd.cm_totype = parse_element_type(*argv); + ++argv; --argc; + + /* <to EU> */ + cmd.cm_tounit = parse_element_unit(*argv); + ++argv; --argc; + + /* Deal with optional command modifier. */ + if (argc) { + val = parse_special(*argv); + switch (val) { + case SW_INVERT: + cmd.cm_flags |= CM_INVERT; + break; + + default: + errx(1, "%s: inappropriate modifier `%s'", + cname, *argv); + /* NOTREACHED */ + } + } + + /* Send command to changer. */ + if (ioctl(changer_fd, CHIOMOVE, (char *)&cmd)) + err(1, "%s: CHIOMOVE", changer_name); + + return (0); + + usage: + fprintf(stderr, "usage: %s %s " + "<from ET> <from EU> <to ET> <to EU> [inv]\n", __progname, cname); + return (1); +} + +static int +do_exchange(cname, argc, argv) + char *cname; + int argc; + char **argv; +{ + struct changer_exchange cmd; + int val; + + /* + * On an exchange command, we expect the following: + * + * <src ET> <src EU> <dst1 ET> <dst1 EU> [<dst2 ET> <dst2 EU>] [inv1] [inv2] + * + * where ET == element type and EU == element unit. + */ + if (argc < 4) { + warnx("%s: too few arguments", cname); + goto usage; + } else if (argc > 8) { + warnx("%s: too many arguments", cname); + goto usage; + } + bzero(&cmd, sizeof(cmd)); + + /* <src ET> */ + cmd.ce_srctype = parse_element_type(*argv); + ++argv; --argc; + + /* <src EU> */ + cmd.ce_srcunit = parse_element_unit(*argv); + ++argv; --argc; + + /* <dst1 ET> */ + cmd.ce_fdsttype = parse_element_type(*argv); + ++argv; --argc; + + /* <dst1 EU> */ + cmd.ce_fdstunit = parse_element_unit(*argv); + ++argv; --argc; + + /* + * If the next token is a special word or there are no more + * arguments, then this is a case of simple exchange. + * dst2 == src. + */ + if ((argc == 0) || is_special(*argv)) { + cmd.ce_sdsttype = cmd.ce_srctype; + cmd.ce_sdstunit = cmd.ce_srcunit; + goto do_special; + } + + /* <dst2 ET> */ + cmd.ce_sdsttype = parse_element_type(*argv); + ++argv; --argc; + + /* <dst2 EU> */ + cmd.ce_sdstunit = parse_element_unit(*argv); + ++argv; --argc; + + do_special: + /* Deal with optional command modifiers. */ + while (argc) { + val = parse_special(*argv); + ++argv; --argc; + switch (val) { + case SW_INVERT1: + cmd.ce_flags |= CE_INVERT1; + break; + + case SW_INVERT2: + cmd.ce_flags |= CE_INVERT2; + break; + + default: + errx(1, "%s: inappropriate modifier `%s'", + cname, *argv); + /* NOTREACHED */ + } + } + + /* Send command to changer. */ + if (ioctl(changer_fd, CHIOEXCHANGE, (char *)&cmd)) + err(1, "%s: CHIOEXCHANGE", changer_name); + + return (0); + + usage: + fprintf(stderr, "usage: %s %s <src ET> <src EU> <dst1 ET> <dst1 EU>\n" + " [<dst2 ET> <dst2 EU>] [inv1] [inv2]\n", + __progname, cname); + return (1); +} + +static int +do_position(cname, argc, argv) + char *cname; + int argc; + char **argv; +{ + struct changer_position cmd; + int val; + + /* + * On a position command, we expect the following: + * + * <to ET> <to EU> [inv] + * + * where ET == element type and EU == element unit. + */ + if (argc < 2) { + warnx("%s: too few arguments", cname); + goto usage; + } else if (argc > 3) { + warnx("%s: too many arguments", cname); + goto usage; + } + bzero(&cmd, sizeof(cmd)); + + /* <to ET> */ + cmd.cp_type = parse_element_type(*argv); + ++argv; --argc; + + /* <to EU> */ + cmd.cp_unit = parse_element_unit(*argv); + ++argv; --argc; + + /* Deal with optional command modifier. */ + if (argc) { + val = parse_special(*argv); + switch (val) { + case SW_INVERT: + cmd.cp_flags |= CP_INVERT; + break; + + default: + errx(1, "%s: inappropriate modifier `%s'", + cname, *argv); + /* NOTREACHED */ + } + } + + /* Send command to changer. */ + if (ioctl(changer_fd, CHIOPOSITION, (char *)&cmd)) + err(1, "%s: CHIOPOSITION", changer_name); + + return (0); + + usage: + fprintf(stderr, "usage: %s %s <to ET> <to EU> [inv]\n", + __progname, cname); + return (1); +} + +static int +do_params(cname, argc, argv) + char *cname; + int argc; + char **argv; +{ + struct changer_params data; + + /* No arguments to this command. */ + if (argc) { + warnx("%s: no arguements expected", cname); + goto usage; + } + + /* Get params from changer and display them. */ + bzero(&data, sizeof(data)); + if (ioctl(changer_fd, CHIOGPARAMS, (char *)&data)) + err(1, "%s: CHIOGPARAMS", changer_name); + + printf("%s: %d slot%s, %d drive%s, %d picker%s", + changer_name, + data.cp_nslots, (data.cp_nslots > 1) ? "s" : "", + data.cp_ndrives, (data.cp_ndrives > 1) ? "s" : "", + data.cp_npickers, (data.cp_npickers > 1) ? "s" : ""); + if (data.cp_nportals) + printf(", %d portal%s", data.cp_nportals, + (data.cp_nportals > 1) ? "s" : ""); + printf("\n%s: current picker: %d\n", changer_name, data.cp_curpicker); + + return (0); + + usage: + fprintf(stderr, "usage: %s %s\n", __progname, cname); + return (1); +} + +static int +do_getpicker(cname, argc, argv) + char *cname; + int argc; + char **argv; +{ + int picker; + + /* No arguments to this command. */ + if (argc) { + warnx("%s: no arguments expected", cname); + goto usage; + } + + /* Get current picker from changer and display it. */ + if (ioctl(changer_fd, CHIOGPICKER, (char *)&picker)) + err(1, "%s: CHIOGPICKER", changer_name); + + printf("%s: current picker: %d\n", changer_name, picker); + + return (0); + + usage: + fprintf(stderr, "usage: %s %s\n", __progname, cname); + return (1); +} + +static int +do_setpicker(cname, argc, argv) + char *cname; + int argc; + char **argv; +{ + int picker; + + if (argc < 1) { + warnx("%s: too few arguments", cname); + goto usage; + } else if (argc > 1) { + warnx("%s: too many arguments", cname); + goto usage; + } + + picker = parse_element_unit(*argv); + + /* Set the changer picker. */ + if (ioctl(changer_fd, CHIOSPICKER, (char *)&picker)) + err(1, "%s: CHIOSPICKER", changer_name); + + return (0); + + usage: + fprintf(stderr, "usage: %s %s <picker>\n", __progname, cname); + return (1); +} + +static int +do_status(cname, argc, argv) + char *cname; + int argc; + char **argv; +{ + struct changer_element_status cmd; + struct changer_params data; + u_int8_t *statusp; + int i, count, chet, schet, echet; + char *cmdname, *description; + + /* + * On a status command, we expect the following: + * + * [<ET>] + * + * where ET == element type. + * + * If we get no arguments, we get the status of all + * known element types. + */ + if (argc > 1) { + warnx("%s: too many arguments", cname); + goto usage; + } + + /* + * Get params from changer. Specifically, we need the element + * counts. + */ + bzero(&data, sizeof(data)); + if (ioctl(changer_fd, CHIOGPARAMS, (char *)&data)) + err(1, "%s: CHIOGPARAMS", changer_name); + + if (argc) + schet = echet = parse_element_type(*argv); + else { + schet = CHET_MT; + echet = CHET_DT; + } + + for (chet = schet; chet <= echet; ++chet) { + switch (chet) { + case CHET_MT: + count = data.cp_npickers; + description = "picker"; + break; + + case CHET_ST: + count = data.cp_nslots; + description = "slot"; + break; + + case CHET_IE: + count = data.cp_nportals; + description = "portal"; + break; + + case CHET_DT: + count = data.cp_ndrives; + description = "drive"; + break; + } + + if (count == 0) { + if (argc == 0) + continue; + else { + printf("%s: no %s elements\n", + changer_name, description); + return (0); + } + } + + /* Allocate storage for the status bytes. */ + if ((statusp = (u_int8_t *)malloc(count)) == NULL) + errx(1, "can't allocate status storage"); + + bzero(statusp, count); + bzero(&cmd, sizeof(cmd)); + + cmd.ces_type = chet; + cmd.ces_data = statusp; + + if (ioctl(changer_fd, CHIOGSTATUS, (char *)&cmd)) { + free(statusp); + err(1, "%s: CHIOGSTATUS", changer_name); + } + + /* Dump the status for each element of this type. */ + for (i = 0; i < count; ++i) { + printf("%s %d: %s\n", description, i, + bits_to_string(statusp[i], CESTATUS_BITS)); + } + + free(statusp); + } + + return (0); + + usage: + fprintf(stderr, "usage: %s %s [<element type>]\n", __progname, + cname); + return (1); +} + +static int +parse_element_type(cp) + char *cp; +{ + int i; + + for (i = 0; elements[i].et_name != NULL; ++i) + if (strcmp(elements[i].et_name, cp) == 0) + return (elements[i].et_type); + + errx(1, "invalid element type `%s'", cp); +} + +static int +parse_element_unit(cp) + char *cp; +{ + int i; + char *p; + + i = (int)strtol(cp, &p, 10); + if ((i < 0) || (*p != '\0')) + errx(1, "invalid unit number `%s'", cp); + + return (i); +} + +static int +parse_special(cp) + char *cp; +{ + int val; + + val = is_special(cp); + if (val) + return (val); + + errx(1, "invalid modifier `%s'", cp); +} + +static int +is_special(cp) + char *cp; +{ + int i; + + for (i = 0; specials[i].sw_name != NULL; ++i) + if (strcmp(specials[i].sw_name, cp) == 0) + return (specials[i].sw_value); + + return (0); +} + +static char * +bits_to_string(v, cp) + int v; + const char *cp; +{ + const char *np; + char f, sep, *bp; + static char buf[128]; + + bp = buf; + bzero(buf, sizeof(buf)); + + for (sep = '<'; (f = *cp++) != 0; cp = np) { + for (np = cp; *np >= ' ';) + np++; + if ((v & (1 << (f - 1))) == 0) + continue; + bp += sprintf(bp, "%c%.*s", sep, np - cp, cp); + sep = ','; + } + if (sep != '<') + *bp = '>'; + + return (buf); +} + +static void +cleanup() +{ + + /* Simple enough... */ + (void)close(changer_fd); +} + +static void +usage() +{ + + fprintf(stderr, "usage: %s command arg1 arg2 ...\n", __progname); + exit(1); +} diff --git a/bin/chio/defs.h b/bin/chio/defs.h new file mode 100644 index 0000000..5bab57e --- /dev/null +++ b/bin/chio/defs.h @@ -0,0 +1,57 @@ +/* $Id: $ */ + +/* + * Copyright (c) 1996 Jason R. Thorpe <thorpej@and.com> + * 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 acknowledgements: + * This product includes software developed by Jason R. Thorpe + * for And Communications, http://www.and.com/ + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +struct element_type { + char *et_name; /* name; i.e. "picker, "slot", etc. */ + int et_type; /* type number */ +}; + +struct changer_command { + char *cc_name; /* command name */ + /* command handler */ + int (*cc_handler) __P((char *, int, char **)); +}; + +struct special_word { + char *sw_name; /* special word */ + int sw_value; /* token value */ +}; + +/* sw_value */ +#define SW_INVERT 1 /* set "invert media" flag */ +#define SW_INVERT1 2 /* set "invert media 1" flag */ +#define SW_INVERT2 3 /* set "invert media 2" flag */ + +/* Environment variable to check for default changer. */ +#define CHANGER_ENV_VAR "CHANGER" diff --git a/bin/chio/pathnames.h b/bin/chio/pathnames.h new file mode 100644 index 0000000..cdd67fa --- /dev/null +++ b/bin/chio/pathnames.h @@ -0,0 +1,35 @@ +/* $Id: $ */ + +/* + * Copyright (c) 1996 Jason R. Thorpe <thorpej@and.com> + * 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 acknowledgements: + * This product includes software developed by Jason R. Thorpe + * for And Communications, http://www.and.com/ + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#define _PATH_CH "/dev/ch0" |