1 | /************************************************************************* |
---|
2 | * |
---|
3 | * |
---|
4 | * MP version 1.1.2: Multi Protocol |
---|
5 | * Kent State University, Kent, OH |
---|
6 | * Authors: S. Gray, N. Kajler, P. Wang |
---|
7 | * (C) 1993, 1994, 1995, 1996, 1997 All Rights Reserved |
---|
8 | * |
---|
9 | * NOTICE |
---|
10 | * |
---|
11 | * Permission to use, copy, modify, and distribute this software and |
---|
12 | * its documentation for non-commercial purposes and without fee is |
---|
13 | * hereby granted provided that the above copyright notice appear in all |
---|
14 | * copies and that both the copyright notice and this permission notice |
---|
15 | * appear in supporting documentation. |
---|
16 | * |
---|
17 | * Neither Kent State University nor the Authors make any representations |
---|
18 | * about the suitability of this software for any purpose. The MP Library |
---|
19 | * is distributed in the hope that it will be useful, but is provided "as |
---|
20 | * is" and without any warranty of any kind and without even the implied |
---|
21 | * warranty of merchantability or fitness for a particular purpose. |
---|
22 | * |
---|
23 | * |
---|
24 | * IMPLEMENTATION FILE: MP_Env.c |
---|
25 | * |
---|
26 | * Routines to initialize and destroy the MP environment. The |
---|
27 | * environment includes the host name of the machine, the log |
---|
28 | * file name, the buffer pool, etc. The call to MP_InitializeEnv() |
---|
29 | * must occur before any attempt is made to open a link. |
---|
30 | * MP_ReleaseEnv() is one of the last things that should be done |
---|
31 | * before exiting the program. |
---|
32 | * |
---|
33 | * Change Log: |
---|
34 | * September 11, 1995 SG - Reorganization of files. Cleaned up |
---|
35 | * header files and relocated source to |
---|
36 | * its own file. |
---|
37 | * September 18, 1995 SG - Added MP_AllocateEnv(). |
---|
38 | * Changed MP_InitializeEnv() to take env |
---|
39 | * as an argument. If env is NULL, we start |
---|
40 | * from scratch, else we assume MP_AllocateEnv() |
---|
41 | * was called previously. |
---|
42 | * 10/16/95 OB - open always a new log file, i.e. do not |
---|
43 | * reuse an existing one |
---|
44 | * 11/25/96 SG - Added defines/declarations/functions to |
---|
45 | * support negotiation of word ordering. |
---|
46 | * 1/29/96 sgray - added MP_GetEnvOption(). Note that since we return |
---|
47 | * MP_Failure for an illegal option, we must never |
---|
48 | * allow a legal option to be the value MP_Failure (0). |
---|
49 | * 3/3/96 SG - Added routines MP_AddEnvTranspDevice(), |
---|
50 | * mp_free_env_transp_list(), and IMP_GetTranspByName(), |
---|
51 | * to support adding devices to an environment dynamically. |
---|
52 | * Also made necessary changes to the other environment fncs. |
---|
53 | * 4/23/96 SG - Added code to support different arbitrary precision |
---|
54 | * packages. Modified MP_AllocateEnv() and added |
---|
55 | * MP_SetEnvBigIntFormat(). |
---|
56 | ***************************************************************************/ |
---|
57 | |
---|
58 | #ifndef lint |
---|
59 | static char vcid[] = "@(#) $Id: MP_Env.c,v 1.6 2001-11-05 17:09:58 Singular Exp $"; |
---|
60 | #endif /*lint */ |
---|
61 | |
---|
62 | #include <values.h> /* to figure out if we use IEEE or not */ |
---|
63 | #include "MP.h" |
---|
64 | |
---|
65 | #include <string.h> |
---|
66 | #include <sys/time.h> |
---|
67 | #include <time.h> |
---|
68 | |
---|
69 | #ifndef __WIN32__ |
---|
70 | #include <unistd.h> |
---|
71 | #include <stdlib.h> |
---|
72 | #ifdef __cplusplus |
---|
73 | extern "C" |
---|
74 | { |
---|
75 | #endif |
---|
76 | #include <sys/stat.h> |
---|
77 | #ifdef __cplusplus |
---|
78 | } |
---|
79 | #endif |
---|
80 | #endif /* __WIN32__ */ |
---|
81 | |
---|
82 | #ifdef __WIN32__ |
---|
83 | #define MP_LOGFILE "mplog.100" |
---|
84 | #define MP_LOGFILE_NAME "mplog." |
---|
85 | #else /* not __WIN32__ */ |
---|
86 | #define MP_LOGFILE "/tmp/mplog.100" |
---|
87 | #define MP_LOGFILE_NAME "/tmp/mplog." |
---|
88 | #endif /* not __WIN32__ */ |
---|
89 | |
---|
90 | /* These are the "builtin" devices we support */ |
---|
91 | EXTERN MP_TranspOps_t tcp_ops; |
---|
92 | EXTERN MP_TranspOps_t file_ops; |
---|
93 | |
---|
94 | /* This is the default Big Integer package - GNU Multiple Precision */ |
---|
95 | EXTERN MP_BigIntOps_t gmp_bigint_ops; |
---|
96 | EXTERN MP_BigRealOps_t gmp_bigreal_ops; |
---|
97 | |
---|
98 | static char log_msg[128]; |
---|
99 | /* Note: this is dependent on the order of supported formats defined */ |
---|
100 | /* in MP_BigNum.h. */ |
---|
101 | static char *bignum_format2string[4] = {"Dummy", "GMP", "PARI", "SAC"}; |
---|
102 | |
---|
103 | |
---|
104 | /* At compile time we figure out what the native byte ordering is */ |
---|
105 | /* and set it in the environment. Links will inherit this attribute */ |
---|
106 | /* from the environment as the preferred word ordering and then may */ |
---|
107 | /* negotiate it with their partner. */ |
---|
108 | |
---|
109 | #ifdef WORDS_BIGENDIAN |
---|
110 | static MP_WordOrder_t MP_NATIVE_WORD_ORDER = MP_BigEndian; |
---|
111 | #else |
---|
112 | static MP_WordOrder_t MP_NATIVE_WORD_ORDER = MP_LittleEndian; |
---|
113 | #endif |
---|
114 | |
---|
115 | #ifdef _IEEE |
---|
116 | static MP_FpFormat_t MP_NATIVE_FP_FORMAT = MP_IEEE_fp; |
---|
117 | #elif vax |
---|
118 | static MP_FpFormat_t MP_NATIVE_FP_FORMAT = MP_Vax_fp; |
---|
119 | #elif _AIX |
---|
120 | static MP_FpFormat_t MP_NATIVE_FP_FORMAT = MP_IEEE_fp; |
---|
121 | #else |
---|
122 | static MP_FpFormat_t MP_NATIVE_FP_FORMAT = MP_IEEE_fp; |
---|
123 | #endif |
---|
124 | |
---|
125 | |
---|
126 | /* utility routines used private to this file */ |
---|
127 | #ifdef __STDC__ |
---|
128 | static void mp_free_env_transp_list(MP_Env_pt env) |
---|
129 | #else |
---|
130 | static void mp_free_env_transp_list(env) |
---|
131 | MP_Env_pt env; |
---|
132 | #endif |
---|
133 | { |
---|
134 | MP_TranspList_pt tp, tpn; |
---|
135 | |
---|
136 | if (env == NULL) |
---|
137 | return; |
---|
138 | |
---|
139 | tp = env->transp_dev_list; |
---|
140 | tpn = (MP_TranspList_pt)tp->next; |
---|
141 | IMP_MemFreeFnc(tp, sizeof(struct transp_list_elem)); |
---|
142 | |
---|
143 | while (tpn != NULL) { |
---|
144 | tp = tpn; |
---|
145 | tpn = (MP_TranspList_pt)tp->next; |
---|
146 | IMP_MemFreeFnc(tp, sizeof(struct transp_list_elem)); |
---|
147 | } |
---|
148 | } |
---|
149 | |
---|
150 | |
---|
151 | #ifdef __STDC__ |
---|
152 | MP_Status_t open_logfile(MP_ENV env) |
---|
153 | #else |
---|
154 | MP_Status_t open_logfile(env) |
---|
155 | MP_ENV env; |
---|
156 | #endif |
---|
157 | { |
---|
158 | char fname[128] = MP_LOGFILE; |
---|
159 | char logext[8]; |
---|
160 | int ext = MP_INIT_LOGFILE_EXT; |
---|
161 | |
---|
162 | /* Open a log file with a unique extension starting with mplog.100 */ |
---|
163 | #ifdef __WIN32__ |
---|
164 | while ((env->logfd = fopen(fname, "r")) != NULL && ext < 10000) |
---|
165 | { |
---|
166 | fclose(env->logfd); |
---|
167 | #else |
---|
168 | struct stat buf; |
---|
169 | |
---|
170 | while ((stat(fname, &buf) == 0) && (ext < 100000)) |
---|
171 | { |
---|
172 | #endif |
---|
173 | sprintf(logext, "%d", ++ext); |
---|
174 | fname[0]='\0'; |
---|
175 | strcpy(fname, MP_LOGFILE_NAME); |
---|
176 | strcat(fname, logext); |
---|
177 | } |
---|
178 | |
---|
179 | /* Found a log file name which didn't exist previously, so open it now. */ |
---|
180 | env->logfd = fopen(fname, "w"); |
---|
181 | if (env->logfd == NULL) { |
---|
182 | fprintf(stderr, "MP_InitializeEnv: can't open log file!!\n"); |
---|
183 | fflush(stderr); |
---|
184 | return MP_Failure; |
---|
185 | } |
---|
186 | |
---|
187 | #ifndef __WIN32__ |
---|
188 | /* chmod to a+w so that others can wipe out those files */ |
---|
189 | chmod(fname, |
---|
190 | S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH | S_IWOTH); |
---|
191 | #endif |
---|
192 | |
---|
193 | /* Store the log file name. */ |
---|
194 | env->logfilename = IMP_RawMemAllocFnc(strlen(fname) + 1); |
---|
195 | if (env->logfilename == NULL) { |
---|
196 | fprintf(stderr, "MP_InitializeEnv: can't allocate memory!!\n"); |
---|
197 | fflush(stderr); |
---|
198 | IMP_MemFreeFnc(env, sizeof(MP_Env_t)); |
---|
199 | return MP_Failure; |
---|
200 | } |
---|
201 | strcpy(env->logfilename, fname); |
---|
202 | |
---|
203 | return MP_Success; |
---|
204 | } |
---|
205 | |
---|
206 | |
---|
207 | /****************** Public Interface starts here **************************/ |
---|
208 | |
---|
209 | /*************************************************************************** |
---|
210 | * FUNCTION: MP_AllocateEnv() |
---|
211 | * ARGUMENT: none |
---|
212 | * RETURN: env - pointer to a environment structure |
---|
213 | * PURPOSE: Simply allocate memory for an environment stucture and |
---|
214 | * initialize the variables the may be altered using |
---|
215 | * MP_SetEnvOption(). The rest will be handled by a subsequent |
---|
216 | * call to MP_InitializeEnv(). |
---|
217 | **************************************************************************/ |
---|
218 | #ifdef __STDC__ |
---|
219 | MP_ENV MP_AllocateEnv(void) |
---|
220 | #else |
---|
221 | MP_ENV MP_AllocateEnv() |
---|
222 | #endif |
---|
223 | { |
---|
224 | MP_Env_pt env = ((MP_Env_pt)IMP_MemAllocFnc(sizeof(MP_Env_t))); |
---|
225 | |
---|
226 | if (env == NULL) { /* make sure malloc() worked */ |
---|
227 | fprintf(stderr, "MP_AllocateEnv: can't allocate memory!!\n"); |
---|
228 | fflush(stderr); |
---|
229 | return NULL; |
---|
230 | } |
---|
231 | |
---|
232 | env->transp_dev_list = NULL; |
---|
233 | env->initialized = MP_FALSE; |
---|
234 | env->buffer_size = MP_DEFAULT_BUFF_SIZE; |
---|
235 | env->max_free_buffers = MP_DEFAULT_MAX_FREE_BUFF; |
---|
236 | env->init_free_buffers = MP_DEFAULT_INIT_FREE_BUFF; |
---|
237 | env->num_o_buff = 1; |
---|
238 | env->native_word_order = MP_NATIVE_WORD_ORDER; |
---|
239 | env->native_fp_format = MP_NATIVE_FP_FORMAT; |
---|
240 | |
---|
241 | env->bignum.native_bigint_format = imp_default_bigint_format; |
---|
242 | env->bignum.bigint_ops = &imp_default_bigint_ops; |
---|
243 | env->bignum.native_bigreal_format = imp_default_bigreal_format; |
---|
244 | env->bignum.bigreal_ops = &imp_default_bigreal_ops; |
---|
245 | |
---|
246 | #ifndef NO_LOGGING |
---|
247 | if (open_logfile(env) != MP_Success) |
---|
248 | return NULL; |
---|
249 | #else |
---|
250 | env->logfd = 0; |
---|
251 | env->logfilename = NULL; |
---|
252 | #endif |
---|
253 | |
---|
254 | return env; |
---|
255 | } |
---|
256 | |
---|
257 | |
---|
258 | /*************************************************************************** |
---|
259 | * FUNCTION: MP_InitializeEnv() |
---|
260 | * ARGUMENT: env - pointer to a environment structure (possibly NULL) |
---|
261 | * RETURN: env - pointer to a environment structure |
---|
262 | * PURPOSE: If env is NULL, then we start from scratch to create and |
---|
263 | * completely initialize an environment structure. If env is |
---|
264 | * not NULL, we assume it was created previously with a call |
---|
265 | * to MP_AllocateEnv() and initialize everything except those |
---|
266 | * fields that are settable as options using MP_SetEnvOption(). |
---|
267 | **************************************************************************/ |
---|
268 | #ifdef __STDC__ |
---|
269 | MP_ENV MP_InitializeEnv(MP_Env_pt env) |
---|
270 | #else |
---|
271 | MP_ENV MP_InitializeEnv(env) |
---|
272 | MP_Env_pt env; |
---|
273 | #endif |
---|
274 | { |
---|
275 | char *c; |
---|
276 | time_t now; |
---|
277 | |
---|
278 | if (env == NULL) |
---|
279 | if ((env = MP_AllocateEnv()) == NULL) |
---|
280 | return NULL; |
---|
281 | |
---|
282 | if (gethostname(env->thishost, MP_HOST_NAME_LEN) == -1) |
---|
283 | if ((c = (char *)getenv("HOST")) != NULL) |
---|
284 | strcpy(env->thishost, c); |
---|
285 | else |
---|
286 | strcpy(env->thishost, "can't_get_my_hostname"); |
---|
287 | |
---|
288 | env->num_links = 0; |
---|
289 | env->initialized = MP_TRUE; |
---|
290 | |
---|
291 | if (m_create_pool(env, env->buffer_size, env->max_free_buffers, |
---|
292 | env->init_free_buffers) != MP_Success) { |
---|
293 | fprintf(stderr, "MP_InitializeEnv: can't allocate buffers!!\n"); |
---|
294 | return NULL; |
---|
295 | } |
---|
296 | |
---|
297 | #ifndef NO_LOGGING |
---|
298 | now = time(NULL); |
---|
299 | fprintf(env->logfd, "MP environment: Multi Protocol (MP) version %s %s", |
---|
300 | MP_VERSION, ctime(&now)); |
---|
301 | fprintf(env->logfd, "\thost: %s\n", env->thishost); |
---|
302 | fprintf(env->logfd, "\tlogfile: %s\n", env->logfilename); |
---|
303 | fprintf(env->logfd, "\tbuffer size: %d bytes\n", env->buffer_size); |
---|
304 | fprintf(env->logfd, "\tmax free buffers: %d\n", env->max_free_buffers); |
---|
305 | fprintf(env->logfd, "\tinit free buffers: %d\n", env->init_free_buffers); |
---|
306 | fprintf(env->logfd, "\tnumber output buffers: %d\n", env->num_o_buff); |
---|
307 | fprintf(env->logfd, "\tnative word ordering: "); |
---|
308 | |
---|
309 | if (MP_NATIVE_WORD_ORDER == MP_BigEndian) |
---|
310 | fprintf(env->logfd, "big endian\n"); |
---|
311 | else |
---|
312 | fprintf(env->logfd, "little endian\n"); |
---|
313 | |
---|
314 | /* |
---|
315 | * the following is good for now, but will have to be developed when we |
---|
316 | * add more floating point formats |
---|
317 | */ |
---|
318 | |
---|
319 | fprintf(env->logfd, "\tnative floating point format: "); |
---|
320 | if (MP_NATIVE_FP_FORMAT == MP_IEEE_fp) |
---|
321 | fprintf(env->logfd, "IEEE\n"); |
---|
322 | else |
---|
323 | fprintf(env->logfd, "VAX\n"); |
---|
324 | fprintf(env->logfd, "\tnative multiple precision integer format: %s\n", |
---|
325 | bignum_format2string[env->bignum.native_bigint_format]); |
---|
326 | fprintf(env->logfd, "\n"); |
---|
327 | fflush(env->logfd); |
---|
328 | #endif /* NO_LOGGING */ |
---|
329 | |
---|
330 | MP_AddEnvTranspDevice(env, MP_TcpTransportDev, &tcp_ops); |
---|
331 | MP_AddEnvTranspDevice(env, MP_FileTransportDev, &file_ops); |
---|
332 | |
---|
333 | return env; |
---|
334 | } |
---|
335 | |
---|
336 | |
---|
337 | /*************************************************************************** |
---|
338 | * FUNCTION: MP_ReleaseEnv() |
---|
339 | * ARGUMENT: env - pointer to a environment structure (possibly NULL) |
---|
340 | * RETURN: none |
---|
341 | * PURPOSE: Release all the resources associated with this environment, |
---|
342 | * then release the environment structure. |
---|
343 | **************************************************************************/ |
---|
344 | #ifdef __STDC__ |
---|
345 | void MP_ReleaseEnv(MP_Env_pt env) |
---|
346 | #else |
---|
347 | void MP_ReleaseEnv(env) |
---|
348 | MP_Env_pt env; |
---|
349 | #endif |
---|
350 | { |
---|
351 | if (env == NULL) |
---|
352 | return; |
---|
353 | |
---|
354 | #ifndef NO_LOGGING |
---|
355 | fprintf(env->logfd, "\nReleasing MP environment resources. \n"); |
---|
356 | fclose(env->logfd); |
---|
357 | IMP_RawMemFreeFnc(env->logfilename); |
---|
358 | #endif |
---|
359 | |
---|
360 | mp_free_env_transp_list(env); |
---|
361 | m_free_pool(env->buff_pool); |
---|
362 | |
---|
363 | IMP_MemFreeFnc(env, sizeof(MP_Env_t)); |
---|
364 | } |
---|
365 | |
---|
366 | /******************************************************************** |
---|
367 | * FUNCTION: MP_SetEnvOption |
---|
368 | * ARGUMENT: env - pointer to a env structure |
---|
369 | * option - the option to set |
---|
370 | * value - value to set the option to |
---|
371 | * RETURN: success - old value of the option |
---|
372 | * failure - MP_Failure |
---|
373 | * |
---|
374 | * PURPOSE: Make sure that the option and value are valid. |
---|
375 | ********************************************************************/ |
---|
376 | #ifdef __STDC__ |
---|
377 | int MP_SetEnvOption(MP_Env_pt env, |
---|
378 | int option, |
---|
379 | int value) |
---|
380 | #else |
---|
381 | int MP_SetEnvOption(env, option, value) |
---|
382 | MP_Env_pt env; |
---|
383 | int option; |
---|
384 | int value; |
---|
385 | #endif |
---|
386 | { |
---|
387 | int oldval; |
---|
388 | char logmsg[128]; |
---|
389 | |
---|
390 | if (env == NULL) { |
---|
391 | fprintf(stderr, "MP_SetEnvOption: null environment!!\n"); |
---|
392 | fflush(stderr); |
---|
393 | return MP_Failure; |
---|
394 | } |
---|
395 | |
---|
396 | switch (option) { |
---|
397 | case MP_BUFFER_SIZE_OPT: |
---|
398 | oldval = env->buffer_size; |
---|
399 | sprintf(logmsg, |
---|
400 | "Init Event %s %d", "MP_SetEnvOption: set buffer size to", |
---|
401 | value); |
---|
402 | env->buffer_size = value; |
---|
403 | break; |
---|
404 | |
---|
405 | case MP_MAX_FREE_BUFFERS_OPT: |
---|
406 | oldval = env->max_free_buffers; |
---|
407 | sprintf(logmsg, "Init Event %s %d", |
---|
408 | "MP_SetEnvOption: set maximum free buffers to ", value); |
---|
409 | env->max_free_buffers = value; |
---|
410 | break; |
---|
411 | |
---|
412 | case MP_INIT_FREE_BUFFERS_OPT: |
---|
413 | oldval = env->init_free_buffers; |
---|
414 | if (env->init_free_buffers > env->max_free_buffers) |
---|
415 | env->init_free_buffers = env->max_free_buffers; |
---|
416 | else |
---|
417 | env->init_free_buffers = value; |
---|
418 | sprintf(logmsg, "Init Event %s %d", |
---|
419 | "MP_SetEnvOption: set initial number of free buffers to ", |
---|
420 | env->init_free_buffers); |
---|
421 | break; |
---|
422 | |
---|
423 | default: |
---|
424 | sprintf(logmsg, "%s: MP_SetEnvOption: illegal option %d", |
---|
425 | MP_ERROR_EVENT, option); |
---|
426 | oldval = MP_Failure; |
---|
427 | } |
---|
428 | |
---|
429 | #ifndef NO_LOGGING |
---|
430 | fprintf(env->logfd, "%s\n", logmsg); |
---|
431 | #endif |
---|
432 | |
---|
433 | return oldval; |
---|
434 | } |
---|
435 | |
---|
436 | |
---|
437 | |
---|
438 | /******************************************************************** |
---|
439 | * FUNCTION: MP_GetEnvOption |
---|
440 | * ARGUMENT: env - pointer to a env structure |
---|
441 | * option - the option to return |
---|
442 | * RETURN: success - value of the option |
---|
443 | * failure - MP_Failure |
---|
444 | * |
---|
445 | * PURPOSE: Make sure that the option is valid. |
---|
446 | ********************************************************************/ |
---|
447 | #ifdef __STDC__ |
---|
448 | int MP_GetEnvOption(MP_Env_pt env, |
---|
449 | int option) |
---|
450 | #else |
---|
451 | int MP_GetEnvOption(env, option) |
---|
452 | MP_Env_pt env; |
---|
453 | int option; |
---|
454 | #endif |
---|
455 | { |
---|
456 | if (env == NULL) { |
---|
457 | fprintf(stderr, "MP_GetEnvOption: null environment!!\n"); |
---|
458 | fflush(stderr); |
---|
459 | return MP_Failure; |
---|
460 | } |
---|
461 | |
---|
462 | switch (option) { |
---|
463 | case MP_BUFFER_SIZE_OPT: |
---|
464 | return env->buffer_size; |
---|
465 | |
---|
466 | case MP_INIT_FREE_BUFFERS_OPT: |
---|
467 | return env->init_free_buffers; |
---|
468 | |
---|
469 | default: ; |
---|
470 | } |
---|
471 | |
---|
472 | return MP_Failure; |
---|
473 | } |
---|
474 | |
---|
475 | |
---|
476 | |
---|
477 | /*************************************************************************** |
---|
478 | * FUNCTION: MP_AddEnvTranspDevice() |
---|
479 | * ARGUMENT: env - the environment to which we will add the device |
---|
480 | * name - the name by which the device will be known. This |
---|
481 | * is the value to be used with -MPtransp (changed to int) |
---|
482 | * ops - the MP_TranspOps_t structure containing pointers to the |
---|
483 | * functions for this device. |
---|
484 | * RETURN: MP_Status - MP_Success if all goes well |
---|
485 | * - MP_Failure only if env is null or we run out of mem. |
---|
486 | * PURPOSE: Create a new transport list element structure, fill in the |
---|
487 | * fields with the function's arguments and place the new list |
---|
488 | * element at the head of the environment's device list. Note |
---|
489 | * that we don't check for duplicates. As my brother and I used |
---|
490 | * to say, if the user does this, "that his dumbness". |
---|
491 | **************************************************************************/ |
---|
492 | #ifdef __STDC__ |
---|
493 | MP_Status_t MP_AddEnvTranspDevice(MP_Env_pt env, |
---|
494 | int transp_dev, |
---|
495 | MP_TranspOps_t *ops) |
---|
496 | #else |
---|
497 | MP_Status_t MP_AddEnvTranspDevice(env, transp_dev, ops) |
---|
498 | MP_Env_pt env; |
---|
499 | int transp_dev; |
---|
500 | MP_TranspOps_t *ops; |
---|
501 | #endif |
---|
502 | { |
---|
503 | MP_TranspList_pt tp; |
---|
504 | |
---|
505 | #ifdef MP_DEBUG |
---|
506 | fprintf(stderr,"MP_AddEnvTranspDevice: entering to add device %d\n", transp_dev); |
---|
507 | fflush(stderr); |
---|
508 | #endif |
---|
509 | |
---|
510 | if (env == NULL) |
---|
511 | return MP_Failure; /* may have to do more */ |
---|
512 | |
---|
513 | if ((tp = IMP_MemAllocFnc(sizeof(struct transp_list_elem))) == NULL) |
---|
514 | return MP_Failure; |
---|
515 | |
---|
516 | tp->transp_dev = transp_dev; |
---|
517 | |
---|
518 | memcpy((char *)&(tp->transp_ops), (char *)ops, sizeof(MP_TranspOps_t)); |
---|
519 | tp->next = (MP_TranspList_pt *)env->transp_dev_list; |
---|
520 | env->transp_dev_list = tp; |
---|
521 | |
---|
522 | #ifndef NO_LOGGING |
---|
523 | fprintf(env->logfd, "\tAdded transport device %d to environment\n", |
---|
524 | transp_dev ); |
---|
525 | fflush(env->logfd); |
---|
526 | #endif |
---|
527 | |
---|
528 | #ifdef MP_DEBUG |
---|
529 | fprintf(stderr,"MP_AddEnvTranspDevice: exiting\n"); |
---|
530 | fflush(stderr); |
---|
531 | #endif |
---|
532 | |
---|
533 | return MP_Success; |
---|
534 | } |
---|
535 | |
---|
536 | |
---|
537 | |
---|
538 | /*************************************************************************** |
---|
539 | * FUNCTION: MP_SetEnvBigIntFormat() |
---|
540 | * ARGUMENT: env - the environment for which we change the big num package |
---|
541 | * format - the name of the BigInt package to use. The list of |
---|
542 | * supported packages can also be found in MP_Types.h. |
---|
543 | * ops - the MP_BigIntOps_t structure containing pointers to the |
---|
544 | * functions for this BigInt package. |
---|
545 | * RETURN: MP_Status - MP_Success if all goes well |
---|
546 | * - MP_Failure only if env is null or we run out of mem. |
---|
547 | * PURPOSE: Change the big integer package to be used for sending and |
---|
548 | * receiving arbitrary precision integers. The default is the |
---|
549 | * GNU Multiple Precision package. But if communication is b/t |
---|
550 | * homogeneous systems, we want to avoid the conversion to GMP. |
---|
551 | * Also, this approach make any _necessary_ conversions transparent. |
---|
552 | * The sender at least has the illusion of sending in its "native" |
---|
553 | * format (assuming it is one of the supported packages). |
---|
554 | * NOTE: if the ops structure is not one already supported by MP, |
---|
555 | * we cannot verify that it has the correct functionality. We |
---|
556 | * trust the programmer on this one. |
---|
557 | **************************************************************************/ |
---|
558 | #ifdef __STDC__ |
---|
559 | MP_Status_t MP_SetEnvBigIntFormat(MP_Env_t *env, |
---|
560 | MP_BigIntOps_t *ops, |
---|
561 | MP_BigNumFormat_t format) |
---|
562 | #else |
---|
563 | MP_Status_t MP_SetEnvBigIntFormat(env, ops, format) |
---|
564 | MP_Env_t *env; |
---|
565 | MP_BigIntOps_t *ops; |
---|
566 | MP_BigNumFormat_t format; |
---|
567 | #endif |
---|
568 | { |
---|
569 | if (env == NULL) |
---|
570 | return MP_NullLink; |
---|
571 | |
---|
572 | switch (format) { |
---|
573 | case MP_GMP: |
---|
574 | sprintf(log_msg, "%s: environment BigInt format set to %s\n", |
---|
575 | MP_INIT_EVENT, bignum_format2string[format]); |
---|
576 | break; |
---|
577 | case MP_SAC: |
---|
578 | sprintf(log_msg, "%s: environment BigInt format set to %s\n", |
---|
579 | MP_INIT_EVENT, bignum_format2string[format]); |
---|
580 | break; |
---|
581 | case MP_PARI: |
---|
582 | sprintf(log_msg, "%s: environment BigInt format set to %s\n", |
---|
583 | MP_INIT_EVENT, bignum_format2string[format]); |
---|
584 | break; |
---|
585 | |
---|
586 | default: |
---|
587 | sprintf(log_msg, |
---|
588 | "%s: environment BigInt format set to user-supplied package: %d\n", |
---|
589 | MP_INIT_EVENT, format); |
---|
590 | } |
---|
591 | env->bignum.native_bigint_format = format; |
---|
592 | env->bignum.bigint_ops = ops; |
---|
593 | |
---|
594 | #ifndef NO_LOGGING |
---|
595 | fprintf(env->logfd, log_msg); |
---|
596 | #endif |
---|
597 | |
---|
598 | return MP_Success; |
---|
599 | } |
---|
600 | |
---|
601 | /*************************************************************************** |
---|
602 | * FUNCTION: MP_SetEnvBigRealFormat() |
---|
603 | * ARGUMENT: env - the environment for which we change the big num package |
---|
604 | * format - the name of the BigReal package to use. The list of |
---|
605 | * supported packages can also be found in MP_Types.h. |
---|
606 | * ops - the MP_BigRealOps_t structure containing pointers to the |
---|
607 | * functions for this BigReal package. |
---|
608 | * RETURN: MP_Status - MP_Success if all goes well |
---|
609 | * - MP_Failure only if env is null or we run out of mem. |
---|
610 | * PURPOSE: Change the big real package to be used for sending and |
---|
611 | * receiving arbitrary precision reals. The default is the |
---|
612 | * GNU Multiple Precision package. But if communication is b/t |
---|
613 | * homogeneous systems, we want to avoid the conversion to GMP. |
---|
614 | * Also, this approach make any _necessary_ conversions transparent. |
---|
615 | * The sender at least has the illusion of sending in its "native" |
---|
616 | * format (assuming it is one of the supported packages). |
---|
617 | * NOTE: if the ops structure is not one already supported by MP, |
---|
618 | * we cannot verify that it has the correct functionality. We |
---|
619 | * trust the programmer on this one. |
---|
620 | **************************************************************************/ |
---|
621 | #ifdef __STDC__ |
---|
622 | MP_Status_t MP_SetEnvBigRealFormat(MP_Env_t *env, |
---|
623 | MP_BigRealOps_t *ops, |
---|
624 | MP_BigNumFormat_t format) |
---|
625 | #else |
---|
626 | MP_Status_t MP_SetEnvBigRealFormat(env, ops, format) |
---|
627 | MP_Env_t *env; |
---|
628 | MP_BigRealOps_t *ops; |
---|
629 | MP_BigNumFormat_t format; |
---|
630 | #endif |
---|
631 | { |
---|
632 | MP_Status_t status = MP_Success; |
---|
633 | |
---|
634 | if (env == NULL) |
---|
635 | return MP_NullLink; |
---|
636 | |
---|
637 | switch (format) { |
---|
638 | case MP_GMP: |
---|
639 | sprintf(log_msg, "%s: environment BigReal format set to %s\n", |
---|
640 | MP_INIT_EVENT, bignum_format2string[format]); |
---|
641 | break; |
---|
642 | case MP_SAC: |
---|
643 | sprintf(log_msg, "%s: %s does not support a BigReal format\n", |
---|
644 | MP_ERROR_EVENT, bignum_format2string[format]); |
---|
645 | status = MP_Failure; |
---|
646 | break; |
---|
647 | case MP_PARI: |
---|
648 | sprintf(log_msg, "%s: environment BigReal format set to %s\n", |
---|
649 | MP_INIT_EVENT, bignum_format2string[format]); |
---|
650 | break; |
---|
651 | |
---|
652 | default: |
---|
653 | sprintf(log_msg, |
---|
654 | "%s: environment BigReal format set to user-supplied package: %d\n", |
---|
655 | MP_INIT_EVENT, format); |
---|
656 | } |
---|
657 | if (status == MP_Success) { |
---|
658 | env->bignum.native_bigreal_format = format; |
---|
659 | env->bignum.bigreal_ops = ops; |
---|
660 | } |
---|
661 | |
---|
662 | #ifndef NO_LOGGING |
---|
663 | fprintf(env->logfd, log_msg); |
---|
664 | #endif |
---|
665 | |
---|
666 | return status; |
---|
667 | } |
---|
668 | |
---|
669 | |
---|
670 | /*************************************************************************** |
---|
671 | * FUNCTION: IMP_GetTranspByName |
---|
672 | * ARGUMENT: env - the environment to which we will add the device |
---|
673 | * name - the name of the device we are looking for. This is the |
---|
674 | * name used with -MPtransp. |
---|
675 | * RETURN: NULL on failure to find the device or env is NULL. |
---|
676 | * pointer to a transport list element if name is found. |
---|
677 | * PURPOSE: Search the environment's device list for a device with the |
---|
678 | * given name. Return the _first_ occurrence found. |
---|
679 | **************************************************************************/ |
---|
680 | #ifdef __STDC__ |
---|
681 | MP_TranspList_pt IMP_GetTranspByName(MP_Env_pt env, |
---|
682 | int transp_dev) |
---|
683 | #else |
---|
684 | MP_TranspList_pt IMP_GetTranspByName(env, transp_dev) |
---|
685 | MP_Env_pt env; |
---|
686 | int transp_dev; |
---|
687 | #endif |
---|
688 | { |
---|
689 | MP_TranspList_pt tp; |
---|
690 | |
---|
691 | if (env == NULL) |
---|
692 | return NULL; |
---|
693 | |
---|
694 | tp = env->transp_dev_list; |
---|
695 | while (tp != NULL && (transp_dev != tp->transp_dev)) |
---|
696 | tp = (MP_TranspList_pt)tp->next; |
---|
697 | |
---|
698 | return tp; |
---|
699 | } |
---|
700 | |
---|
701 | |
---|