ns_files.c revision 8548bf79039833dba8615afdf63258b2cb122121
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <string.h>
#include <ctype.h>
#include <nsswitch.h>
#include <rpcsvc/nfs_prot.h>
#include <thread.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <synch.h>
#include <strings.h>
#include "automount.h"
int linesz);
int linesz);
/*
* Initialize the stack
*/
void
{
/*
* The call is bogus for automountd since the stack is
* is more appropriately initialized in the thread-private
* routines
*/
return;
}
int
char *key;
char *mapname;
{
int nserr;
int syntaxok = 1;
if (iswildcard)
*iswildcard = FALSE;
goto done;
}
goto done;
}
/*
* If the file has its execute bit on then
* assume it's an executable map.
* Execute it and pass the key as an argument.
* Expect to get a map entry on the stdout.
* Ignore the "x" bit on restricted maps.
*/
int rc;
if (trace > 1) {
trace_prt(1,
"\tExecutable map: map=%s key=%s\n",
}
if (rc != 0) {
goto done;
}
goto done;
}
goto done;
}
/*
* It's just a normal map file.
* Search for the entry with the required key.
*/
for (;;) {
goto done;
}
syntaxok = 0;
"leading space in map entry \"%s\" in %s",
}
continue;
break;
if (iswildcard)
*iswildcard = TRUE;
break;
}
if (word[0] == '+') {
if (nserr == __NSW_SUCCESS)
goto done;
continue;
}
/*
* sanity check each map entry key against
* the lookup key as the map is searched.
*/
if (*key == '/') {
if (*word != '/') {
syntaxok = 0;
"bad key \"%s\" in direct map %s\n",
}
} else {
syntaxok = 0;
"bad key \"%s\" in indirect map %s\n",
}
}
}
}
done:
if (fp) {
}
return (nserr);
}
int
char *mapname;
int *error;
int *cache_time;
{
int syntaxok = 1;
int nserr;
if (trace > 1)
goto done;
}
goto done;
}
goto done;
}
/*
* If the file has its execute bit on then
* assume it's an executable map.
* I don't know how to list executable maps, return
* an empty map.
*/
*error = 0;
goto done;
}
/*
* It's just a normal map file.
* List entries one line at a time.
*/
for (;;) {
goto done;
}
syntaxok = 0;
"leading space in map entry \"%s\" in %s",
}
continue;
/*
* Wildcard entries should be ignored and this should be
* the last entry read to corroborate the search through
* files, i.e., search for key until a wildcard is reached.
*/
break;
if (word[0] == '+') {
/*
* Name switch here
*/
/*
* the list may have been updated, therefore
* our 'last' may no longer be valid
*/
continue;
}
goto done;
}
}
done:
if (fp) {
}
/*
* list of entries found
*/
*error = 0;
}
return (nserr);
}
int
char *mastermap;
char *defopts;
{
int done = 0;
return (__NSW_UNAVAIL);
"map %s: line too long (max %d chars)",
continue;
}
dir++;
if (*dir == '\0')
continue;
if (*map)
*map++ = '\0';
if (*dir == '+') {
opts++;
if (*opts != '-')
else
opts++;
/*
* Check for no embedded blanks.
*/
dir++;
} else {
continue;
}
} else {
map++;
if (*map == '\0')
continue;
opts++;
if (*opts) {
*opts++ = '\0';
opts++;
}
if (*opts != '-')
else
opts++;
/*
* Check for no embedded blanks.
*/
} else {
continue;
}
}
done++;
}
}
int
{
int done = 0;
return (__NSW_UNAVAIL);
p1++;
if (*p1 == '\0')
continue;
p2++;
*p2 = '\0';
if (*p1 == '+') {
p1++;
stkptr);
} else {
}
done++;
}
}
/*
* This procedure opens the file and pushes it onto the
* the stack. Only if a file is opened successfully, is
* it pushed onto the stack
*/
static FILE *
{
if (*map != '/') {
/* prepend an "/etc" */
} else
return (NULL);
}
}
return (fp);
}
/*
* reimplemnted to be MT-HOT.
*/
int
int op;
char *name;
{
/*
* the stackptr points to the next empty slot
* for PUSH: put the element and increment stkptr
* for POP: decrement stkptr and free
*/
switch (op) {
case INIT:
return (1);
case ERASE:
if (*ptr) {
if (trace > 1)
}
return (1);
case PUSH:
return (0);
return (0);
}
if (trace > 1)
return (0);
}
(*stkptr)++;
return (1);
case POP:
(*stkptr)--;
else
if (trace > 1)
}
return (1);
default:
return (0);
}
}
#define READ_EXECOUT_ARGS 3
/*
* read_execout(char *key, char **lp, char *fname, char *line, int linesz)
* A simpler, multithreaded implementation of popen(). Used due to
* non multithreaded implementation of popen() (it calls vfork()) and a
* significant bug in execl().
* Returns 0 on OK or -1 on error.
*/
static int
{
int p[2];
int status = 0;
int child_pid;
char *args[READ_EXECOUT_ARGS];
if (pipe(p) < 0) {
return (-1);
}
/* setup args for execv */
return (-1);
}
if (trace > 3)
case -1:
return (-1);
case 0:
/*
* Child
*/
close(p[0]);
close(1);
"read_execout: dup of stdout failed");
_exit(-1);
}
close(p[1]);
_exit(-1);
default:
/*
* Parent
*/
close(p[1]);
/*
* wait for child to complete. Note we read after the
* child exits to guarantee a full pipe.
*/
/* if waitpid fails with EINTR, restart */
status = -1;
break;
}
}
if (status != -1) {
} else {
close(p[0]);
status = -1;
}
} else {
close(p[0]);
}
/* free args */
if (trace > 3)
return (status);
}
}
void
{
char *lp;
int rc;
rc = 0;
}
if (rc != 0) {
/*
* read_execout returned an error, return 0 to the door_client
* to indicate failure
*/
rc = 0;
} else {
}
}
int
int linesz)
{
int ret;
if (trace >= 1)
return (ret);
}