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