1/* 2* Copyright (c) Bull S.A. 2007 All Rights Reserved. 3* Copyright (c) 2014 Oracle and/or its affiliates. All Rights Reserved. 4* 5* This program is free software; you can redistribute it and/or modify it 6* under the terms of version 2 of the GNU General Public License as 7* published by the Free Software Foundation. 8* 9* This program is distributed in the hope that it would be useful, but 10* WITHOUT ANY WARRANTY; without even the implied warranty of 11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12* 13* Further, this software is distributed without any warranty that it is 14* free of the rightful claim of any third person regarding infringement 15* or the like. Any license provided herein, whether implied or 16* otherwise, applies only to this software file. Patent licenses, if 17* any, provided herein do not apply to combinations of this program with 18* other software, or any other product whatsoever. 19* 20* You should have received a copy of the GNU General Public License along 21* with this program; if not, write the Free Software Foundation, Inc., 22* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 23* 24* History: 25* Created by: Cyril Lacabanne (Cyril.Lacabanne@bull.net) 26* 27*/ 28 29#include <stdio.h> 30#include <tirpc/netconfig.h> 31#include <sys/socket.h> 32#include <tirpc/rpc/rpc.h> 33#include <tirpc/rpc/types.h> 34#include <tirpc/rpc/xdr.h> 35#include <tirpc/rpc/svc.h> 36#include <errno.h> 37#include <netinet/in.h> 38#include <unistd.h> 39#include "librpc-tirpc.h" 40 41#define VERSNUM 1 42#define PROCSIMPLEPING 1 43 44struct server_def_t { 45 SVCXPRT *transp; 46 struct netconfig *nconf; 47 char netid[4]; 48 int domain; 49 int type; 50 int sock; 51 SVCXPRT *(*svc_func)(const int, const u_int, const u_int); 52}; 53 54static struct server_def_t server_defs[] = { 55 { NULL, NULL, "tcp", AF_INET, SOCK_STREAM, -1, svc_vc_create }, 56 { NULL, NULL, "udp", AF_INET, SOCK_DGRAM, -1, svc_dg_create }, 57}; 58 59static int server_instances = sizeof(server_defs) / sizeof(*server_defs); 60 61static void exm_proc(struct svc_req *rqstp, SVCXPRT *transp); 62 63int main(int argn, char *argc[]) 64{ 65 int progNum = atoi(argc[1]); 66 int i; 67 struct server_def_t *this; 68 69 svc_unreg(progNum, VERSNUM); 70 71 for (i = 0; i < server_instances; i++) { 72 this = &(server_defs[i]); 73 74 this->nconf = getnetconfigent(this->netid); 75 if (this->nconf == NULL) { 76 fprintf(stderr, "Cannot get a netconfig entry for %s", 77 this->netid); 78 goto cleanup; 79 } 80 81 this->sock = bound_socket(this->domain, this->type); 82 if (this->sock < 0) { 83 perror("bound_socket() failed"); 84 goto cleanup; 85 } 86 87 if (this->type == SOCK_STREAM) { 88 if (listen(this->sock, 10) < 0) { 89 perror("listen() failed"); 90 goto cleanup; 91 } 92 } 93 94 this->transp = this->svc_func(this->sock, 1024, 1024); 95 if (this->transp == NULL) { 96 fprintf(stderr, "Cannot create service.\n"); 97 goto cleanup; 98 } 99 100 if (!svc_reg(this->transp, progNum, VERSNUM, 101 exm_proc, this->nconf)) { 102 fprintf(stderr, "svc_reg failed!!\n"); 103 goto cleanup; 104 } 105 } 106 107 108 svc_run(); 109 110 fprintf(stderr, "svc_run() returned. ERROR has occurred.\n"); 111 112cleanup: 113 svc_unreg(progNum, VERSNUM); 114 115 for (i = 0; i < server_instances; i++) { 116 this = &(server_defs[i]); 117 118 if (this->transp != NULL) 119 svc_destroy(this->transp); 120 121 if (this->sock >= 0) 122 close(this->sock); 123 } 124 125 return 1; 126} 127 128/* Remote Procedures */ 129char *simplePing(char *in) 130{ 131 static int result = 0; 132 result = *in; 133 return (char *)&result; 134} 135 136/* Dispatch Function */ 137static void exm_proc(struct svc_req *rqstp, SVCXPRT *transp) 138{ 139 union { 140 int varIn; 141 } argument; 142 143 char *result; 144 xdrproc_t xdr_argument = NULL; 145 xdrproc_t xdr_result = NULL; 146 char *(*proc) (char *); 147 148 switch (rqstp->rq_proc) { 149 case PROCSIMPLEPING: 150 { 151 xdr_argument = (xdrproc_t) xdr_int; 152 xdr_result = (xdrproc_t) xdr_int; 153 proc = (char *(*)(char *))simplePing; 154 break; 155 } 156 } 157 memset((char *)&argument, (int)0, sizeof(argument)); 158 if (svc_getargs(transp, xdr_argument, (char *)&argument) == FALSE) { 159 svcerr_decode(transp); 160 return; 161 } 162 163 result = (char *)(*proc) ((char *)&argument); 164 165 if ((result != NULL) 166 && (svc_sendreply(transp, xdr_result, result) == FALSE)) { 167 svcerr_systemerr(transp); 168 } 169 if (svc_freeargs(transp, xdr_argument, (char *)&argument) == FALSE) { 170 (void)fprintf(stderr, "unable to free arguments\n"); 171 exit(1); 172 } 173} 174