00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "_dicelib.h"
00025 #include <stdarg.h>
00026 #include <string.h>
00027 #include <errno.h>
00028 #ifndef WINDOWS
00029 #include <unistd.h>
00030 #include <sys/types.h>
00031 #include <signal.h>
00032 # ifdef USE_LTDL
00033 # include <ltdl.h>
00034 # endif
00035 #else
00036 #define VERSION "Windows port"
00037 #endif
00038
00039 #ifdef USE_MCHECK
00040 #include <mcheck.h>
00041 #endif
00042
00043 int init = 0;
00044
00045 struct _dice_data dice_data;
00046 pid_t pid = 0;
00047 char *defaultpath;
00048 char **environ;
00049 static int dice_parse_dicerc ( void );
00050
00051 #define NO_FUNC ""
00052
00053 #define FUNCTION "DICE_init"
00054
00083 int DICE_init ( int *argc, char **argv ) {
00084 int i;
00085 struct { int norc;
00086 } flags = { 0 };
00087 enum { CONTROL, CLIENT } type = CONTROL;
00088 char *ourargv[25];
00089 char dir[256], *tmp;
00090 int ourargc, used_args = 0;
00091
00092 if ( init == 0 )
00093 init = 1;
00094 else
00095 return -1;
00096
00097 #ifdef USE_MCHECK
00098 mtrace();
00099 #endif
00100
00101
00102
00103 dice_data.verbose = 3;
00104 dice_data.port = 6748;
00105 dice_data.max_connections = 5;
00106 dice_data.error = stderr;
00107 dice_data.handle = NULL;
00108 dice_data.color[0] = NULL;
00109 dice_data.color[1] = NULL;
00110 dice_data.clientnum = -1;
00111 dice_data.clients = NULL;
00112 dice_data.id = -1;
00113 dice_data.controlname = NULL;
00114 dice_data.original_only = 0;
00115 dice_data.spawn = RSH;
00116 _dice_debug(3, fprintf(dice_data.error, FUNCTION "()\n");)
00117
00118 #ifdef USE_LTDL
00119 if ( lt_dlinit() ) {
00120 _dice_debug(1, fprintf(dice_data.error, FUNCTION "Error in ltdl: %s", lt_dlerror());)
00121 return -11;
00122 }
00123 dice_data.handle = lt_dlopen(NULL);
00124 if ( !dice_data.handle ) {
00125 _dice_debug(1, fprintf(dice_data.error, FUNCTION " %s\n", lt_dlerror());)
00126 return -1;
00127 }
00128 #endif
00129
00130
00131
00132
00133
00134
00135
00136
00137 tmp = strrchr(argv[0], '/');
00138 if ( !tmp )
00139 tmp = argv[0];
00140 else
00141 tmp++;
00142 getcwd(dir, 256);
00143 defaultpath = malloc(strlen(dir)+strlen(tmp)+2);
00144 strcpy(defaultpath, dir);
00145 strcat(defaultpath, "/");
00146 strcat(defaultpath, tmp);
00147 ourargv[2] = strdup("--dice-control-is");
00148 ourargc = 4;
00149
00150 for ( i = 1; i < *argc; ) {
00151 if ( strcmp(argv[i], "--dice-client-num" ) == 0 ) {
00152 dice_data.clientnum = atoi(argv[i+1]);
00153 _dice_debug(3, dice_printf(FUNCTION, "using %d clients.\n",
00154 dice_data.clientnum);)
00155 if (i+2 <= *argc)
00156 memmove(&argv[i], &argv[i+2], sizeof(char *)*(*argc-i));
00157 }
00158 else if ( strcmp(argv[i], "--dice-client-only" ) == 0 ) {
00159 _dice_debug(3, dice_printf(FUNCTION, "We're CLIENT\n");)
00160 type = CLIENT;
00161 used_args = 1;
00162 }
00163 else if ( strcmp(argv[i], "--dice-control-is" ) == 0 ) {
00164 _dice_debug(3, dice_printf(FUNCTION, "control is: %s\n",
00165 argv[i+1]);)
00166 dice_data.controlname = argv[i+1];
00167 used_args = 2;
00168 type = CLIENT;
00169 }
00170 else if ( strcmp(argv[i], "--dice-control-only" ) == 0 ) {
00171 _dice_debug(3, dice_printf(FUNCTION, "We're CONTROL\n");)
00172 type = CONTROL;
00173 (*argc)--;
00174 if (i+1 <= *argc)
00175 memmove(&argv[i], &argv[i+1], sizeof(char *)*(*argc-i));
00176 }
00177 else if ( strcmp(argv[i], "--dice-environment" ) == 0 ) {
00178 _dice_debug(3, dice_printf(FUNCTION, "environment: %s\n",
00179 argv[i+1]);)
00180 putenv(argv[i+1]);
00181 used_args = 2;
00182 }
00183 #if 0
00184 else if ( strcmp(argv[i], "--dice-function" ) == 0 ) {
00185 _dice_debug(3, dice_printf(FUNCTION, "function is: %s\n",
00186 argv[i+1]);)
00187 if ( *argv[i+1] != '!' ) {
00188 dice_data.function = dlsym(dice_data.handle, argv[i+1]);
00189 if ( !dice_data.function ) {
00190 _dice_debug(2, dice_printf(FUNCTION, "function %s not found: %s\n",
00191 argv[i+1], dlerror());)
00192 }
00193 }
00194 used_args = 2;
00195 }
00196 #endif
00197 else if ( strcmp(argv[i], "--dice-no-rc" ) == 0 ) {
00198 _dice_debug(3, dice_printf(FUNCTION, "don't read rc.\n");)
00199 flags.norc = 1;
00200 used_args = 1;
00201 }
00202 else if ( strcmp(argv[i], "--dice-spawn" ) == 0 ) {
00203 if ( strcmp(argv[i+1], "none") == 0 )
00204 dice_data.spawn = NONE;
00205 else if ( strcmp(argv[i+1], "rsh") == 0 )
00206 dice_data.spawn = RSH;
00207 else if ( strcmp(argv[i+1], "ssh") == 0 )
00208 dice_data.spawn = SSH;
00209 else if ( strcmp(argv[i+1], "bproc") == 0 )
00210 dice_data.spawn = BPROC;
00211 else {
00212 _dice_debug(1, dice_printf(FUNCTION, "Invalid spawn option: %s\n", argv[i+1]);)
00213 i++;
00214 continue;
00215 }
00216 _dice_debug(3, dice_printf(FUNCTION, "Spawn type: %s.\n", argv[i+1]);)
00217 *argc -= 2;
00218 if (i+2 <= *argc)
00219 memmove(&argv[i], &argv[i+2], sizeof(char **)*(*argc-i));
00220 }
00221 #if 0
00222 else if ( strcmp(argv[i], "--dice-original" ) == 0 ) {
00223 _dice_debug(3, dice_printf(FUNCTION, "original only.\n");)
00224 dice_data.original = 1;
00225 used_args = 1;
00226 }
00227 #endif
00228 else if ( strcmp(argv[i], "--dice-output" ) == 0 ) {
00229 FILE *out;
00230 if ( (out = fopen(argv[i+1], "w")) != NULL ) {
00231 dice_data.error = out;
00232 _dice_debug(3, dice_printf(FUNCTION,
00233 "output will be sent to %s\n",
00234 argv[i+1]);)
00235 }
00236 used_args = 2;
00237 }
00238 else if ( strcmp(argv[i], "--dice-port" ) == 0 ) {
00239 dice_data.port = atoi(argv[i+1]);
00240 _dice_debug(3, dice_printf(FUNCTION, "port set to %d\n",
00241 dice_data.port);)
00242 used_args = 2;
00243 }
00244 else if ( strcmp(argv[i], "--dice-verbose" ) == 0 ) {
00245 dice_data.verbose = atoi(argv[i+1]);
00246 _dice_debug(1, dice_printf(FUNCTION, "verbose set to %d\n",
00247 dice_data.verbose);)
00248 used_args = 2;
00249 }
00250 else if ( strncmp(argv[i], "--dice", 6) == 0 ) {
00251 _dice_debug(2, dice_printf(FUNCTION, "invalid argument %s\n",
00252 argv[i]);)
00253 i++;
00254 }
00255 else {
00256 i++;
00257 }
00258 if (used_args) {
00259 memcpy(&ourargv[ourargc], &argv[i], used_args*sizeof(char *));
00260 ourargc += used_args;
00261 *argc -= used_args;
00262 if (i+used_args <= *argc)
00263 memmove(&argv[i], &argv[i+used_args], sizeof(char *)*(*argc-i));
00264 used_args = 0;
00265 }
00266 }
00267 ourargv[ourargc] = NULL;
00268
00269
00270
00271 if ( dice_type_init_defaults() == -1 ) {
00272 _dice_debug(1, dice_printf(FUNCTION, "init_types\n");)
00273 return -1;
00274 }
00275 if ( dice_sync_init() == -1 ) {
00276 _dice_debug(1, dice_printf(FUNCTION, "sync_init\n");)
00277 return -1;
00278 }
00279 #ifdef USE_ASYNC
00280 if ( dice_async_init() == -1 ) {
00281 _dice_debug(1, dice_printf(FUNCTION, "async_init\n");)
00282 return -1;
00283 }
00284 #endif
00285
00286
00287 if ( flags.norc == 0 && type == CONTROL ) {
00288 if (dice_parse_dicerc())
00289 return -1;
00290 }
00291
00292 if ( type == CONTROL ) {
00293 dice_data.color[0] = strdup("[0;31m");
00294 dice_data.color[1] = strdup("[0m");
00295 dice_data.controlname = (char *)malloc(127);
00296 if ( !dice_data.controlname ) {
00297 _dice_debug(1, dice_printf(FUNCTION, "%s\n", strerror(errno));)
00298 return -1;
00299 }
00300 gethostname(dice_data.controlname, 127);
00301 _dice_debug(3, dice_printf(FUNCTION, "I'm the server %s\n",
00302 dice_data.controlname);)
00303 _exit(dice_control_loop(ourargc, ourargv));
00304 }
00305 else if ( type == CLIENT ) {
00306 dice_data.color[0] = NULL;
00307 dice_data.color[1] = NULL;
00308
00309 _dice_debug(3, dice_printf(FUNCTION, "I'm the client\n");)
00310 if ( !dice_data.controlname ) {
00311 dice_data.controlname = (char *)malloc(127);
00312 if ( !dice_data.controlname ) {
00313 _dice_debug(1, dice_printf(FUNCTION, "%s\n", strerror(errno));)
00314 return -1;
00315 }
00316 gethostname(dice_data.controlname, 127);
00317 }
00318 _dice_debug(3, dice_printf(FUNCTION, "Control is %s\n", dice_data.controlname);)
00319 }
00320
00321 dice_data.clientnum = -1;
00322
00323 return dice_init_client();
00324 }
00325
00326 #undef FUNCTION
00327 #define FUNCTION "DICE_close"
00328
00333 void DICE_close ( void ) {
00334 dice_packet bye;
00335 _dice_debug(3, dice_printf(FUNCTION, "()\n");)
00336
00337 if ( init == 0 )
00338 return;
00339
00340 bye.packtype = GOODBYE;
00341 dice_packet_send(&bye, dice_data.controlsock);
00342
00343 #ifdef USE_ASYNC
00344 dice_async_end();
00345 #endif
00346 dice_sync_end();
00347 dice_type_free_all();
00348 #ifdef USE_LTDL
00349 lt_dlexit();
00350 #endif
00351
00352 dice_free(dice_data.color[0]);
00353 dice_free(dice_data.color[1]);
00354 close(dice_data.controlsock);
00355 }
00356
00357 #undef FUNCTION
00358 #define FUNCTION "DICE_set_attribute"
00359
00368 int DICE_set_attribute ( DICE_AttributeType t, void *value ) {
00369 _dice_debug(3, dice_printf(FUNCTION, "(%d, %p)\n", t, value);)
00370 switch ( t ) {
00371 case LIBVERSION:
00372 _dice_debug(2, dice_printf(FUNCTION, " VERSION is read-only.\n");)
00373 return 0;
00374 case VERBOSE:
00375 if ( (int)value < 0 || (int)value > 3 ) {
00376 _dice_debug(2, dice_printf(FUNCTION, " VERBOSE out of bonds: %d\n", (int)value);)
00377 return -1;
00378 }
00379 dice_data.verbose = (int)value;
00380 return 0;
00381 case PORT:
00382 if ( (int)value < 1024 || (int)value > 65535 ) {
00383 _dice_debug(2, dice_printf(FUNCTION, " PORT out of bonds: %d\n", (int)value);)
00384 return -1;
00385 }
00386 dice_data.port = (int)value;
00387 return 0;
00388 case MAX_CONNECTIONS:
00389 if ( (int)value <= 0 && (int)value < 5 ) {
00390 _dice_debug(2, dice_printf(FUNCTION, " MAX_CONNECTIONS out of bonds: %d\n", (int)value);)
00391 return -1;
00392 }
00393 dice_data.max_connections = (int)value;
00394 return 0;
00395 case OUTPUT:
00396 if ( value == NULL ) {
00397 _dice_debug(2, dice_printf(FUNCTION, " NULL file\n");)
00398 return -1;
00399 }
00400 dice_data.error = (FILE *)value;
00401 return 0;
00402 case COLOR:
00403 return 0;
00404 default:
00405 _dice_debug(2, dice_printf(FUNCTION, " No such attribute %d\n", t);)
00406 return -1;
00407 }
00408 }
00409
00410 #undef FUNCTION
00411 #define FUNCTION "DICE_get_attribute"
00412
00419 void *DICE_get_attribute ( DICE_AttributeType t ) {
00420 _dice_debug(3, dice_printf(FUNCTION, "(%d)\n", t);)
00421 switch ( t ) {
00422 case LIBVERSION:
00423 return (void *)VERSION;
00424 case VERBOSE:
00425 return (void *)dice_data.verbose;
00426 case PORT:
00427 return (void *)dice_data.port;
00428 case MAX_CONNECTIONS:
00429 return (void *)dice_data.max_connections;
00430 case OUTPUT:
00431 return (void *)dice_data.color;
00432 case COLOR:
00433 return (void *)dice_data.color;
00434 default:
00435 _dice_debug(2, dice_printf(FUNCTION, " No such attribute %d\n", t);)
00436 }
00437 return NULL;
00438 }
00439
00448 void dice_printf ( char *function, char *format, ... ) {
00449 va_list argp;
00450
00451 if ( dice_data.color[0] )
00452 fputs(dice_data.color[0], dice_data.error);
00453 if ( function ) {
00454 fputs(function, dice_data.error);
00455 fputs(": ", dice_data.error);
00456 }
00457 va_start(argp, format);
00458 vfprintf(dice_data.error, format, argp);
00459 va_end(argp);
00460 if ( dice_data.color[1] )
00461 fputs(dice_data.color[1], dice_data.error);
00462 }
00463
00464 #undef FUNCTION
00465 #define FUNCTION "dice_parse_dicerc"
00466
00472 static int dice_parse_dicerc ( void ) {
00473 FILE *fp;
00474 char buf[256], *t;
00475 int lines = 0;
00476
00477
00478 fp = fopen("dicerc", "r");
00479 if (!fp)
00480 fp = fopen("~/dicerc", "r");
00481 if (!fp)
00482 fp = fopen("/etc/dicerc", "r");
00483
00484 if (!fp) {
00485 _dice_debug(1, dice_printf(FUNCTION, "Could not find dicerc\n");)
00486 return -1;
00487 }
00488
00489
00490
00491 while (!feof(fp)) {
00492 fgets(buf, 256, fp);
00493 t = strtok(buf, " \t\r\n");
00494 if (t && *t != '#')
00495 lines++;
00496 }
00497 rewind(fp);
00498 if (dice_data.clientnum <= 0 || dice_data.clientnum > lines)
00499 dice_data.clientnum = lines;
00500
00501 dice_data.clients = malloc(dice_data.clientnum*sizeof(struct _clients));
00502 if (!dice_data.clients) {
00503 _dice_debug(1, dice_printf(FUNCTION, "Malloc clients.\n");)
00504 return -1;
00505 }
00506
00507
00508 lines = 0;
00509 while (!feof(fp) && lines < dice_data.clientnum) {
00510 fgets(buf, 256, fp);
00511 t = strtok(buf, " \t\r\n");
00512 if (t && *t != '#' ) {
00513 dice_data.clients[lines].address = strdup(t);
00514 if (!dice_data.clients[lines].address) {
00515 _dice_debug(1, dice_printf(FUNCTION, "strdup\n");)
00516 return -1;
00517 }
00518 }
00519 else
00520 continue;
00521
00522 if (!(t = strtok(NULL, " \t\r\n"))) {
00523 dice_data.clients[lines].path = NULL;
00524 dice_data.clients[lines].function = NO_FUNC;
00525 continue;
00526 }
00527
00528
00529 if (*t == '%')
00530 dice_data.clients[lines].path = NULL;
00531 else {
00532 dice_data.clients[lines].path = strdup(t);
00533 if (!dice_data.clients[lines].path) {
00534 _dice_debug(1, dice_printf(FUNCTION,
00535 "strdup 2\n");)
00536 return -1;
00537 }
00538 }
00539
00540 if ((t = strtok(NULL, " \t\r\n"))) {
00541 dice_data.clients[lines].function = strdup(t);
00542 if (!dice_data.clients[lines].function) {
00543 _dice_debug(1, dice_printf(FUNCTION,
00544 "strdup 3\n");)
00545 return -1;
00546 }
00547 }
00548 else
00549 dice_data.clients[lines].function = NO_FUNC;
00550
00551 dice_printf(FUNCTION, "[%s %s %s]\n",
00552 dice_data.clients[lines].address,
00553 dice_data.clients[lines].path,
00554 dice_data.clients[lines].function);
00555 lines++;
00556 }
00557 fclose(fp);
00558 return 0;
00559 }
00560
00561
00562