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 <sys/socket.h> 31 #include <errno.h> 32 #include <netinet/in.h> 33 #include "lapi/rpc.h" 34 35 //Standard define 36 #define VERSNUM 1 37 #define PROGSYSERROR 10 38 #define PROGAUTHERROR 100 39 #define CALCTHREADPROC 1000 40 41 static void exm_proc(); 42 int progNum; 43 int run_mode; 44 45 struct datas { 46 double a; 47 double b; 48 double c; 49 } argument; 50 51 //XDR Struct function 52 bool_t xdr_datas(XDR * pt_xdr, struct datas *pt) 53 { 54 return (xdr_double(pt_xdr, &(pt->a)) && 55 xdr_double(pt_xdr, &(pt->b)) && xdr_double(pt_xdr, &(pt->c))); 56 } 57 58 void *server_thread_process(void *arg) 59 { 60 //Server process in a thread 61 int err = 0; 62 int i = (long)arg; 63 64 if (run_mode == 1) { 65 printf("Server #%d launched\n", i); 66 printf("Server Nb : %d\n", progNum + i); 67 } 68 69 svc_unreg(progNum + atoi(arg), VERSNUM); 70 71 err = svc_create(exm_proc, progNum + atoi(arg), VERSNUM, "VISIBLE"); 72 73 if (err == 0) { 74 fprintf(stderr, "Cannot create service.\n"); 75 exit(1); 76 } 77 78 svc_run(); 79 80 fprintf(stderr, "svc_run() returned. ERROR has occurred.\n"); 81 svc_unreg(progNum, VERSNUM); 82 83 pthread_exit(0); 84 } 85 86 //****************************************// 87 //*** Main Function ***// 88 //****************************************// 89 int main(int argn, char *argc[]) 90 { 91 //Server parameter is : argc[1] : Server Program Number 92 // argc[2] : Number of threads 93 // others arguments depend on server program 94 run_mode = 0; 95 int threadNb = atoi(argc[2]); 96 long i; 97 //Thread declaration 98 pthread_t *pThreadArray; 99 void *ret; 100 101 progNum = atoi(argc[1]); 102 103 pThreadArray = malloc(threadNb * sizeof(pthread_t)); 104 for (i = 0; i < threadNb; i++) { 105 if (run_mode == 1) 106 fprintf(stderr, "Try to create Thread Server %ld\n", i); 107 if (pthread_create 108 (&pThreadArray[i], NULL, server_thread_process, (void*)i) < 0) { 109 fprintf(stderr, "pthread_create error for thread 1\n"); 110 exit(1); 111 } 112 } 113 114 //Clean threads 115 for (i = 0; i < threadNb; i++) { 116 (void)pthread_join(pThreadArray[i], &ret); 117 } 118 119 return 1; 120 } 121 122 //****************************************// 123 //*** Remotes Procedures ***// 124 //****************************************// 125 char *calcProc(struct datas *dt) 126 { 127 //Makes a + b * c from structure dt and returns double 128 //printf("*** In calcProc ***\n"); 129 static double result = 0; 130 result = dt->a + (dt->b * dt->c); 131 //printf("Received : %lf, %lf, %lf\n", dt->a, dt->b, dt->c); 132 return (char *)&result; 133 } 134 135 //****************************************// 136 //*** Dispatch Function ***// 137 //****************************************// 138 static void exm_proc(struct svc_req *rqstp, SVCXPRT * transp) 139 { 140 //printf("* in Dispatch Func.\n"); 141 142 char *result; 143 xdrproc_t xdr_argument; 144 xdrproc_t xdr_result; 145 int *(*proc) (struct datas *); 146 147 switch (rqstp->rq_proc) { 148 case CALCTHREADPROC: 149 { 150 //printf("** in PROCPONG dispatch Func.\n"); 151 xdr_argument = (xdrproc_t) xdr_datas; 152 xdr_result = (xdrproc_t) xdr_double; 153 proc = (int *(*)(struct datas *))calcProc; 154 break; 155 } 156 case PROGSYSERROR: 157 { 158 //Simulate an error 159 svcerr_systemerr(transp); 160 return; 161 } 162 case PROGAUTHERROR: 163 { 164 //Simulate an authentification error 165 svcerr_weakauth(transp); 166 return; 167 } 168 default: 169 { 170 //Proc is unavaible 171 svcerr_noproc(transp); 172 return; 173 } 174 } 175 memset((int *)&argument, (int)0, sizeof(argument)); 176 if (svc_getargs(transp, xdr_argument, (char *)&argument) == FALSE) { 177 svcerr_decode(transp); 178 return; 179 } 180 181 result = (char *)(*proc) ((struct datas *)&argument); 182 183 if ((result != NULL) 184 && (svc_sendreply(transp, xdr_result, result) == FALSE)) { 185 svcerr_systemerr(transp); 186 } 187 if (svc_freeargs(transp, xdr_argument, (char *)&argument) == FALSE) { 188 (void)fprintf(stderr, "unable to free arguments\n"); 189 exit(1); 190 } 191 } 192