* 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>
#include <sys/socket.h>
#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)
#endif
-extern getquota_rslt *rquotaproc_getquota_1(getquota_args *argp,
- struct svc_req *rqstp);
-extern getquota_rslt *rquotaproc_getactivequota_1(getquota_args *argp,
- struct svc_req *rqstp);
-extern getquota_rslt *rquotaproc_getquota_2(ext_getquota_args *argp,
- struct svc_req *rqstp);
-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.
xdrproc_t xdr_argument, xdr_result;
char *(*local)(char *, struct svc_req *);
+#ifdef HAVE_TCP_WRAPPER
+ /* remote host authorization check */
+ if (!check_default("rquotad", svc_getcaller(transp),
+ rqstp->rq_proc, RQUOTAPROG)) {
+ svcerr_auth (transp, AUTH_FAILED);
+ return;
+ }
+#endif
+
/*
* Don't bother authentication for NULLPROC.
*/
case RQUOTAPROC_GETQUOTA:
xdr_argument = (xdrproc_t) xdr_getquota_args;
xdr_result = (xdrproc_t) xdr_getquota_rslt;
- local = (char *(*)(char *, struct svc_req *)) rquotaproc_getquota_1;
+ local = (char *(*)(char *, struct svc_req *)) rquotaproc_getquota_1_svc;
break;
case RQUOTAPROC_GETACTIVEQUOTA:
xdr_argument = (xdrproc_t) xdr_getquota_args;
xdr_result = (xdrproc_t) xdr_getquota_rslt;
- local = (char *(*)(char *, struct svc_req *)) rquotaproc_getactivequota_1;
+ local = (char *(*)(char *, struct svc_req *)) rquotaproc_getactivequota_1_svc;
break;
default:
xdrproc_t xdr_argument, xdr_result;
char *(*local)(char *, struct svc_req *);
+#ifdef HAVE_TCP_WRAPPER
+ /* remote host authorization check */
+ if (!check_default("rquotad", svc_getcaller(transp),
+ rqstp->rq_proc, RQUOTAPROG)) {
+ svcerr_auth (transp, AUTH_FAILED);
+ return;
+ }
+#endif
+
/*
* Don't bother authentication for NULLPROC.
*/
case RQUOTAPROC_GETQUOTA:
xdr_argument = (xdrproc_t) xdr_ext_getquota_args;
xdr_result = (xdrproc_t) xdr_getquota_rslt;
- local = (char *(*)(char *, struct svc_req *)) rquotaproc_getquota_2;
+ local = (char *(*)(char *, struct svc_req *)) rquotaproc_getquota_2_svc;
break;
case RQUOTAPROC_GETACTIVEQUOTA:
xdr_argument = (xdrproc_t) xdr_ext_getquota_args;
xdr_result = (xdrproc_t) xdr_getquota_rslt;
- local = (char *(*)(char *, struct svc_req *)) rquotaproc_getactivequota_2;
+ local = (char *(*)(char *, struct svc_req *)) rquotaproc_getactivequota_2_svc;
break;
default:
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);
- transp = svcudp_create(RPC_ANYSOCK);
+ 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! */
+ 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);
+
+ 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);