home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / utils / sossntr3 / src / exports.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  7.2 KB  |  309 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. #include "ntfsauth.h"
  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.  
  39.     for(;;) {
  40.         switch(c = getc(fp)) {
  41.  
  42.         case ' ':
  43.         case '\t':
  44.         case '\n':
  45.             break;      /* do nothing */
  46.     case '#':       /* a comment line */
  47.             while((c = getc(fp)) != '\n' && c != EOF);
  48.             if (c == EOF)
  49.                 return END_TOKEN;   /* end of file */
  50.             else
  51.                 break;          /* can continue */
  52.  
  53.         case '\\':      /* a pathname */
  54.             ungetc(c, fp);
  55.             lexval.str = (char *) malloc(MAXSTRLEN);
  56.             (void) fscanf(fp, "%s", lexval.str);
  57.             return PATH_TOKEN;
  58.  
  59.         default:
  60.             if (isalnum(c)) {       // rruther 931014 */
  61.                 if ((c2 = getc(fp)) == ':') {
  62.                     /* drive specification */
  63.                     lexval.drive = (int)
  64.                       (c - (islower(c) ? 'a' : 'A')) + 1;
  65.                     return DRIVE_TOKEN;
  66.                 }
  67.                 /* it's a host name */
  68.                 ungetc(c2, fp);     /* back into stream */
  69.                 ungetc(c, fp);      /* push both chars */
  70.                 lexval.str = (char *) malloc(MAXSTRLEN);
  71.                 (void) fscanf(fp, "%s", lexval.str);
  72.                 return CLNT_TOKEN;
  73.             }
  74.             if (c == EOF)
  75.                 return END_TOKEN;
  76.  
  77.             return ERROR_TOKEN;
  78.         }
  79.     }
  80. }
  81.  
  82. /* the export list exists here */
  83. Exports *explist;
  84.         
  85. /*
  86.  *  bool_t exps_parse() --
  87.  *      Parses the export file EXPORTS and creates the export list
  88.  *      Returns TRUE if successful and FALSE if an error occurred.
  89.  */
  90. bool_t exps_parse()
  91. {
  92.     FILE *fp, *fopen();
  93.     struct hostent *Host;
  94.     Exps_Tokens tok;
  95.     int lastfsys;       /* last filesystem # */
  96.     unsigned long addr;
  97.  
  98.     if ((fp = fopen(EXPORTS, "r")) == NULL) {
  99.         (void) fprintf(stderr, "exps: cannot open exports file\n");
  100.         return FALSE;
  101.     }
  102.     tok = lex(fp);      /* read start token */
  103.     for(lastfsys = 1; ;lastfsys++) {
  104.         Exports *exp_entry; /* single export entry */
  105.         Exports *temp;
  106.         int i;
  107.         
  108.         if (tok == END_TOKEN) {
  109.                 DBGPRT0 (mountd, "exps: finished parsing exps file");
  110.             (void) fclose(fp);
  111.             exps_showexps();
  112.             return TRUE;
  113.         }
  114.         if (tok != DRIVE_TOKEN) {
  115.             (void) fprintf(stderr, "exps: line %d expected DRIVE_TOKEN\n", lastfsys);
  116.             (void) fclose(fp);
  117.             return FALSE;
  118.         }
  119.         exp_entry = (Exports *) malloc(sizeof(Exports));
  120.         exp_entry->drive = lexval.drive;
  121. #ifdef NTFS                
  122.         {
  123.             char    drive[3];
  124.  
  125.             sprintf( drive, "%c:", lexval.drive + 'a' - 1);
  126.             NtfsInitDrive( drive);
  127.         }
  128. #endif
  129.         if ((tok = lex(fp)) != PATH_TOKEN) {
  130.             (void) fprintf(stderr, "exps: line %d expected PATH_TOKEN\n", lastfsys-1);
  131.             (void) fclose(fp);
  132.             return FALSE;
  133.         }
  134.         exp_entry->pn = lexval.str;
  135.  
  136.         tok = lex(fp);
  137.         for(i = 0;tok == CLNT_TOKEN && i < MAXEXPSCLNTS;
  138.             tok = lex(fp), i++) {
  139.             exp_entry->clnts[i] = lexval.str;
  140.  
  141.             if( Host = gethostbyname( lexval.str ))
  142.                 memcpy( &addr, Host->h_addr,Host->h_length);
  143.             else    
  144.  
  145.                 addr = inet_addr(lexval.str);
  146.  
  147.             exp_entry->clnts_ip[i] = addr;
  148.             DBGPRT2 (mountd, "clnt %s addr %ld", lexval.str, 
  149.                  exp_entry->clnts_ip[i]);
  150.             if (exp_entry->clnts_ip[i] == -1) {
  151.                 (void) fprintf(stderr,
  152.                      "exps: line %d invalid client: %s\n",
  153.                            lastfsys-1, lexval.str);
  154.                 (void) fclose(fp);
  155.                 return FALSE;
  156.             }
  157.         }
  158.         if (i > MAXEXPSCLNTS) {
  159.             (void) fprintf(stderr, "exps: too many clients\n");
  160.             (void) fclose(fp);
  161.             return FALSE;
  162.         }       
  163.         exp_entry->clnts[i] = (char *) NULL;
  164.         exp_entry->clnts_ip[i] = (long) 0;
  165.         exp_entry->fsys = lastfsys; /* assign file system id */
  166.     
  167.         /* finished reading one entry - now add to rest of list */
  168.         temp = explist;
  169.         explist = exp_entry;
  170.         exp_entry->next = temp;
  171.     }
  172. }
  173.  
  174. /*
  175.  *  void exps_showexps() --
  176.  *      Prints out the export list.
  177.  */
  178. void exps_showexps()
  179. {
  180.     Exports *exptr;
  181.  
  182.     (void) printf("\n\tCurrent exported filesystems are :\n\n");
  183.     for(exptr = explist; exptr != NULL; exptr = exptr->next) {
  184.         int i;
  185.  
  186.         (void) printf("   %c:", exptr->drive + (int) 'a' - 1);
  187.         (void) printf("%s\n", exptr->pn);
  188.         for(i = 0; i < MAXEXPSCLNTS && exptr->clnts[i] != NULL; i++)
  189.             (void) printf("\tclnt #%d is %s\n", 
  190.                     i+1, exptr->clnts[i]);
  191.     }
  192.     putchar('\n');
  193. }
  194.  
  195. /*
  196.  *  struct exports *exps_get() --
  197.  *      Gets a pointer to the exports list
  198.  */
  199. struct exports *exps_get()
  200. {
  201.     static struct exports *expout = NULL;
  202.     Exports *ptrin;
  203.     struct exports *prev, *ptrout;
  204.  
  205.     if (expout == NULL) {
  206.     ptrin = explist;
  207.         prev = NULL;
  208.  
  209.     while (ptrin != NULL) {
  210.         ptrout = (struct exports *) malloc (sizeof (struct exports));
  211.         if (prev == NULL)
  212.           expout = ptrout;
  213.         else
  214.           prev->ex_next = ptrout;
  215.         prev = ptrout;
  216.         ptrout->ex_name = malloc (MAXPATHNAMELEN);
  217.  
  218.         /* Translate pathname into Unix format */
  219.         pathd2u (ptrin->drive, ptrin->pn, ptrout->ex_name);
  220.         ptrout->ex_dev = ptrin->drive;
  221.         ptrout->ex_groups = NULL;
  222.         ptrout->ex_rootmap = 0;
  223.         ptrout->ex_flags = 0;
  224.         ptrout->ex_next = NULL;
  225.         ptrin = ptrin->next;
  226.     }
  227.     }
  228.     return expout;
  229. }
  230.  
  231. /*
  232.  *  Exports *exps_isexport(char *path);
  233.  *      Returns the export pointer to the entry in the export list
  234.  *  where the directory path is found.  Returns NULL if no such entry.
  235.  */
  236. Exports *exps_isexport(path)
  237.     char *path;
  238. {
  239.     Exports *ptr;
  240.     char fullpath[MAXPATHNAMELEN];
  241.  
  242.     for (ptr = explist; ptr != NULL; ) {
  243.     if (!strcmp (path, pathd2u (ptr->drive, ptr->pn, fullpath)))
  244.       return ptr;
  245.     ptr = ptr->next;
  246.     }
  247.     return NULL;
  248. }
  249.  
  250. /*
  251.  *  bool_t exps_isclnt(char *path, long addr) --
  252.  *      Check if client is in export list for path.  If there are no clients
  253.  *      then the filesystem is exported to the world and it returns TRUE.
  254.  */
  255. bool_t exps_isclnt(path, addr)
  256.     char *path;
  257.     unsigned long addr;
  258. {
  259.     Exports *exp;
  260.     int i = 0;
  261.     char ipbuf [30];
  262.  
  263.     if ((exp = exps_isexport(path)) == NULL)
  264.         return FALSE;
  265.  
  266.     sprintf (ipbuf, "%ld.%ld.%ld.%ld (%ld)",
  267.          0xFF & addr,
  268.          0xFF & (addr >> 8),
  269.          0xFF & (addr >> 16),
  270.          addr >> 24, addr);
  271.  
  272.     DBGPRT1 (mountd, "isclnt: ipaddr = %s", ipbuf);
  273.  
  274.     while(exp->clnts_ip[i] != 0 && i < MAXEXPSCLNTS) 
  275.         if ( (unsigned)(exp->clnts_ip[i]) == addr)
  276.             return TRUE;
  277.         else
  278.             i++;
  279.     if (i == 0)
  280.         return TRUE;
  281.     else
  282.         return FALSE;
  283. }
  284.  
  285. /*
  286.  *  char *pathd2u(int drive, char *path, char *str) --
  287.  *      Converts a DOS path name into Unix format, e.g.
  288.  *     C:\FOO\BAR     -->  /c/foo/bar
  289.  */
  290. char *pathd2u (drive, path, str)
  291.      int drive;
  292.      char *path;
  293.      char *str;
  294. {
  295.     int i;
  296.  
  297.     sprintf (str, "/%c%s", 'a'-1+drive, path);
  298.     for (i=2;;i++) {
  299.     if (str[i] == '\\')
  300.       str[i] = '/';
  301.     else if (str[i] == '\0') {
  302.         if (str[i-1] == '/')
  303.           str[i-1] = '\0';
  304.         break;
  305.     }
  306.     }
  307.     return (str);
  308. }
  309.