home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
lan
/
soss.arj
/
SRC
/
EXPORTS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-22
|
7KB
|
294 lines
/*
* exports.c --
* Parses and keeps a list of exported filesystems on the PC.
* It should be called by the netd routines. Refer to exports(5)
* for a detailed discussion of the export file format.
*
* Author:
* See-Mong Tan
* Modified by:
* Rich Braun @ Kronos, 2/15/91
*/
#include "common.h"
/* tokens returned by the lexer */
typedef enum {
DRIVE_TOKEN, PATH_TOKEN, CLNT_TOKEN, END_TOKEN, ERROR_TOKEN
} Exps_Tokens;
/* value of symbol */
static union {
char *str; /* string ptr to path/client names */
int drive; /* which drive */
} lexval;
#define MAXSTRLEN ((unsigned) 80)
/*
* Exps_Tokens lex(FILE *fp) --
* The exports file lexical analyzer. Reads the opened file *fp
* and returns tokens of type Exps_Tokens
*/
Exps_Tokens lex(fp)
FILE *fp;
{
char c, c2;
char *s;
for(;;) {
switch(c = getc(fp)) {
case ' ':
case '\t':
case '\n':
break; /* do nothing */
case '#': /* a comment line */
while((c = getc(fp)) != '\n' && c != EOF);
if (c == EOF)
return END_TOKEN; /* end of file */
else
break; /* can continue */
case '\\': /* a pathname */
ungetc(c, fp);
lexval.str = (char *) malloc(MAXSTRLEN);
(void) fscanf(fp, "%s", lexval.str);
return PATH_TOKEN;
default:
if (isalpha(c)) {
if ((c2 = getc(fp)) == ':') {
/* drive specification */
lexval.drive = (int)
(c - (islower(c) ? 'a' : 'A')) + 1;
return DRIVE_TOKEN;
}
/* it's a host name */
ungetc(c2, fp); /* back into stream */
ungetc(c, fp); /* push both chars */
lexval.str = (char *) malloc(MAXSTRLEN);
(void) fscanf(fp, "%s", lexval.str);
return CLNT_TOKEN;
}
if (c == EOF)
return END_TOKEN;
return ERROR_TOKEN;
}
}
}
/* the export list exists here */
Exports *explist;
/*
* bool_t exps_parse() --
* Parses the export file EXPORTS and creates the export list
* Returns TRUE if successful and FALSE if an error occurred.
*/
bool_t exps_parse()
{
FILE *fp, *fopen();
Exps_Tokens tok;
int lastfsys; /* last filesystem # */
if ((fp = fopen(EXPORTS, "r")) == NULL) {
(void) fprintf(stderr, "exps: cannot open exports file\n");
return FALSE;
}
tok = lex(fp); /* read start token */
for(lastfsys = 1; ;lastfsys++) {
Exports *exp_entry; /* single export entry */
Exports *temp;
int i;
if (tok == END_TOKEN) {
DBGPRT0 (mountd, "exps: finished parsing exps file");
(void) fclose(fp);
exps_showexps();
return TRUE;
}
if (tok != DRIVE_TOKEN) {
(void) fprintf(stderr, "exps: line %d expected DRIVE_TOKEN\n", lastfsys);
(void) fclose(fp);
return FALSE;
}
exp_entry = (Exports *) malloc(sizeof(Exports));
exp_entry->drive = lexval.drive;
if ((tok = lex(fp)) != PATH_TOKEN) {
(void) fprintf(stderr, "exps: line %d expected PATH_TOKEN\n", lastfsys-1);
(void) fclose(fp);
return FALSE;
}
exp_entry->pn = lexval.str;
tok = lex(fp);
for(i = 0;tok == CLNT_TOKEN && i < MAXEXPSCLNTS;
tok = lex(fp), i++) {
exp_entry->clnts[i] = lexval.str;
exp_entry->clnts_ip[i] = sock_gethostbyname(lexval.str);
DBGPRT2 (mountd, "clnt %s addr %ld", lexval.str,
exp_entry->clnts_ip[i]);
if (exp_entry->clnts_ip[i] == -1) {
(void) fprintf(stderr,
"exps: line %d invalid client: %s\n",
lastfsys-1, lexval.str);
(void) fclose(fp);
return FALSE;
}
}
if (i > MAXEXPSCLNTS) {
(void) fprintf(stderr, "exps: too many clients\n");
(void) fclose(fp);
return FALSE;
}
exp_entry->clnts[i] = (char *) NULL;
exp_entry->clnts_ip[i] = (long) 0;
exp_entry->fsys = lastfsys; /* assign file system id */
/* finished reading one entry - now add to rest of list */
temp = explist;
explist = exp_entry;
exp_entry->next = temp;
}
}
/*
* void exps_showexps() --
* Prints out the export list.
*/
void exps_showexps()
{
Exports *exptr;
(void) printf("\n\tCurrent exported filesystems are :\n\n");
for(exptr = explist; exptr != NULL; exptr = exptr->next) {
int i;
(void) printf(" %c:", exptr->drive + (int) 'a' - 1);
(void) printf("%s\n", exptr->pn);
for(i = 0; i < MAXEXPSCLNTS && exptr->clnts[i] != NULL; i++)
(void) printf("\tclnt #%d is %s\n",
i+1, exptr->clnts[i]);
}
putchar('\n');
}
/*
* struct exports *exps_get() --
* Gets a pointer to the exports list
*/
struct exports *exps_get()
{
static struct exports *expout = NULL;
Exports *ptrin;
struct exports *prev, *ptrout;
if (expout == NULL) {
ptrin = explist;
prev = NULL;
while (ptrin != NULL) {
ptrout = (struct exports *) malloc (sizeof (struct exports));
if (prev == NULL)
expout = ptrout;
else
prev->ex_next = ptrout;
prev = ptrout;
ptrout->ex_name = malloc (MAXPATHNAMELEN);
/* Translate pathname into Unix format */
pathd2u (ptrin->drive, ptrin->pn, ptrout->ex_name);
ptrout->ex_dev = ptrin->drive;
ptrout->ex_groups = NULL;
ptrout->ex_rootmap = 0;
ptrout->ex_flags = 0;
ptrout->ex_next = NULL;
ptrin = ptrin->next;
}
}
return expout;
}
/*
* Exports *exps_isexport(char *path);
* Returns the export pointer to the entry in the export list
* where the directory path is found. Returns NULL if no such entry.
*/
Exports *exps_isexport(path)
char *path;
{
Exports *ptr;
char fullpath[MAXPATHNAMELEN];
for (ptr = explist; ptr != NULL; ) {
if (!strcmp (path, pathd2u (ptr->drive, ptr->pn, fullpath)))
return ptr;
ptr = ptr->next;
}
return NULL;
}
/*
* bool_t exps_isclnt(char *path, long addr) --
* Check if client is in export list for path. If there are no clients
* then the filesystem is exported to the world and it returns TRUE.
*/
bool_t exps_isclnt(path, addr)
char *path;
long addr;
{
Exports *exp;
int i = 0;
char ipbuf [30];
if ((exp = exps_isexport(path)) == NULL)
return FALSE;
sprintf (ipbuf, "%ld.%ld.%ld.%ld (%ld)",
0xFF & addr,
0xFF & (addr >> 8),
0xFF & (addr >> 16),
addr >> 24, addr);
DBGPRT1 (mountd, "isclnt: ipaddr = %s", ipbuf);
while(exp->clnts_ip[i] != 0 && i < MAXEXPSCLNTS)
if (exp->clnts_ip[i] == addr)
return TRUE;
else
i++;
if (i == 0)
return TRUE;
else
return FALSE;
}
/*
* char *pathd2u(int drive, char *path, char *str) --
* Converts a DOS path name into Unix format, e.g.
* C:\FOO\BAR --> /c/foo/bar
*/
char *pathd2u (drive, path, str)
int drive;
char *path;
char *str;
{
int i;
sprintf (str, "/%c%s", 'a'-1+drive, path);
for (i=2;;i++) {
if (str[i] == '\\')
str[i] = '/';
else if (str[i] == '\0') {
if (str[i-1] == '/')
str[i-1] = '\0';
break;
}
}
return (str);
}