/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ #pragma ident "%Z%%M% %I% %E% SMI" /* * devfree key [device [...]] */ #include #include #include #include #include #include #include #include #include #include /* * Local definitions * TRUE Boolean TRUE value * FALSE Boolean FALSE value */ #ifndef TRUE #define TRUE ('t') #endif #ifndef FALSE #define FALSE 0 #endif /* * Exit codes: * EX_OK Exit code for all went well * EX_ERROR Exit code for something failed * EX_TBLERR Exit code for errors relating to device or lock tables * EX_NOFREE Exit code for free failed */ #define EX_OK 0 #define EX_ERROR 1 #define EX_TBLERR 2 #define EX_NOFREE 3 /* * Messages * M_USAGE Usage error * M_INVKEY Invalid key specified * M_NOTRSVD Attempting to free something not alloc'd * M_NOTONKEY Attempting to free with wrong key * M_DEVTAB Error opening the device table * M_RSVTAB Error opening the device-reservation table * M_ERROR Some internal error */ #define M_USAGE "usage: devfree key [device [...]]" #define M_INVKEY "Invalid key: %s" #define M_NOTRSVD "Device not reserved: %s" #define M_NOTONKEY "Cannot unreserve device: %s" #define M_DEVTAB "Cannot open the device table: %s" #define M_RSVTAB "Cannot open the device-reservation table: %s" #define M_ERROR "Internal error, errno=%d" /* * Local functions and static data * stdmsg(r,l,s,m) Macro for standard message generation * r MM_NRECOV or MM_RECOV (recoverability) * l Label * s Severity * m Message * lbl Buffer for the label-component of a message. * msg Buffer for the text-component of a message. */ #define stdmsg(r,l,s,m) (void) fmtmsg(MM_PRINT|MM_UTIL|r,l,s,m,MM_NULLACT,MM_NULLTAG) static char lbl[MM_MXLABELLN+1]; static char msg[MM_MXTXTLN+1]; /* * devfree key [device [device [...]]] * * This command frees devices that have been reserved using * the devreserv command (or the devreserv() function). * * Options: None * * Arguments: * key The key on which the device to free was allocated on. * If omitted, all keys are assumed. * device The device to free. If omitted, all devices allocated * using the key are freed. * * Command Values: * EX_OK 0 Device(s) successfully freed * EX_ERROR 1 A syntax error or other error occurred * EX_TBLERR 2 A problem with device management tables * EX_NOFREE 3 A requested device couldn't be freed */ int main(int argc, char *argv[]) { /* Automatics */ char **argp; /* Ptr to current argument */ struct reservdev **rsvd; /* Ptr to list of locks */ struct reservdev **plk; /* Running ptr to locks */ char *devtab; /* Ptr to device table name */ char *rsvtab; /* Ptr to dev-rsv-tbl name */ char *p; /* Temp char pointer */ int argcount; /* Number of args on cmd */ long lkey; /* Key for locking (long) */ int key; /* Key for locking */ int halt; /* TRUE if we need to stop */ int sev; /* Message severity */ int exitcode; /* Value of command */ int syntaxerr; /* Flag, TRUE if syntax error */ int exitcd; /* Value for exit() */ int c; /* Option character */ /* * Initializations */ /* Build a message label */ if (p = strrchr(argv[0], '/')) p++; else p = argv[0]; (void) strlcat(strcpy(lbl, "UX:"), p, sizeof(lbl)); /* Make only the text component of messages appear (remove this in SVR4.1) */ (void) putenv("MSGVERB=text"); /* * Parse the options from the command line */ opterr = 0; syntaxerr = FALSE; while ((c = getopt(argc, argv, "")) != EOF) switch(c) { default: syntaxerr = FALSE; break; } /* Argument initializations */ argp = &argv[optind]; if ((argcount = argc-optind) < 1) syntaxerr = TRUE; /* If there's (an obvious) syntax error, write a message and quit */ if (syntaxerr) { stdmsg(MM_NRECOV, lbl, MM_ERROR, M_USAGE); exit(EX_ERROR); } /* * devfree key * * Free all devices that have been reserved using the key "key". */ if (argcount == 1) { /* Extract the key from the command */ lkey = strtol(*argp, &p, 10); if (*p || (lkey <= 0) || (lkey > MAXINT)) { (void) snprintf(msg, sizeof (msg), M_INVKEY, *argp); stdmsg(MM_NRECOV, lbl, MM_ERROR, msg); exit(EX_ERROR); } key = (int) lkey; /* Get the list of devices currently reserved */ if (rsvd = reservdev()) { exitcd = EX_OK; for (plk = rsvd ; *plk ; plk++) { if ((*plk)->key == key) if (devfree(key, (*plk)->devname) != 0) exitcd = EX_NOFREE; } } else { if (((errno == ENOENT) || (errno == EACCES)) && (rsvtab = _rsvtabpath())) { (void) snprintf(msg, sizeof(msg), M_RSVTAB, rsvtab); exitcd = EX_TBLERR; sev = MM_ERROR; } else { (void) snprintf(msg, sizeof (msg), M_ERROR, errno); exitcd = EX_ERROR; sev = MM_HALT; } stdmsg(MM_NRECOV, lbl, sev, msg); } /* Done */ exit(exitcd); } /* * devfree key device [...] * * Free specific devices */ /* Open the device file (if there's one to be opened) */ if (!_opendevtab("r")) { if (devtab = _devtabpath()) { (void) snprintf(msg, sizeof(msg), M_DEVTAB, devtab); exitcd = EX_TBLERR; sev = MM_ERROR; } else { (void) snprintf(msg, sizeof (msg), M_ERROR, errno); exitcd = EX_ERROR; sev = MM_HALT; } stdmsg(MM_NRECOV, lbl, sev, msg); exit(exitcd); } /* Extract the key from the command */ lkey = strtol(*argp, &p, 10); if (*p || (lkey <= 0) || (lkey > MAXINT)) { (void) snprintf(msg, sizeof(msg), M_INVKEY, *argp); stdmsg(MM_NRECOV, lbl, MM_ERROR, msg); exit(EX_ERROR); } key = (int) lkey; argp++; /* Loop through the list of devices to free */ exitcode = EX_OK; halt = FALSE; while (!halt && *argp) { /* Try to free the device */ if (devfree(key, *argp) != 0) { if ((errno == EACCES) || (errno == ENOENT)) { /* Can't get at reservation file */ if (rsvtab = _rsvtabpath()) { exitcode = EX_TBLERR; (void) snprintf(msg, sizeof(msg), M_RSVTAB, rsvtab); sev = MM_ERROR; } else { exitcode = EX_ERROR; (void) snprintf(msg, sizeof (msg), M_ERROR, errno); sev = MM_HALT; } stdmsg(MM_NRECOV, lbl, sev, msg); halt = TRUE; } else if (errno == EPERM) { /* Wrong key */ (void) snprintf(msg, sizeof(msg), M_NOTONKEY, *argp); stdmsg(MM_NRECOV, lbl, MM_ERROR, msg); exitcode = EX_NOFREE; } else if (errno == EINVAL) { /* Device not reserved */ (void) snprintf(msg, sizeof(msg), M_NOTRSVD, *argp); stdmsg(MM_NRECOV, lbl, MM_ERROR, msg); exitcode = EX_NOFREE; } else { /* Some other strange error occurred */ (void) snprintf(msg, sizeof (msg), M_ERROR, errno); stdmsg(MM_NRECOV, lbl, MM_HALT, msg); exitcode = EX_ERROR; halt = TRUE; } } argp++; } /* Exit with the appropriate code */ return(exitcode); }