Main Page   Compound List   File List   Compound Members   File Members  

init.c

00001 /* DICElib (DIstributed CAVE Engine library) 
00002  * Copyright (c) 2001 Bruno Barberi Gnecco <brunobg@lsi.usp.br>
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to
00006  * deal in the Software without restriction, including without limitation the
00007  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
00008  * sell copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies of the Software, its documentation and marketing & publicity
00013  * materials, and acknowledgment shall be given in the documentation, materials
00014  * and software packages that this Software was used.
00015  *
00016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00019  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00020  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00021  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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" /* should be auto-set */
00037 #endif /* WINDOWS */
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]; /*todo: dynamic */
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(); /* memory leaks */
00099 #endif
00100 
00101 //      putenv("DISPLAY=:0.0");
00102         /* init defaults */
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         /* parse arguments; and get a copy for spawning */
00131         /* ourargv[0]: machine name.
00132            ourargv[1]: program name.
00133            ourargv[2]: --dice-control-is
00134            ourargv[3]: control address
00135         */
00136         /* set program name */
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         /* other initializations */
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         /* try to read data file. SHOULD BE DONE ONLY IN CONTROL, i.e., after fork!! */
00287         if ( flags.norc == 0 && type == CONTROL ) {
00288                 if (dice_parse_dicerc())
00289                         return -1;
00290         }
00291 
00292         if ( type == CONTROL ) { /* child or server only*/
00293                 dice_data.color[0] = strdup("");
00294                 dice_data.color[1] = strdup("");
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 ) { /* assume localhost */
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; /* to know we are clients */
00322         /* client */
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 //      dice_free(dice_data.controlname);
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 ) { /* BSD limit it to 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         /* try to open file */
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         /* parse */
00490         /* number of clients */
00491         while (!feof(fp)) {
00492                 fgets(buf, 256, fp);
00493                 t = strtok(buf, " \t\r\n");
00494                 if (t && *t != '#')     /* filter comments */
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         /* get client names */
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                 /* get path */
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                 /* get functions */
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 /* The following is only used for documentation, and can be disregarded. */

Generated at Sun Dec 9 16:13:18 2001 for dicelib by doxygen1.2.9.1 written by Dimitri van Heesch, © 1997-2001