rmm_util.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* 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
* 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 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#define DEBUG 1
#include <stdio.h>
#include <dlfcn.h>
#include <errno.h>
#include <string.h>
#include <stdarg.h>
#include <fcntl.h>
#include <rmmount.h>
#include <libintl.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include "rmm_int.h"
/*
* file pointer for mnttab
*/
/*
* Load a dso named "name" into our address space, and return a pointer
* to the function named "funcname"
*/
void *
{
void *dso_handle = NULL;
/*
* Look for the name with the correct version in various places.
* Algorithm: /usr/lib/rmmount/name.version
* ./name.version
* ./name (warning)
*/
"dso_load: %s/%s.%d not found\n",
return (FALSE);
}
}
dprintf("trying unversioned dso %s (want ver %d)\n",
}
}
/*
* decided on a name, now on to the real work.
*/
return (FALSE);
}
gettext("%s(%ld) warning: dso_load on \"%s\": %s\n"),
}
return (initfunc);
}
void
{
char *s;
*ac = 0;
for (s = buf; *s; s++) {
if (*s == '"') {
if (quote) {
} else {
}
}
if (setnull) {
s[-1] = NULL;
}
if (*s == '\n') {
*s = NULL;
}
*av++ = s;
(*ac)++;
}
break;
}
}
}
/*
* Go through the av strings and remove any quotes.
* This really doesn't fix any extremely general case. It's intended
* to just take care of an argv that looks like:
* "this is a crock"
* and turn it into:
* this is a crock
*/
void
{
int i;
int j;
int k;
char *s;
for (i = 0; i < ac; i++) {
if (*av[i] == '"') {
for (j = 0, k = 0; s[k]; k++) {
if (s[k] == '"') {
continue;
}
av[i][j++] = s[k];
}
free(s);
}
}
}
/*
* swiped from mkdir.c
*/
int
{
int err;
char *slash;
return (0);
}
return (-1);
}
return (-1);
}
*slash++ = '/';
return (err);
}
}
void
{
const char *p;
extern char *sys_errlist[];
char *s;
if (rmm_debug == 0) {
return;
}
/* scan for %m and replace with errno msg */
p = fmt;
while (*p != NULLC) {
if ((*p == '%') && (*(p+1) == 'm')) {
p += 2;
continue;
}
*s++ = *p++;
}
*s = NULLC; /* don't forget the null byte */
/* write off to log file */
}
/*
* Take a path and return the character device. The getfullrawname
* function only works with dsk and rdsk names. I also do the
* irritating floppy name. Unlike getfullrawname, we return
* NULL if we can't find the right stuff.
*/
char *
rawpath(char *n)
{
extern char *getfullrawname(char *);
char *rval;
char *s;
return (rval);
}
}
}
/* ok, so we either have a bad device or a floppy. */
/* the fd# form */
s++; /* point at 'f' */
*s = NULLC;
*s = 'f';
}
/* the diskette form */
s++; /* point at 'd' */
*s = NULLC;
*s = 'd';
}
/* no rawpath found! */
return (strdup(""));
}
/*
* audio_only: return TRUE iff CD-ROM has only audio on it
*
* note: it's better to return FALSE even if we have an audio-only CD-ROM
* than it is to return TRUE incorrectly, since later code can handle the
* latter error case more easily
*
* algorithm:
*
* if no raw path then
* return FALSE
*
* if open of raw path fails then
* return FALSE
*
* if read of TOC HEADER fails then
* try_leadout:
* // try to read just the LEADOUT track
* if read of TOC ENTRY for LEADOUT track fails then
* return FALSE
* if CDROM_DATA_TRACK flag set in cdte_ctrl field then
* return FALSE
* else
* return TRUE
*
* // assume always at least one regular (i.e. non-LEADOUT) track
* for each entry listed in the TOC HEADER do
* if read of TOC ENTRY for this track fails then
* goto try_leadout
* if CDROM_DATA_TRACK flag set in cdte_ctrl field then
* return FALSE
*
* // none of the tracks has the CDROM_DATA_TRACK flag set
* return TRUE
*/
int
{
struct cdrom_tocentry te;
int fd;
int i; /* track index */
return (FALSE);
}
goto dun;
}
/* try to read the TOC Header (may fail on some drive types) */
dprintf("audio_only: CDREADTOCHDR on \"%s\"; %m\n",
aa->aa_rawpath);
/* look at LEADOUT track to see if we have data or music */
/* return FALSE and let caller figure it out */
"audio_only: CDROMREADTOCENTRY on LEADOUT for \"%s\"; %m\n",
aa->aa_rawpath);
goto dun;
}
/*
* a read of the TOC header or a TOC entry failed, but
* the LEADOUT track indicates audio, so
* *guess* "audio only"
*/
}
goto dun;
}
/* assume non-audio-only if start track > end track */
goto dun;
}
/* look through tracks -- any non-music track -> NOT audioonly */
te.cdte_track = (unsigned char)i;
"audio_only: CDREADTOCENTRY for track %d on \"%s\"; %m\n",
i, aa->aa_rawpath);
goto try_leadout;
}
goto dun;
}
}
/* all tracks were non-data => music only */
dun:
dprintf("DEBUG: audio_only() returning %s for \"%s\"\n",
return (res);
}
/*
* This is very nasty business. We must tell share if the file system
* is to be exported read-only. We rewack the option string if someone
* put in 'rw'. The real case we fix here is (for example) a floppy
* that is mounted read-only because it's write protected. It also
* makes the cdrom thing easier too because you don't have to specify
* '-o ro' in your share command, it'll just figure it out for you.
*/
void
{
char *s, *p;
int ac;
int c;
/*
* If he didn't give us any flags...
*/
return;
}
optind = 0; /* reset our getopt state */
switch (c) {
case 'F':
break;
case 'd':
break;
case 'o':
break;
}
}
/*
* Here's where we can really make a mess of things.
* We want to convert any 'rw' strings in the oopt
* into 'ro' strings. The problem is differentiating
* between the 'rw' option and 'rw in a name (like
* a domain name). So, we say 'rw' needs to be
* followed by a : or an = or a null. I hope this
* works or whoever names their machine "cankerworm"
* will be upset with me.
*/
for (p = oopt; *p; p++) {
if (*p == 'r' && *(p+1) == 'w') {
if ((*(p+2) == ':') ||
(*(p+2) == '=') ||
(*(p+2) == NULLC)) {
*(p+1) = 'o';
}
}
}
} else {
oopt = "ro";
}
/* build the new thing */
}
}
}
/* whew! */
free(s);
}
/*
* Convert a shell regular expression to a regex regular
* expression. Thanks to sam @ RMTC.
*/
char *
sh_to_regex(char *s)
{
char vi[MAXNAMELEN];
char *c;
for (c = vi+1; *s; ++c, ++s) {
if (*s == '\\') {
*(c++) = *(s++);
} else if (*s == '*') {
*(c++) = '.';
} else if ((*s == '.') || (*s == '$') || (*s == '^')) {
*(c++) = '\\';
} else if (*s == '?') {
*s = '.';
}
*c = *s;
if (*s == NULLC) {
++c;
break;
}
}
*(c++) = '$'; /* anchar search at end */
*c = NULLC;
}
/*
* if mnttab not open, open it, else reset to its start
*/
static bool_t
{
return (FALSE);
}
} else {
}
return (TRUE);
}
/*
* Given a special device, return the place where it's mounted
* or NULL.
*/
char *
getmntpoint(char *special)
{
if (!reset_mnttab()) {
goto dun;
}
goto found1; /* found an entry */
}
/*
* we didn't find a mnttab entry -- try brute force search looking
* for something like "pathname:N" (for PCFS hard disk mounts)
*/
/* skip non-pcfs entries */
continue;
}
goto found1; /* a match */
}
}
/* nothing found */
goto dun;
/*
* found a mnttab entry -- check for cachefs mount
*/
/*
* if we have a cachefs mount then we need to
* itererate again
* (XXX: is this correct?)
*/
"%s(%ld): cachefs-used mount %s not found in mnttab\n",
goto dun;
}
}
/* success */
dun:
}
return (res);
}
/*
* return the mountpath given a path
*
* normally these will be the same, but for PCFS on non-floppies, we must
* (see mount_pcfs(1M))
*/
void
{
/*
* this should never happen since we should have
* checked for this earlier
*/
dprintf("%s(%ld): VOLUME_MEDIATYPE unspecified\n",
}
}
/*
* XXX: just assume (hope?) that user is using first FDISK
* partition ???
*/
} else {
/* default to return the path passed in */
}
}