1 /* 2 * Copyright (c) Bull S.A. 2007 All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it would be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * 12 * Further, this software is distributed without any warranty that it is 13 * free of the rightful claim of any third person regarding infringement 14 * or the like. Any license provided herein, whether implied or 15 * otherwise, applies only to this software file. Patent licenses, if 16 * any, provided herein do not apply to combinations of this program with 17 * other software, or any other product whatsoever. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write the Free Software Foundation, Inc., 21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 22 * 23 * History: 24 * Created by: Cyril Lacabanne (Cyril.Lacabanne (at) bull.net) 25 * 26 */ 27 28 #include <stdio.h> 29 #include <pthread.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 39 //Standard define 40 #define VERSNUM 1 41 #define PROGSYSERROR 10 42 #define PROGAUTHERROR 100 43 #define CALCTHREADPROC 1000 44 45 static void exm_proc(); 46 int progNum; 47 int run_mode; 48 49 struct datas { 50 double a; 51 double b; 52 double c; 53 } argument; 54 55 //XDR Struct function 56 bool_t xdr_datas(XDR * pt_xdr, struct datas *pt) 57 { 58 return (xdr_double(pt_xdr, &(pt->a)) && 59 xdr_double(pt_xdr, &(pt->b)) && xdr_double(pt_xdr, &(pt->c))); 60 } 61 62 void *server_thread_process(void *arg) 63 { 64 //Server process in a thread 65 int err = 0; 66 int i = (long)arg; 67 68 if (run_mode == 1) { 69 printf("Server #%d launched\n", i); 70 printf("Server Nb : %d\n", progNum + i); 71 } 72 73 svc_unreg(progNum + atoi(arg), VERSNUM); 74 75 err = svc_create(exm_proc, progNum + atoi(arg), VERSNUM, "VISIBLE"); 76 77 if (err == 0) { 78 fprintf(stderr, "Cannot create service.\n"); 79 exit(1); 80 } 81 82 svc_run(); 83 84 fprintf(stderr, "svc_run() returned. ERROR has occurred.\n"); 85 svc_unreg(progNum, VERSNUM); 86 87 pthread_exit(0); 88 } 89 90 //****************************************// 91 //*** Main Function ***// 92 //****************************************// 93 int main(int argn, char *argc[]) 94 { 95 //Server parameter is : argc[1] : Server Program Number 96 // argc[2] : Number of threads 97 // others arguments depend on server program 98 run_mode = 0; 99 int threadNb = atoi(argc[2]); 100 long i; 101 //Thread declaration 102 pthread_t *pThreadArray; 103 void *ret; 104 105 progNum = atoi(argc[1]); 106 107 pThreadArray = malloc(threadNb * sizeof(pthread_t)); 108 for (i = 0; i < threadNb; i++) { 109 if (run_mode == 1) 110 fprintf(stderr, "Try to create Thread Server %ld\n", i); 111 if (pthread_create 112 (&pThreadArray[i], NULL, server_thread_process, (void*)i) < 0) { 113 fprintf(stderr, "pthread_create error for thread 1\n"); 114 exit(1); 115 } 116 } 117 118 //Clean threads 119 for (i = 0; i < threadNb; i++) { 120 (void)pthread_join(pThreadArray[i], &ret); 121 } 122 123 return 1; 124 } 125 126 //****************************************// 127 //*** Remotes Procedures ***// 128 //****************************************// 129 char *calcProc(struct datas *dt) 130 { 131 //Makes a + b * c from structure dt and returns double 132 //printf("*** In calcProc ***\n"); 133 static double result = 0; 134 result = dt->a + (dt->b * dt->c); 135 //printf("Received : %lf, %lf, %lf\n", dt->a, dt->b, dt->c); 136 return (char *)&result; 137 } 138 139 //****************************************// 140 //*** Dispatch Function ***// 141 //****************************************// 142 static void exm_proc(struct svc_req *rqstp, SVCXPRT * transp) 143 { 144 //printf("* in Dispatch Func.\n"); 145 146 char *result; 147 xdrproc_t xdr_argument; 148 xdrproc_t xdr_result; 149 int *(*proc) (struct datas *); 150 151 switch (rqstp->rq_proc) { 152 case CALCTHREADPROC: 153 { 154 //printf("** in PROCPONG dispatch Func.\n"); 155 xdr_argument = (xdrproc_t) xdr_datas; 156 xdr_result = (xdrproc_t) xdr_double; 157 proc = (int *(*)(struct datas *))calcProc; 158 break; 159 } 160 case PROGSYSERROR: 161 { 162 //Simulate an error 163 svcerr_systemerr(transp); 164 return; 165 } 166 case PROGAUTHERROR: 167 { 168 //Simulate an authentification error 169 svcerr_weakauth(transp); 170 return; 171 } 172 default: 173 { 174 //Proc is unavaible 175 svcerr_noproc(transp); 176 return; 177 } 178 } 179 memset((int *)&argument, (int)0, sizeof(argument)); 180 if (svc_getargs(transp, xdr_argument, (char *)&argument) == FALSE) { 181 svcerr_decode(transp); 182 return; 183 } 184 185 result = (char *)(*proc) ((struct datas *)&argument); 186 187 if ((result != NULL) 188 && (svc_sendreply(transp, xdr_result, result) == FALSE)) { 189 svcerr_systemerr(transp); 190 } 191 if (svc_freeargs(transp, xdr_argument, (char *)&argument) == FALSE) { 192 (void)fprintf(stderr, "unable to free arguments\n"); 193 exit(1); 194 } 195 } 196