home *** CD-ROM | disk | FTP | other *** search
- /* nfsd - an Amiga NFS daemon
-
- ©1998, 1999 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.
- */
-
- /*
- This is the main routine - it opens libraries, calls allocation routines,
- checks versions, and installs RPC dispatchers.
- */
-
- /*
- 28-Sep-1999 - Uses ReadArgs. Allows the user to set the GMT offset.
- 30-Nov-1999 - Major changes to support new RPC code.
- */
-
- #include "nfsd.h"
- #include "nfs.h"
- #include "mount.h"
- #include "pcnfsd.h"
-
- #include "service_nfsd.h" // service()
-
- #include "rpc_register.h"
- #include "handle_list.h"
- #include "memory.h"
- #include "config.h"
- #include "timerdev.h"
- #include "nfs_utils.h"
-
- #include <stdio.h>
- #include <signal.h>
- #include <string.h> /* strcmp */
- #include <sys/socket.h>
- #include <netinet/in.h>
-
- #include <dos/dosextens.h> /* struct Process */
-
- #include <proto/socket.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
-
- /* Seems some SDKs don't follow Amiga conventions... */
- #ifndef SOCKETNAME
- #define SOCKETNAME "bsdsocket.library"
- #endif
-
- /* Are we verbose? If so, print copious output */
- BOOL verbose = FALSE;
-
- /* This changes how authentication behaves */
- extern BOOL allow_root; /* in auth.c */
-
- /* The offset of local time from GMT */
- extern LONG amigaGMTOffset; /* in nfs_util.c */
-
- /* I'm relying on DiceC to have opened these */
- extern struct Library *SysBase;
- extern struct DosLibrary *DOSBase;
-
- struct Library *SocketBase = NULL;
-
- /* This is a rather busy main, but what the hey... */
- int main(int argc, char *argv[])
- {
- /* Declarations first */
-
- /* Keep track of whether or not we need to deregister these */
- BOOL registered_nfsd = FALSE,
- registered_mount = FALSE,
- registered_pcnfsd = FALSE;
-
- /* Our future point of presence in IP space */
- int sock = -1;
-
- /* We need these to inhibit graphical requesters */
- struct Process *process;
- APTR vptr;
-
- /* Just a little beta-blaring... */
- puts("nfsd beta, ©1998, 1999 Joseph Walton <ver@etla.org>\n"
- "This version compiled " __DATE__ ".\n"
- "nfsd is free software, distributed under the terms of the GNU General Public License.\n"
- "It comes with ABSOLUTELY NO WARRANTY.");
- /* Moved from pre-pre- to just plain pre-...
- And now we're a plain beta... */
-
- /* We'll handle CTRL-C's ourselves */
- signal(SIGINT, SIG_IGN);
-
- /* We need some v39 exec.library functions - sorry */
- if (SysBase->lib_Version < 39) {
- puts("nfsd requires v39 exec.library");
- goto finish;
- }
-
- /* We do need some v39 dos.library functions - sorry */
- if (DOSBase->dl_lib.lib_Version < 39) {
- puts("nfsd requires v39 dos.library");
- goto finish;
- }
-
- /* We manually open timer.device, as SAS/C won't do it for us */
- if (!td_opentimer()) {
- puts("Unable to open " TIMERNAME);
- goto finish;
- }
-
- /* Oh, I might need some socket handling routines... */
- SocketBase = OpenLibrary(SOCKETNAME, 4);
-
- if (!SocketBase) {
- puts("Unable to open " SOCKETNAME " v4");
- goto finish;
- }
-
- /* Need to get memory to work with */
- if (!init_memory()) {
- puts("Unable to allocate handle list");
- goto finish;
- }
-
- /* Check the command line */
- {
- STRPTR template = "GMTOFFSET/K/N,ALLOWROOT/S,VERBOSE/S";
- LONG opts[3] = {0, 0, 0};
- struct RDArgs *argsptr;
-
- if (NULL == (argsptr = ReadArgs(template, opts, NULL))) {
- PrintFault(IoErr(), NULL);
- goto finish;
- }
-
- /* Now act on those arguments */
- if (opts[0]) {
- amigaGMTOffset = *(LONG *)opts[0];
- }
-
- if (opts[1]) {
- allow_root = TRUE;
- puts("Allowing remote accesses by root");
- }
-
- if (opts[2]) {
- verbose = TRUE;
- puts("Verbose mode enabled");
- }
-
- FreeArgs(argsptr);
- }
-
- /* And parse our configuration */
- if (!process_cfg("nfsd.config")) {
- puts("Unable to get configuration");
- goto finish;
- }
-
- /* Now fetch the inode base */
- persistent_inode_fetch();
- /* Any failure is dealt with internally, by starting afresh at 1 */
-
- /* We need a socket to communicate with */
- sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (sock < 0) {
- printSocketError("Could not create a socket");
- goto finish;
- }
-
- /* nfsd needs to bind to a well-known port */
- {
- struct sockaddr_in addr = {
- sizeof(struct sockaddr_in),
- AF_INET,
- htons(NFS_PORT),
- {htonl(INADDR_ANY)}
- };
-
- /* Can I do this without a macro? */
- #define A(x) #x
-
- if (-1 == bind(sock, &addr, sizeof(addr))) {
- printSocketError("Unable to bind to port " A(NFS_PORT));
- goto finish;
- }
-
- #undef A
- }
-
- /*
- We don't try to get rid of any old mapping at the moment.
- It might well fail confusingly, and gazumping services like
- that is hardly polite.
- */
-
- /* Establish mappings. We bind everything to the same port. */
- if (pmap_set(sock, NFS_PROGRAM, NFS_VERSION, NFS_PORT)) {
- registered_nfsd = TRUE;
- } else {
- puts("Unable to register (NFS_PROGRAM, NFS_VERSION, NFS_PORT).");
- goto finish;
- }
-
- if (pmap_set(sock, MOUNT_PROGRAM, MOUNT_VERSION, NFS_PORT)) {
- registered_mount = TRUE;
- } else {
- puts("Unable to register (MOUNT_PROGRAM, MOUNT_VERSION, NFS_PORT).");
- goto finish;
- }
-
- if (pmap_set(sock, PCNFSD_PROGRAM, PCNFSD_VERSION, NFS_PORT)) {
- registered_pcnfsd = TRUE;
- } else {
- puts("Unable to register (PCNFSD_PROGRAM, PCNFSD_VERSION, NFS_PORT).");
- goto finish;
- }
-
- /* We don't want any requesters popped up */
- process = (struct Process *)FindTask(NULL);
- vptr = process->pr_WindowPtr;
- process->pr_WindowPtr = (APTR)-1L;
-
- puts("Serving.");
- service(sock); /* This where we jump to the Real Work */
-
- puts("Finished.");
-
- /* Now return things to normal */
- process->pr_WindowPtr = vptr;
-
- if (!persistent_inode_store())
- puts("Failed to store current inode");
-
- /* Now, free any resources and exit */
- finish:
- td_closetimer();
-
- if (SocketBase) {
- if (sock >= 0) {
- /* If any of these time out we should probably skip the
- rest, but we currently don't export that information
- from the registration process */
- if (registered_pcnfsd)
- if (!pmap_unset(sock, PCNFSD_PROGRAM, PCNFSD_VERSION))
- puts("Unable to deregister the PCNFSD service.");
- if (registered_nfsd)
- if (!pmap_unset(sock, NFS_PROGRAM, NFS_VERSION))
- puts("Unable to deregister the NFS service.");
- if (registered_mount)
- if (!pmap_unset(sock, MOUNT_PROGRAM, MOUNT_VERSION))
- puts("Unable to deregister the mount service.");
- CloseSocket(sock);
- }
- CloseLibrary(SocketBase);
- }
- free_memory();
- return RETURN_OK;
- }
-
-