home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 13 / MA_Cover_13.bin / source / c / nfsd / src / config.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-11-30  |  7.2 KB  |  249 lines

  1. /*  Configuration file handling
  2.  
  3.     ©1998 Joseph Walton
  4.  
  5.     This software is distributed under the terms of the GNU General Public
  6.     License; either version 2 of the License, or (at your option) any
  7.     later version.
  8. */
  9.  
  10. /*
  11.     Here we read in a configuration file and parse it. It assumes a single
  12.      global configuration that is never changed, which is hardly ideal
  13.      but sufficient for our purposes.
  14. */
  15.  
  16. /*
  17.     30-Nov-1999 - No longer prints a mask of 255.255.255.255 when summarising.
  18. */
  19.  
  20. #include "nfsd.h"
  21. #include "config.h"
  22. #include "memory.h"
  23. #include "nfs_utils.h"
  24.  
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <dos/dos.h>
  28.  
  29. #include <clib/alib_protos.h>
  30.  
  31. #include <proto/dos.h>
  32. #include <proto/exec.h>
  33. #include <proto/socket.h>
  34.  
  35. /* This is the format of the configuration lines */
  36. #define TEMPLATE "PATH/A,EXPORTAS/A,IP/A,RW=READWRITE/S,UID/K/N,GID/K/N,PERM/K/N,ALL=FORCEALL/S"
  37.  
  38. /* Options are returned here - it must match the format above */
  39. LONG opts[8];
  40.  
  41. /* This is the buffer lines are read into. It should be enough for most
  42.     configurations. */
  43. char buffer[0x100];
  44.  
  45. extern struct List cfg_list;
  46.  
  47. /* Internal prototypes */
  48. struct ConfigEntry *create_configentry(STRPTR path,
  49.     STRPTR exportas, STRPTR exportip, BOOL readwrite,
  50.     LONG *uid, LONG *gid, LONG *perm, BOOL forceall);
  51.  
  52. BOOL process_cfg(STRPTR cfg_name)
  53. {
  54.     BPTR handle;
  55.     BOOL success = TRUE;
  56.  
  57.     int line_number = 0;
  58.  
  59.     /* We're assuming cfg_list is empty -
  60.         we should probably free its contents, to let this be used
  61.         more than once during a run */
  62.  
  63.     if (handle = Open(cfg_name, MODE_OLDFILE)) {
  64.         struct RDArgs *rda = AllocDosObject(DOS_RDARGS, NULL);
  65.  
  66.         if (rda) {
  67.             rda->RDA_Flags = RDAF_NOPROMPT;
  68.             rda->RDA_DAList = NULL;
  69.  
  70.             while (success && FGets(handle, buffer, sizeof(buffer))) {
  71.                 int len;
  72.                 STRPTR cmnt;
  73.  
  74.                 line_number++;
  75.  
  76.                 /* First end the line at any comment char */
  77.                 if (cmnt = strchr(buffer, ';'))
  78.                     *cmnt = 0;
  79.                 if (cmnt = strchr(buffer, '#'))
  80.                     *cmnt = 0;
  81.  
  82.                 len = strlen(buffer);
  83.  
  84.                 /* Does this line still have any characters? */
  85.                 if ( (len > 0)
  86.  
  87.                 /* Are they non-whitespace? */
  88.                     && (strspn(buffer, " \t\n") < len) ) {
  89.                     /* Process that line */
  90.  
  91.                     rda->RDA_Source.CS_Buffer = buffer;
  92.                     rda->RDA_Source.CS_Length = len;
  93.                     rda->RDA_Source.CS_CurChr = 0;
  94.                     rda->RDA_Buffer = NULL;
  95.                     rda->RDA_BufSiz = 0;
  96.  
  97.                     /* Zero everything */
  98.                     opts[0] = 0; opts[1] = 0;
  99.                     opts[2] = 0; opts[3] = 0;
  100.                     opts[4] = 0; opts[5] = 0; /* for UID,GID,permissions */
  101.                     opts[6] = 0;
  102.                     opts[7] = 0;
  103.  
  104.                     if (ReadArgs(TEMPLATE, opts, rda)) {
  105.                         struct ConfigEntry *nce;
  106.  
  107.                         nce = create_configentry((STRPTR) opts[0],
  108.                             (STRPTR) opts[1],
  109.                             (STRPTR) opts[2], (BOOL) opts[3],
  110.                             (LONG *) opts[4], (LONG *) opts[5],
  111.                             (LONG *) opts[6], (BOOL) opts[7]);
  112.  
  113.                         if (nce)
  114.                             AddTail(&cfg_list, (struct Node *)nce);
  115.                         else {
  116.                             printf("Problem with line %d\n", line_number);
  117.                             success = FALSE;
  118.                         }
  119.  
  120.                         FreeArgs(rda);
  121.                     } else {
  122.                         printf("Error at line %d\n", line_number);
  123.                         PrintFault(IoErr(), "Error parsing configuration");
  124.                         success = FALSE;
  125.                     }
  126.                 }
  127.             }
  128.  
  129.             if (IoErr() != 0) {/* Not the normal end of file */
  130.                 PrintFault(IoErr(), "Error reading configuration");
  131.                 success = FALSE;
  132.             }
  133.  
  134.             FreeDosObject(DOS_RDARGS, rda);
  135.         }
  136.         Close(handle);
  137.     } else {
  138.         PrintFault(IoErr(), "Error opening configuration");
  139.         success = FALSE;
  140.     }
  141.  
  142.     return success;
  143. }
  144.  
  145. /* This constructs a new ConfigEntry from the split up strings */
  146. static struct ConfigEntry *create_configentry(STRPTR path,
  147.     STRPTR exportas, STRPTR exportip, BOOL readwrite,
  148.     LONG *uid, LONG *gid, LONG *perm, BOOL forceall)
  149. {
  150.     struct ConfigEntry *nce;
  151.  
  152.     /* Allocate store for this new entry */
  153.     nce = AllocVecPooled(sizeof(struct ConfigEntry));
  154.  
  155.     if (nce) {
  156.         nce->ce_Path = DupString(path);
  157.         nce->ce_ExportAs = DupString(exportas);
  158.     }
  159.  
  160.     /* Yes, I know, memory may be left unfreed by this. But if this
  161.         fails, we quit out and our memory pool is freed anyway. */
  162.  
  163.     if (!(nce && nce->ce_Path && nce->ce_ExportAs)) {
  164.         puts("create_configentry had memory problems");
  165.         return NULL;
  166.     }
  167.  
  168.     nce->ce_ReadWrite = readwrite;
  169.  
  170.     /* Let's actually parse the IP thing */
  171.     if (!strcmp(exportip, "-")) {
  172.         nce->ce_ExportIP = 0;     /* Match anything */
  173.         nce->ce_IPMask = 0;
  174.     } else {
  175.         STRPTR slash = strchr(exportip, '/');
  176.         if (slash)
  177.             *slash++ = 0;
  178.  
  179.         /* We're checking for failure here, so 255.255.255.255
  180.             ceases to be a valid address or mask.
  181.             If this is the mask you wanted, just omit it - it's the default. */
  182.  
  183.         #define FAILED 0xffffffff
  184.  
  185.         if ( FAILED == (nce->ce_ExportIP = inet_addr(exportip))) {
  186.             puts("Unable to parse export IP address");
  187.             return NULL;
  188.         }
  189.  
  190.         if (slash) {
  191.             if (FAILED == (nce->ce_IPMask = inet_addr(slash))) {
  192.                 puts("Unable to parse export IP mask");
  193.                 return NULL;
  194.             }
  195.         } else
  196.             nce->ce_IPMask = 0xffffffff;
  197.  
  198.         #undef FAILED
  199.     }
  200.  
  201.     /* Set the UID/GID/permissions */
  202.     nce->ce_UID = (uid ? *uid : -1);
  203.     nce->ce_GID = (gid ? *gid : -1);
  204.  
  205.     if (perm) {
  206.         /* We get it in 777 format, so we have to convert */
  207.         u_int unix_mode = (*perm / 100) % 10;
  208.         unix_mode <<= 3;
  209.         unix_mode |= (*perm / 10) % 10;
  210.         unix_mode <<= 3;
  211.         unix_mode |= (*perm % 10);
  212.  
  213.         nce->ce_Protection = Amiga_prot(unix_mode);
  214.     } else {
  215.         nce->ce_Protection = -1;
  216.     }
  217.  
  218.     nce->ce_ForceAll = forceall;
  219.  
  220.     /* Now summarise this line to standard output */
  221.     if (verbose) {
  222.         printf("Export: %s exported as %s ",
  223.             nce->ce_Path, nce->ce_ExportAs);
  224.         if (nce->ce_ReadWrite)
  225.             printf("(readwrite) ");
  226.  
  227.         printf("IP=%s, ", Inet_NtoA(nce->ce_ExportIP));
  228.  
  229.         if (nce->ce_IPMask != ~0)
  230.             printf("mask=%s", Inet_NtoA(nce->ce_IPMask));
  231.  
  232.         if (nce->ce_UID != -1)
  233.             printf(" UID=%d", nce->ce_UID);
  234.         if (nce->ce_GID != -1)
  235.             printf(" GID=%d", nce->ce_GID);
  236.         if (nce->ce_Protection != -1)
  237.             printf(" Mode=%03o", NFS_mode(nce->ce_Protection));
  238.  
  239.         if (nce->ce_ForceAll) {
  240.             puts(" FORCEALL");
  241.         } else {
  242.             puts(""); /* Make a newline */
  243.         }
  244.     }
  245.  
  246.     return nce;
  247. }
  248.  
  249.