home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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);
- }
-