]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - utils/rquotad/rquota_svc.c
Add option to specify directory to search for credentials cache files
[nfs-utils.git] / utils / rquotad / rquota_svc.c
index f55c192762bf3aab0975994a05896f2f691e94cc..0785551472aa6e1f3f8109b814b321347c709e44 100644 (file)
  *          as published by the Free Software Foundation; either version
  *          2 of the License, or (at your option) any later version.
  */
-#include "config.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #ifdef HAVE_TCP_WRAPPER
 #include "tcpwrapper.h"
 #endif
 
 #include <unistd.h>
+#include <errno.h>
 #include <rpc/rpc.h>
 #include "rquota.h"
 #include <stdlib.h>
@@ -35,6 +39,9 @@
 #include <netinet/in.h>
 #include <syslog.h>
 #include <signal.h>
+#include <getopt.h>
+#include <rpcmisc.h>
+#include <nfslib.h>
 
 #ifdef __STDC__
 #define SIG_PF void(*)(int)
@@ -49,6 +56,14 @@ extern getquota_rslt *rquotaproc_getquota_2(ext_getquota_args *argp,
 extern getquota_rslt *rquotaproc_getactivequota_2(ext_getquota_args *argp,
                                                  struct svc_req *rqstp);
 
+static struct option longopts[] =
+{
+        { "help", 0, 0, 'h' },
+        { "version", 0, 0, 'v' },
+        { "port", 1, 0, 'p' },
+        { NULL, 0, 0, 0 }
+};
+
 /*
  * Global authentication credentials.
  */
@@ -204,19 +219,77 @@ static void rquotaprog_2(struct svc_req *rqstp, register SVCXPRT *transp)
    return;
 }
 
+static void
+usage(const char *prog, int n)
+{
+  fprintf(stderr, "Usage: %s [-p|--port port] [-h|-?|--help] [-v|--version]\n", prog);
+  exit(n);
+}
+
+static void
+killer (int sig)
+{
+   (void) pmap_unset(RQUOTAPROG, RQUOTAVERS);
+   (void) pmap_unset(RQUOTAPROG, EXT_RQUOTAVERS);
+   syslog(LOG_ERR, "caught signal %d, un-registering and exiting.", sig);
+}
+
 int main(int argc, char **argv)
 {
    register SVCXPRT *transp;
+   int c;
+   int port = 0;
+   struct sigaction sa;
 
    (void) pmap_unset(RQUOTAPROG, RQUOTAVERS);
    (void) pmap_unset(RQUOTAPROG, EXT_RQUOTAVERS);
 
    openlog("rquota", LOG_PID, LOG_DAEMON);
 
+   while ((c = getopt_long(argc, argv, "hp:v", longopts, NULL)) != EOF) {
+     switch (c) {
+     case '?':
+     case 'h':
+       usage(argv[0], 0);
+       break;
+     case 'p':
+       port = atoi(optarg);
+       if (port < 1 || port > 65535) {
+        fprintf(stderr, "%s: bad port number: %s\n",
+                argv[0], optarg);
+        usage(argv[0], 1);
+       }
+       break;
+     case 'v':
+       printf("rquotad %s\n", VERSION);
+       exit(0);
+     default:
+       usage(argv[0], 1);
+     }
+   }
+
+   if (chdir(NFS_STATEDIR)) {
+     fprintf(stderr, "%s: chdir(%s) failed: %s\n",
+            argv [0], NFS_STATEDIR, strerror(errno));
+
+     exit(1);
+   }
+
    /* WARNING: the following works on Linux and SysV, but not BSD! */
-   signal(SIGCHLD, SIG_IGN);
+   sa.sa_handler = SIG_IGN;
+   sa.sa_flags = 0;
+   sigemptyset(&sa.sa_mask);
+   sigaction(SIGCHLD, &sa, NULL);
+
+   sa.sa_handler = killer;
+   sigaction(SIGHUP, &sa, NULL);
+   sigaction(SIGINT, &sa, NULL);
+   sigaction(SIGTERM, &sa, NULL);
 
-   transp = svcudp_create(RPC_ANYSOCK);
+   if (port)
+     transp = svcudp_create(makesock(port, IPPROTO_UDP));
+   else
+     transp = svcudp_create(svcudp_socket (RQUOTAPROG, 1));
    if (transp == NULL) {
       syslog(LOG_ERR, "cannot create udp service.");
       exit(1);