home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / lan / soss.arj / SRC / EXPORTS.C < prev    next >
C/C++ Source or Header  |  1991-02-22  |  7KB  |  294 lines

  1. /*
  2.  *  exports.c --
  3.  *      Parses and keeps a list of exported filesystems on the PC.
  4.  *      It should be called by the netd routines.  Refer to exports(5)
  5.  *      for a detailed discussion of the export file format.
  6.  *
  7.  *  Author:
  8.  *      See-Mong Tan
  9.  *  Modified by:
  10.  *    Rich Braun @ Kronos, 2/15/91
  11.  */
  12. #include "common.h"
  13.  
  14.  
  15.  
  16. /* tokens returned by the lexer */
  17. typedef enum {
  18.     DRIVE_TOKEN, PATH_TOKEN, CLNT_TOKEN, END_TOKEN, ERROR_TOKEN
  19. } Exps_Tokens;
  20.  
  21. /* value of symbol */
  22. static union {
  23.     char *str;        /* string ptr to path/client names */
  24.     int drive;        /* which drive */
  25. } lexval;
  26.  
  27. #define MAXSTRLEN ((unsigned) 80)
  28.  
  29. /*
  30.  *  Exps_Tokens lex(FILE *fp) --
  31.  *      The exports file lexical analyzer.  Reads the opened file *fp
  32.  *      and returns tokens of type Exps_Tokens
  33.  */
  34. Exps_Tokens lex(fp)
  35.     FILE *fp;
  36. {
  37.     char c, c2;
  38.     char *s;
  39.  
  40.     for(;;) {
  41.         switch(c = getc(fp)) {
  42.  
  43.         case ' ':
  44.         case '\t':
  45.         case '\n':
  46.             break;        /* do nothing */
  47.     case '#':        /* a comment line */
  48.             while((c = getc(fp)) != '\n' && c != EOF);
  49.             if (c == EOF)
  50.                 return END_TOKEN;    /* end of file */
  51.             else
  52.                 break;            /* can continue */
  53.  
  54.         case '\\':        /* a pathname */
  55.             ungetc(c, fp);
  56.             lexval.str = (char *) malloc(MAXSTRLEN);
  57.             (void) fscanf(fp, "%s", lexval.str);
  58.             return PATH_TOKEN;
  59.  
  60.         default:
  61.             if (isalpha(c)) {
  62.                 if ((c2 = getc(fp)) == ':') {
  63.                     /* drive specification */
  64.                     lexval.drive = (int)
  65.                       (c - (islower(c) ? 'a' : 'A')) + 1;
  66.                     return DRIVE_TOKEN;
  67.                 }
  68.                 /* it's a host name */
  69.                 ungetc(c2, fp);        /* back into stream */
  70.                 ungetc(c, fp);        /* push both chars */
  71.                 lexval.str = (char *) malloc(MAXSTRLEN);
  72.                 (void) fscanf(fp, "%s", lexval.str);
  73.                 return CLNT_TOKEN;
  74.             }
  75.             if (c == EOF)
  76.                 return END_TOKEN;
  77.  
  78.             return ERROR_TOKEN;
  79.         }
  80.     }
  81. }
  82.  
  83. /* the export list exists here */
  84. Exports *explist;
  85.         
  86. /*
  87.  *  bool_t exps_parse() --
  88.  *      Parses the export file EXPORTS and creates the export list
  89.  *      Returns TRUE if successful and FALSE if an error occurred.
  90.  */
  91. bool_t exps_parse()
  92. {
  93.     FILE *fp, *fopen();
  94.     Exps_Tokens tok;
  95.     int lastfsys;        /* last filesystem # */
  96.  
  97.     if ((fp = fopen(EXPORTS, "r")) == NULL) {
  98.         (void) fprintf(stderr, "exps: cannot open exports file\n");
  99.         return FALSE;
  100.     }
  101.     tok = lex(fp);        /* read start token */
  102.     for(lastfsys = 1; ;lastfsys++) {
  103.         Exports *exp_entry;    /* single export entry */
  104.         Exports *temp;
  105.         int i;
  106.         
  107.         if (tok == END_TOKEN) {
  108.                 DBGPRT0 (mountd, "exps: finished parsing exps file");
  109.             (void) fclose(fp);
  110.             exps_showexps();
  111.             return TRUE;
  112.         }
  113.         if (tok != DRIVE_TOKEN) {
  114.             (void) fprintf(stderr, "exps: line %d expected DRIVE_TOKEN\n", lastfsys);
  115.             (void) fclose(fp);
  116.             return FALSE;
  117.         }
  118.         exp_entry = (Exports *) malloc(sizeof(Exports));
  119.         exp_entry->drive = lexval.drive;
  120.         
  121.         if ((tok = lex(fp)) != PATH_TOKEN) {
  122.             (void) fprintf(stderr, "exps: line %d expected PATH_TOKEN\n", lastfsys-1);
  123.             (void) fclose(fp);
  124.             return FALSE;
  125.          }
  126.         exp_entry->pn = lexval.str;
  127.  
  128.         tok = lex(fp);
  129.         for(i = 0;tok == CLNT_TOKEN && i < MAXEXPSCLNTS;
  130.             tok = lex(fp), i++) {
  131.             exp_entry->clnts[i] = lexval.str;
  132.             exp_entry->clnts_ip[i] = sock_gethostbyname(lexval.str);
  133.             DBGPRT2 (mountd, "clnt %s addr %ld", lexval.str, 
  134.                  exp_entry->clnts_ip[i]);
  135.             if (exp_entry->clnts_ip[i] == -1) {
  136.                 (void) fprintf(stderr,
  137.                      "exps: line %d invalid client: %s\n",
  138.                            lastfsys-1, lexval.str);
  139.                 (void) fclose(fp);
  140.                 return FALSE;
  141.             }
  142.         }
  143.         if (i > MAXEXPSCLNTS) {
  144.             (void) fprintf(stderr, "exps: too many clients\n");
  145.             (void) fclose(fp);
  146.             return FALSE;
  147.         }        
  148.         exp_entry->clnts[i] = (char *) NULL;
  149.         exp_entry->clnts_ip[i] = (long) 0;
  150.         exp_entry->fsys = lastfsys;    /* assign file system id */
  151.     
  152.         /* finished reading one entry - now add to rest of list */
  153.         temp = explist;
  154.         explist = exp_entry;
  155.         exp_entry->next = temp;
  156.     }
  157. }
  158.  
  159. /*
  160.  *  void exps_showexps() --
  161.  *      Prints out the export list.
  162.  */
  163. void exps_showexps()
  164. {
  165.     Exports *exptr;
  166.  
  167.     (void) printf("\n\tCurrent exported filesystems are :\n\n");
  168.     for(exptr = explist; exptr != NULL; exptr = exptr->next) {
  169.         int i;
  170.  
  171.         (void) printf("   %c:", exptr->drive + (int) 'a' - 1);
  172.         (void) printf("%s\n", exptr->pn);
  173.         for(i = 0; i < MAXEXPSCLNTS && exptr->clnts[i] != NULL; i++)
  174.             (void) printf("\tclnt #%d is %s\n", 
  175.                     i+1, exptr->clnts[i]);
  176.     }
  177.     putchar('\n');
  178. }
  179.  
  180. /*
  181.  *  struct exports *exps_get() --
  182.  *      Gets a pointer to the exports list
  183.  */
  184. struct exports *exps_get()
  185. {
  186.     static struct exports *expout = NULL;
  187.     Exports *ptrin;
  188.     struct exports *prev, *ptrout;
  189.  
  190.     if (expout == NULL) {
  191.     ptrin = explist;
  192.         prev = NULL;
  193.  
  194.     while (ptrin != NULL) {
  195.         ptrout = (struct exports *) malloc (sizeof (struct exports));
  196.         if (prev == NULL)
  197.           expout = ptrout;
  198.         else
  199.           prev->ex_next = ptrout;
  200.         prev = ptrout;
  201.         ptrout->ex_name = malloc (MAXPATHNAMELEN);
  202.  
  203.         /* Translate pathname into Unix format */
  204.         pathd2u (ptrin->drive, ptrin->pn, ptrout->ex_name);
  205.         ptrout->ex_dev = ptrin->drive;
  206.         ptrout->ex_groups = NULL;
  207.         ptrout->ex_rootmap = 0;
  208.         ptrout->ex_flags = 0;
  209.         ptrout->ex_next = NULL;
  210.         ptrin = ptrin->next;
  211.     }
  212.     }
  213.     return expout;
  214. }
  215.  
  216. /*
  217.  *  Exports *exps_isexport(char *path);
  218.  *      Returns the export pointer to the entry in the export list
  219.  *    where the directory path is found.  Returns NULL if no such entry.
  220.  */
  221. Exports *exps_isexport(path)
  222.     char *path;
  223. {
  224.     Exports *ptr;
  225.     char fullpath[MAXPATHNAMELEN];
  226.  
  227.     for (ptr = explist; ptr != NULL; ) {
  228.     if (!strcmp (path, pathd2u (ptr->drive, ptr->pn, fullpath)))
  229.       return ptr;
  230.     ptr = ptr->next;
  231.     }
  232.     return NULL;
  233. }
  234.  
  235. /*
  236.  *  bool_t exps_isclnt(char *path, long addr) --
  237.  *      Check if client is in export list for path.  If there are no clients
  238.  *      then the filesystem is exported to the world and it returns TRUE.
  239.  */
  240. bool_t exps_isclnt(path, addr)
  241.     char *path;
  242.     long addr;
  243. {
  244.     Exports *exp;
  245.     int i = 0;
  246.     char ipbuf [30];
  247.  
  248.     if ((exp = exps_isexport(path)) == NULL)
  249.         return FALSE;
  250.  
  251.     sprintf (ipbuf, "%ld.%ld.%ld.%ld (%ld)",
  252.          0xFF & addr,
  253.          0xFF & (addr >> 8),
  254.          0xFF & (addr >> 16),
  255.          addr >> 24, addr);
  256.  
  257.     DBGPRT1 (mountd, "isclnt: ipaddr = %s", ipbuf);
  258.  
  259.     while(exp->clnts_ip[i] != 0 && i < MAXEXPSCLNTS) 
  260.         if (exp->clnts_ip[i] == addr)
  261.             return TRUE;
  262.         else
  263.             i++;
  264.     if (i == 0)
  265.         return TRUE;
  266.     else
  267.         return FALSE;
  268. }
  269.  
  270. /*
  271.  *  char *pathd2u(int drive, char *path, char *str) --
  272.  *      Converts a DOS path name into Unix format, e.g.
  273.  *       C:\FOO\BAR     -->  /c/foo/bar
  274.  */
  275. char *pathd2u (drive, path, str)
  276.      int drive;
  277.      char *path;
  278.      char *str;
  279. {
  280.     int i;
  281.  
  282.     sprintf (str, "/%c%s", 'a'-1+drive, path);
  283.     for (i=2;;i++) {
  284.     if (str[i] == '\\')
  285.       str[i] = '/';
  286.     else if (str[i] == '\0') {
  287.         if (str[i-1] == '/')
  288.           str[i-1] = '\0';
  289.         break;
  290.     }
  291.     }
  292.     return (str);
  293. }
  294.