home *** CD-ROM | disk | FTP | other *** search
- /* Configuration file handling
-
- ©1998 Joseph Walton
-
- This software is distributed under the terms of the GNU General Public
- License; either version 2 of the License, or (at your option) any
- later version.
- */
-
- /*
- Here we read in a configuration file and parse it. It assumes a single
- global configuration that is never changed, which is hardly ideal
- but sufficient for our purposes.
- */
-
- /*
- 30-Nov-1999 - No longer prints a mask of 255.255.255.255 when summarising.
- */
-
- #include "nfsd.h"
- #include "config.h"
- #include "memory.h"
- #include "nfs_utils.h"
-
- #include <stdio.h>
- #include <string.h>
- #include <dos/dos.h>
-
- #include <clib/alib_protos.h>
-
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <proto/socket.h>
-
- /* This is the format of the configuration lines */
- #define TEMPLATE "PATH/A,EXPORTAS/A,IP/A,RW=READWRITE/S,UID/K/N,GID/K/N,PERM/K/N,ALL=FORCEALL/S"
-
- /* Options are returned here - it must match the format above */
- LONG opts[8];
-
- /* This is the buffer lines are read into. It should be enough for most
- configurations. */
- char buffer[0x100];
-
- extern struct List cfg_list;
-
- /* Internal prototypes */
- struct ConfigEntry *create_configentry(STRPTR path,
- STRPTR exportas, STRPTR exportip, BOOL readwrite,
- LONG *uid, LONG *gid, LONG *perm, BOOL forceall);
-
- BOOL process_cfg(STRPTR cfg_name)
- {
- BPTR handle;
- BOOL success = TRUE;
-
- int line_number = 0;
-
- /* We're assuming cfg_list is empty -
- we should probably free its contents, to let this be used
- more than once during a run */
-
- if (handle = Open(cfg_name, MODE_OLDFILE)) {
- struct RDArgs *rda = AllocDosObject(DOS_RDARGS, NULL);
-
- if (rda) {
- rda->RDA_Flags = RDAF_NOPROMPT;
- rda->RDA_DAList = NULL;
-
- while (success && FGets(handle, buffer, sizeof(buffer))) {
- int len;
- STRPTR cmnt;
-
- line_number++;
-
- /* First end the line at any comment char */
- if (cmnt = strchr(buffer, ';'))
- *cmnt = 0;
- if (cmnt = strchr(buffer, '#'))
- *cmnt = 0;
-
- len = strlen(buffer);
-
- /* Does this line still have any characters? */
- if ( (len > 0)
-
- /* Are they non-whitespace? */
- && (strspn(buffer, " \t\n") < len) ) {
- /* Process that line */
-
- rda->RDA_Source.CS_Buffer = buffer;
- rda->RDA_Source.CS_Length = len;
- rda->RDA_Source.CS_CurChr = 0;
- rda->RDA_Buffer = NULL;
- rda->RDA_BufSiz = 0;
-
- /* Zero everything */
- opts[0] = 0; opts[1] = 0;
- opts[2] = 0; opts[3] = 0;
- opts[4] = 0; opts[5] = 0; /* for UID,GID,permissions */
- opts[6] = 0;
- opts[7] = 0;
-
- if (ReadArgs(TEMPLATE, opts, rda)) {
- struct ConfigEntry *nce;
-
- nce = create_configentry((STRPTR) opts[0],
- (STRPTR) opts[1],
- (STRPTR) opts[2], (BOOL) opts[3],
- (LONG *) opts[4], (LONG *) opts[5],
- (LONG *) opts[6], (BOOL) opts[7]);
-
- if (nce)
- AddTail(&cfg_list, (struct Node *)nce);
- else {
- printf("Problem with line %d\n", line_number);
- success = FALSE;
- }
-
- FreeArgs(rda);
- } else {
- printf("Error at line %d\n", line_number);
- PrintFault(IoErr(), "Error parsing configuration");
- success = FALSE;
- }
- }
- }
-
- if (IoErr() != 0) {/* Not the normal end of file */
- PrintFault(IoErr(), "Error reading configuration");
- success = FALSE;
- }
-
- FreeDosObject(DOS_RDARGS, rda);
- }
- Close(handle);
- } else {
- PrintFault(IoErr(), "Error opening configuration");
- success = FALSE;
- }
-
- return success;
- }
-
- /* This constructs a new ConfigEntry from the split up strings */
- static struct ConfigEntry *create_configentry(STRPTR path,
- STRPTR exportas, STRPTR exportip, BOOL readwrite,
- LONG *uid, LONG *gid, LONG *perm, BOOL forceall)
- {
- struct ConfigEntry *nce;
-
- /* Allocate store for this new entry */
- nce = AllocVecPooled(sizeof(struct ConfigEntry));
-
- if (nce) {
- nce->ce_Path = DupString(path);
- nce->ce_ExportAs = DupString(exportas);
- }
-
- /* Yes, I know, memory may be left unfreed by this. But if this
- fails, we quit out and our memory pool is freed anyway. */
-
- if (!(nce && nce->ce_Path && nce->ce_ExportAs)) {
- puts("create_configentry had memory problems");
- return NULL;
- }
-
- nce->ce_ReadWrite = readwrite;
-
- /* Let's actually parse the IP thing */
- if (!strcmp(exportip, "-")) {
- nce->ce_ExportIP = 0; /* Match anything */
- nce->ce_IPMask = 0;
- } else {
- STRPTR slash = strchr(exportip, '/');
- if (slash)
- *slash++ = 0;
-
- /* We're checking for failure here, so 255.255.255.255
- ceases to be a valid address or mask.
- If this is the mask you wanted, just omit it - it's the default. */
-
- #define FAILED 0xffffffff
-
- if ( FAILED == (nce->ce_ExportIP = inet_addr(exportip))) {
- puts("Unable to parse export IP address");
- return NULL;
- }
-
- if (slash) {
- if (FAILED == (nce->ce_IPMask = inet_addr(slash))) {
- puts("Unable to parse export IP mask");
- return NULL;
- }
- } else
- nce->ce_IPMask = 0xffffffff;
-
- #undef FAILED
- }
-
- /* Set the UID/GID/permissions */
- nce->ce_UID = (uid ? *uid : -1);
- nce->ce_GID = (gid ? *gid : -1);
-
- if (perm) {
- /* We get it in 777 format, so we have to convert */
- u_int unix_mode = (*perm / 100) % 10;
- unix_mode <<= 3;
- unix_mode |= (*perm / 10) % 10;
- unix_mode <<= 3;
- unix_mode |= (*perm % 10);
-
- nce->ce_Protection = Amiga_prot(unix_mode);
- } else {
- nce->ce_Protection = -1;
- }
-
- nce->ce_ForceAll = forceall;
-
- /* Now summarise this line to standard output */
- if (verbose) {
- printf("Export: %s exported as %s ",
- nce->ce_Path, nce->ce_ExportAs);
- if (nce->ce_ReadWrite)
- printf("(readwrite) ");
-
- printf("IP=%s, ", Inet_NtoA(nce->ce_ExportIP));
-
- if (nce->ce_IPMask != ~0)
- printf("mask=%s", Inet_NtoA(nce->ce_IPMask));
-
- if (nce->ce_UID != -1)
- printf(" UID=%d", nce->ce_UID);
- if (nce->ce_GID != -1)
- printf(" GID=%d", nce->ce_GID);
- if (nce->ce_Protection != -1)
- printf(" Mode=%03o", NFS_mode(nce->ce_Protection));
-
- if (nce->ce_ForceAll) {
- puts(" FORCEALL");
- } else {
- puts(""); /* Make a newline */
- }
- }
-
- return nce;
- }
-
-