server_start.c

Go to the documentation of this file.
00001 
00007 /* $Id: server_start.c,v 1.147 2009/09/11 19:35:15 yarkhan Exp $ */
00008 /* $UTK_Copyright: $ */
00009 
00010 #include <stdlib.h>
00011 #include <stdio.h>
00012 #include <glob.h>
00013 #include <sys/types.h>
00014 #include <sys/stat.h>
00015 #include <sys/wait.h>
00016 #include <unistd.h>
00017 #include <fcntl.h>
00018 #include <string.h>
00019 #include <signal.h>
00020 #include <errno.h>
00021 
00022 #ifdef HAVE_CONFIG_H
00023 #include "config.h"
00024 #include "gridsolve-config.h"
00025 #endif
00026 
00027 #include "utility.h"
00028 #include "problem.h"
00029 #include "server.h"
00030 #include "comm_basics.h"
00031 #include "comm_data.h"
00032 #include "comm_encode.h"
00033 #include "general.h"
00034 #include "proxylib.h"
00035 #include "kflops.h"
00036 
00037 
00038 #include "gs_seq_dsi.h"
00039 
00040 
00042 static char 
00043   *gridsolve_root = NULL,
00044   *gridsolve_arch = NULL,
00045   *gridsolve_agent = NULL;
00046 
00047 char GS_SERVER_JOB_COUNT_FILE[FN_LEN];
00048 #ifdef GS_SMART_GRIDSOLVE
00049 char GS_SMART_OBJ_FILE_EXT[FN_LEN];
00050 /*
00051  * pointer to list of stored arguments
00052  * in server memory
00053  */ 
00054 gs_argument_t * stored_arg_list;
00055 
00056 /*
00057  * pointer to last stored argument
00058  * in server memory
00059  */ 
00060 gs_argument_t * last_stored_arg;
00061 
00062 
00063 /*
00064  * total number of bytes of arguments stored in
00065  * arg list
00066  */ 
00067 int total_bytes_stored;
00068 char * smart_obj_file_dir="/tmp/gs_smart_arg_files";
00069 
00070 
00071 /*
00072  * total allowed bytes as specified in server_config file. 
00073  */ 
00074 int total_allowed_bytes;
00075 #endif
00076 
00078 static int 
00079   gs_probe_batch_request(char *),
00080   gs_cancel_batch_request(char *),
00081   process_problem_solve(gs_server_t *, int, int),
00082   process_probe_request(int),
00083   process_problem_example(int),
00084   process_cancel_request(int),
00085   process_await_completion(int),
00086   process_kill_server(int),
00087   process_store_file(int),
00088 #ifdef GS_SMART_GRIDSOLVE
00089   process_smart_store_arg_to_memory(int sock),
00090   process_smart_delete_arg_from_memory(int sock),
00091   process_smart_recv_arg_from_memory(int sock),
00092   process_smart_store_arg_to_file(int sock),
00093   process_smart_delete_arg_from_file(int sock),
00094 #endif
00095   process_ping(int);
00096 
00097 
00098 /*****************************************************************/
00099 /* process the request for direct data ttransfer between servers */
00100 /* ------------- for GridSolve request sequencing ---------------*/
00101 /*****************************************************************/
00102 static int process_data_transfer_request(int sock);
00103 /* end and done */
00104 
00105 
00106 
00107 
00116 #ifdef GS_SMART_GRIDSOLVE
00117 
00118 int 
00119 gs_smart_server_process_message(gs_server_t *gs_server, int sock, int tag)
00120 {
00121   int retval = -1;
00122   switch(tag) {
00123     case GS_PROT_PROBLEM_SOLVE:
00124     case GS_PROT_PROBLEM_SOLVE_ASSIGNED:
00125       retval = process_problem_solve(gs_server, tag, sock);
00126       break;
00127     case GS_PROT_PROBE_REQUEST:
00128       retval = process_probe_request(sock);
00129       break;
00130     case GS_PROT_KILL_JOB:
00131       retval = process_cancel_request(sock);
00132       break;
00133     case GS_PROT_AWAIT_COMPLETION:
00134       retval = process_await_completion(sock);
00135       break;
00136     case GS_PROT_KILL_SERVER:
00137       retval = process_kill_server(sock);
00138       break;
00139     case GS_PROT_PROBLEM_EXAMPLE:
00140       retval = process_problem_example(sock);
00141       break;
00142     case GS_PROT_PING:
00143       retval = process_ping(sock);
00144       break;
00145     case GS_PROT_STORE_FILE:
00146       retval = process_store_file(sock);
00147       break;
00148     case GS_SMART_STORE_ARG_TO_FILE:
00149       retval = process_smart_store_arg_to_file(sock);
00150      break;
00151      case GS_SMART_RECV_ARG_FROM_MEMORY:
00152      retval = process_smart_recv_arg_from_memory(sock);
00153      break;
00154     default:
00155       LOGPRINTF("Unknown tag %d\n", tag);
00156       break;
00157   }
00158 
00159   /* to quiet a compiler warning: */
00160   return retval;
00161 }
00162 
00163 
00164 #endif
00165 
00166 
00167 
00168 
00169 
00170 
00180 int 
00181 gs_server_process_message(gs_server_t *gs_server, int sock)
00182 {
00183   char *version_str;
00184   int tag, retval;
00185 
00186   DBGPRINTF("Waiting for message on socket %d\n", sock);
00187 
00188   if(gs_recv_tag(sock, &tag) < 0) {
00189     ERRPRINTF("error reading tag\n");
00190     return -1;
00191   }
00192 
00193   if((gs_recv_string(sock, &version_str)) < 0) {
00194     ERRPRINTF("could not read version string\n");
00195     return -1;
00196   }
00197 
00198   if(gs_versions_incompatible(version_str, VERSION))
00199     retval = gs_send_tag(sock, GS_PROT_VERSION_MISMATCH);
00200   else
00201     retval = gs_send_tag(sock, GS_PROT_OK);
00202 
00203   free(version_str);
00204 
00205   if(retval < 0) {
00206     ERRPRINTF("could not send response tag.\n");
00207     return -1;
00208   }
00209   
00210   retval = -1;
00211 
00212   switch(tag) {
00213     case GS_PROT_PROBLEM_SOLVE:
00214     case GS_PROT_PROBLEM_SOLVE_ASSIGNED:
00215       retval = process_problem_solve(gs_server, tag, sock);
00216       break;
00217     case GS_PROT_PROBE_REQUEST:
00218       retval = process_probe_request(sock);
00219       break;
00220     case GS_PROT_KILL_JOB:
00221       retval = process_cancel_request(sock);
00222       break;
00223     case GS_PROT_AWAIT_COMPLETION:
00224       retval = process_await_completion(sock);
00225       break;
00226     case GS_PROT_KILL_SERVER:
00227       retval = process_kill_server(sock);
00228       break;
00229     case GS_PROT_PROBLEM_EXAMPLE:
00230       retval = process_problem_example(sock);
00231       break;
00232     case GS_PROT_PING:
00233       retval = process_ping(sock);
00234       break;
00235     case GS_PROT_STORE_FILE:
00236       retval = process_store_file(sock);
00237       break;
00238     case GS_PROT_DATA_TRANSFER:
00239       retval = process_data_transfer_request(sock);
00240       break;              
00241     default:
00242       LOGPRINTF("Unknown tag %d\n", tag);
00243       break;
00244   }
00245 
00246   /* to quiet a compiler warning: */
00247   return retval;
00248 }
00249 
00250 
00251 
00252 
00253 
00254 
00255 
00256 
00257 #ifdef GS_SMART_GRIDSOLVE
00258 
00259 
00260 
00266 int
00267 process_smart_store_arg_to_memory(int sock)
00268 {
00269 
00270 
00271   int  my_dsig = pvmgetdsig();
00272   gs_argument_t *arg;
00273   gs_argument_t *last_arg_ptr;
00274   int new_stored_arg_size;
00275   char * arg_file;
00276 
00277   int byte_size;
00278 
00279   /*
00280    * receive the size of incoming argument
00281    */ 
00282   if(gs_recv_int(sock, &byte_size)<0){
00283     ERRPRINTF("SMART : Error receiving byte size\n");
00284     return -1;
00285   } 
00286 
00287   /*
00288    * receive file name identifier of incoming argument
00289    */  
00290   if(gs_recv_string(sock,  &arg_file)<0){
00291     ERRPRINTF("SMART: Error receiving arg file loc\n");
00292     return -1;
00293   }
00294 
00295   /*
00296    * calculate the total size of store arguments if
00297    * incoming argument was stored
00298    */ 
00299   new_stored_arg_size=byte_size+total_bytes_stored;
00300 
00301   arg=(gs_argument_t *)calloc(1, sizeof(gs_argument_t ));
00302   arg->prob=(gs_problem_t *)calloc(1,sizeof(gs_problem_t));
00303 
00304 
00305    if(new_stored_arg_size>total_allowed_bytes){
00306      /*
00307       * if the buffer is full then send 
00308       * gs_smart_arg_buff_full tag back to service process.
00309       */ 
00310      if(gs_send_tag(sock, GS_SMART_ARG_BUFF_FULL) < 0){
00311        ERRPRINTF("Smart: Error sending tag\n");
00312        return -1;
00313      }
00314      /*
00315       * Save argument file name (but not its data)
00316       * and that its data location is a file.
00317       */ 
00318      arg->output_arg_file=arg_file;
00319      arg->arg_data_location=GS_SMART_ARG_STORED_IN_FILE;
00320  
00321     /*
00322      * Add the argument to the stored list of arguments.
00323      */ 
00324 
00325     if(stored_arg_list==NULL){
00326       stored_arg_list=arg;
00327       last_stored_arg=stored_arg_list;
00328     }  
00329     else{
00330       last_arg_ptr=last_stored_arg;
00331       last_arg_ptr->next=arg;
00332       last_stored_arg=last_arg_ptr->next;
00333     }
00334   }
00335   else{
00336     /*
00337      * If the buffer is full then send GS_PROT_OK 
00338      * tag back to service process.
00339      */ 
00340     if(gs_send_tag(sock, GS_PROT_OK) < 0){
00341       ERRPRINTF("Smart: Error sending tag\n");
00342       return -1;
00343     }
00344 
00345      /*
00346       * The args data location is specified to
00347       * be in server memory.
00348       */ 
00349     arg->arg_data_location=GS_SMART_ARG_STORED_IN_S_MEM;
00350 
00351    /*
00352     * Set total size of store arguments to its
00353     * new size
00354     */ 
00355     total_bytes_stored=new_stored_arg_size;
00356     //new_stored_arg_size=byte_size+total_bytes_stored;
00357 
00358     /*
00359      * Receive the argument and its data from service
00360      * process
00361      */ 
00362     if(gs_smart_recv_arg_remotely(sock, arg, my_dsig)<0){
00363       ERRPRINTF("SMART : Error receiving argument remotely\n");
00364       return -1;
00365     } 
00366 
00367     if(gs_send_tag(sock, GS_PROT_OK) < 0){
00368       ERRPRINTF("Smart: Error sending tag\n");
00369       return -1;
00370     }
00371    
00372     /*
00373      * Add incoming argument to stored argument list
00374      */  
00375  
00376     if(stored_arg_list==NULL){
00377       stored_arg_list=arg;
00378       last_stored_arg=stored_arg_list;
00379     }  
00380     else{
00381       last_arg_ptr=last_stored_arg;
00382       last_arg_ptr->next=arg;
00383       last_stored_arg=last_arg_ptr->next;
00384     }
00385   }
00386 
00387   return 0;
00388 }
00389 
00390 
00398 int
00399 gs_smart_get_arg_from_mem(char * arg_file, gs_argument_t ** arg, int * tag){
00400   gs_argument_t *argptr=NULL;
00401   for(argptr=stored_arg_list; argptr!=NULL; argptr=argptr->next){
00402     if(strcmp(argptr->output_arg_file, arg_file)==0){
00403       if(argptr->arg_data_location==GS_SMART_ARG_STORED_IN_FILE){
00404         *tag=GS_SMART_ARG_STORED_IN_FILE;
00405         return 0;
00406       }
00407 
00408       *arg=argptr;
00409       *tag=GS_SMART_ARG_STORED_IN_S_MEM;
00410       return 0;
00411     }
00412   }
00413   *tag=GS_SMART_ARG_NOT_READY;
00414   return 0;
00415 }
00416 
00417 
00422 int
00423 process_smart_recv_arg_from_memory(int sock)
00424 {
00425   gs_argument_t *arg=NULL;
00426   char * arg_file=NULL;
00427   int total_wait_time, wait_time;
00428   int  my_dsig = pvmgetdsig();
00429   int arg_tag;
00430    wait_time=0;
00431   total_wait_time=1;
00432 
00433   if(gs_recv_string(sock, &arg_file) < 0) {
00434     ERRPRINTF("Error recving file storage info.\n");
00435     return -1;
00436   }
00437   if(gs_smart_get_arg_from_mem(arg_file, &arg, &arg_tag)<0){
00438     ERRPRINTF("SMART : Error getting status of argument");
00439     return -1;
00440   }
00441 
00442   if(gs_send_tag(sock, arg_tag)<0){
00443       ERRPRINTF("SMART : Error sending tag\n");
00444       return -1;
00445   }
00446 
00447   if(arg_tag==GS_SMART_ARG_STORED_IN_S_MEM){
00448 
00449    /*
00450     * send the data signature of source server
00451     * in theory this is not needed because
00452     * the argument is always stored in the local
00453     * server process so the data signature 
00454     * is the same.
00455     */ 
00456     if(gs_send_int(sock, my_dsig)<0){
00457       ERRPRINTF("SMART : Error sending source server data signature\n");
00458       return -1;
00459     }
00460 
00461     if(gs_send_arg(sock, arg, my_dsig)<0){
00462       ERRPRINTF("SMART : Error sending arg\n");
00463       return -1;
00464      }
00465 
00466   } 
00467   return 0;
00468 }
00469 
00470 
00471 
00472 
00476 int
00477 process_smart_store_arg_to_file(int sock)
00478 {
00479   int  my_dsig = pvmgetdsig();
00480   gs_argument_t *arg;
00481   arg=(gs_argument_t *)calloc(1, sizeof(gs_argument_t ));
00482   arg->prob=(gs_problem_t *)calloc(1,sizeof(gs_problem_t));
00483 
00484   if(gs_send_tag(sock, GS_PROT_OK) < 0) {
00485     ERRPRINTF("Error sending confirmaton 1\n");
00486     return -1;
00487   }
00488   
00489  
00490   if(gs_smart_recv_arg_remotely(sock, arg, my_dsig)<0){
00491     ERRPRINTF("SMART : Error receiving argument remotely\n");
00492     return -1;
00493   } 
00494   /*
00495    * Sending server does not have to wait for file to
00496    * be writen therfore send back the GS_PROT_OK tag now
00497    */  
00498   if(gs_send_tag(sock, GS_PROT_OK) < 0){
00499     ERRPRINTF("Smart: Error sending tag\n");
00500     return -1;
00501   }
00502 
00503   if(gs_smart_write_arg_to_file(arg->output_arg_file, arg)<0){
00504     ERRPRINTF("SMART : Error writing arg to file\n");
00505     return -1;
00506   }
00507 
00508   if(arg->prob){
00509     free(arg->prob);
00510   }
00511   if(arg){
00512     int free_data=1;
00513     gs_smart_free_arg(arg, free_data);
00514 
00515   } 
00516  
00517  
00518 
00519   return 0;
00520 }
00521 
00522 
00529 int
00530 process_smart_delete_arg_from_memory(int sock)
00531 {
00532 
00533   char * arg_file=NULL;
00534   gs_argument_t *argptr=NULL;
00535   gs_argument_t *prev_argptr=NULL;
00536  
00537   if(gs_recv_string(sock, &arg_file) < 0) {
00538     ERRPRINTF("Error recving file storage info.\n");
00539     return -1;
00540   }
00541 
00542   if(gs_send_tag(sock, GS_PROT_OK) < 0){
00543     ERRPRINTF("Smart: Error sending tag\n");
00544     return -1;
00545   }
00546 
00547   int arg_cnt=0;
00548   gs_argument_t *next_argptr=NULL;
00549   for(argptr=stored_arg_list; argptr!=NULL; argptr=argptr->next){
00550     if(strcmp(argptr->output_arg_file, arg_file)==0){
00551       if(argptr){
00552         if(arg_cnt==0){
00553           next_argptr=stored_arg_list->next;
00554           int free_data=1;
00555           total_bytes_stored=total_bytes_stored-argptr->byte_size;
00556           if(gs_smart_free_arg(stored_arg_list, free_data)<0){
00557             ERRPRINTF("SMART : Error freeing argument from server buffer\n");
00558             return -1;
00559           }
00560           stored_arg_list=next_argptr;
00561           if(stored_arg_list==NULL){
00562             /*
00563              * no args left in buffer break 
00564              */ 
00565              break;
00566           }
00567           if(stored_arg_list->next==NULL){
00568             last_stored_arg=stored_arg_list;
00569           }
00570         }
00571         else{
00572           next_argptr=argptr->next;
00573           int free_data=1;
00574           total_bytes_stored=total_bytes_stored-argptr->byte_size;
00575           if(gs_smart_free_arg(argptr, free_data)<0){
00576             ERRPRINTF("SMART : Error freeing argument from server buffer\n");
00577             return -1;
00578           }
00579           prev_argptr->next=next_argptr;
00580           
00581           if(next_argptr==NULL){
00582             last_stored_arg=prev_argptr;
00583           }
00584         }
00585         break;
00586       }
00587     }
00588     arg_cnt++;
00589     prev_argptr=argptr;
00590   }
00591   return 0;
00592 }
00593 
00594 
00595 
00604 int
00605 process_smart_delete_arg_from_file(int sock)
00606 {
00607   char * arg_file=NULL;
00608   gs_argument_t *argptr=NULL;
00609   gs_argument_t *prev_argptr=NULL;
00610   if(gs_recv_string(sock, &arg_file) < 0) {
00611     ERRPRINTF("Error recving file storage info.\n");
00612     return -1;
00613   }
00614 
00615   if(gs_send_tag(sock, GS_PROT_OK) < 0){
00616     ERRPRINTF("Smart: Error sending tag\n");
00617     return -1;
00618   }
00619 
00620   int arg_cnt=0;
00621   gs_argument_t *next_argptr=NULL;
00622   for(argptr=stored_arg_list; argptr!=NULL; argptr=argptr->next){
00623     if(strcmp(argptr->output_arg_file, arg_file)==0){
00624       if(argptr){
00625         if(arg_cnt==0){
00626           next_argptr=stored_arg_list->next;
00627           int free_data=0;
00628           if(gs_smart_free_arg(stored_arg_list, free_data)<0){
00629             ERRPRINTF("SMART : Error freeing argument from server buffer\n");
00630             return -1;
00631           }
00632           stored_arg_list=next_argptr;
00633           if(stored_arg_list==NULL){
00634             /*
00635              * no args left in buffer break 
00636              */ 
00637              break;
00638           }
00639           if(stored_arg_list->next==NULL){
00640             last_stored_arg=stored_arg_list;
00641           }
00642         }
00643         else{
00644           next_argptr=argptr->next;
00645           int free_data=0;
00646           if(gs_smart_free_arg(argptr, free_data)<0){
00647             ERRPRINTF("SMART : Error freeing argument from server buffer\n");
00648             return -1;
00649           }
00650           prev_argptr->next=next_argptr;
00651           
00652           if(next_argptr==NULL){
00653             last_stored_arg=prev_argptr;
00654           }
00655         }
00656         break;
00657       }
00658     }
00659     arg_cnt++;
00660     prev_argptr=argptr;
00661   }
00662 
00663 
00664 /*  
00665   if(remove(argptr->input_arg_file)<0){
00666     ERRPRINTF("SMART : Error removing file %s\n", argptr->name);
00667     return -1;
00668   }
00669 */
00670   return 0;
00671 }
00672 
00673 
00674 #endif
00675 
00676 
00677 
00678 
00679 
00680 
00681 
00682 
00683 
00684 
00685 
00686 
00687 
00688 
00693 static int process_data_transfer_request(int sock) {
00694     char *request;
00695     LFS_DSI_OBJECT *obj;
00696     char *path, *file_name, *full_name;
00697 
00698     /* receive data transfer request */
00699     if (gs_recv_string(sock, &request) < 0) {
00700         ERRPRINTF("error receiving data transfer request\n");
00701         return -1;
00702     }
00703 
00704     /* decode the data transfer request */
00705     if ((obj = gs_seq_decode_lfs_dsi_object(request)) == NULL) {
00706         ERRPRINTF("bad data transfer request\n");
00707         return -1;
00708     }
00709 
00710     /* get path and name of the file storing the requested data */
00711     path = obj->path;
00712     file_name = obj->file_name;
00713 
00714     /* make sure the file path and name are ok */
00715     if (!path || !file_name) {
00716         ERRPRINTF("bad data file path or name\n");
00717         return -1;
00718     }
00719 
00720     /* construct the full path name */
00721     full_name = (char *) malloc(sizeof(char) * (strlen(path) + strlen(file_name) + 1));
00722     if (!full_name) {
00723         perror("malloc");
00724         return -1;
00725     }
00726 
00727     strcpy(full_name, path);
00728     full_name[strlen(path)] = '\0';
00729     
00730     strcat(full_name, file_name);
00731     full_name[strlen(path) + strlen(file_name)] = '\0';
00732 
00733     /* send data from the specified file to the requesting server */
00734     if (gs_send_arg_from_file(sock, full_name) < 0) {
00735         ERRPRINTF("error sending data from file\n");
00736         return -1;
00737     }
00738     
00739     return 0;
00740 }
00741 
00742 
00743 
00752 static int
00753 process_store_file(int sock)
00754 {
00755   char *msg = NULL;
00756 
00757   if(gs_recv_string(sock, &msg) < 0) {
00758     ERRPRINTF("Error recving file storage info.\n");
00759     return -1;
00760   }
00761 
00762   if(gs_recv_arg_into_file(sock, msg) < 0) {
00763     ERRPRINTF("saving to file '%s'.\n", msg);
00764     return -1;
00765   }
00766 
00767   return 0;
00768 }
00769 
00778 static int
00779 process_ping(int sock)
00780 {
00781   char *msg = NULL;
00782   int len = 0;
00783 
00784   if(gs_recv_int(sock, &len) < 0) {
00785     ERRPRINTF("Error recving ping len\n");
00786     return -1;
00787   }
00788 
00789   if((len < 1) || (len > GS_MAX_PING))
00790     return -1;
00791 
00792   msg = (char *)malloc(len);
00793 
00794   if(!msg)
00795     return -1;
00796 
00797   if(gs_tread(sock, msg, len) < 0) {
00798     ERRPRINTF("Error recving ping msg\n");
00799     return -1;
00800   }
00801 
00802   if(gs_twrite(sock, msg, len) < 0) {
00803     ERRPRINTF("Communication error.\n");
00804     if(msg) free(msg);
00805     return -1;
00806   }
00807 
00808   if(msg) free(msg);
00809 
00810   return 0;
00811 }
00812 
00821 static int
00822 process_problem_example(int sock)
00823 {
00824   char *msg, *example;
00825 
00826   if(gs_recv_string(sock, &msg) < 0) {
00827     ERRPRINTF("Error recving problem name\n");
00828     return -1;
00829   }
00830 
00831   example = dstring_sprintf("%s/service/%s/%s_grpc_example.c",
00832     gridsolve_root, msg, msg);
00833 
00834   if(!example) {
00835     ERRPRINTF("Failed to create example filename.\n");
00836     free(msg);
00837     return -1;
00838   }
00839   
00840   if(gs_send_arg_from_file(sock, example) < 0) {
00841     ERRPRINTF("Failed to send example code.\n");
00842     free(example);
00843     free(msg);
00844     return -1;
00845   }
00846 
00847   free(example);
00848   free(msg);
00849 
00850   return 0;
00851 }
00852 
00862 static int
00863 process_kill_server(int sock)
00864 {
00865   char *msg;
00866 
00867   DBGPRINTF("receiving password\n");
00868 
00869   if(gs_recv_string(sock,&msg) < 0) {
00870     ERRPRINTF("Error receiving password\n");
00871     return -1;
00872   }
00873   
00874   if(!strcmp(msg, "GridSolve")) {
00875     free(msg);
00876 
00877     if(gs_send_tag(sock, GS_PROT_OK) < 0) {
00878       ERRPRINTF("Error sending confirmaton\n");
00879       return -1;
00880     }
00881   }
00882   else {
00883     free(msg);
00884 
00885     if(gs_send_tag(sock, GS_PROT_ERROR) < 0) {
00886       ERRPRINTF("Error sending confirmaton\n");
00887       return -1;
00888     }
00889     return 0;
00890   }
00891 
00892   kill(getppid(), SIGTERM);
00893   return 0;
00894 }
00895 
00905 static int 
00906 process_await_completion(int sock)
00907 {
00908   char *request_id;
00909   struct stat stbuf;
00910   gs_problem_t *problem;
00911 
00912   if(gs_recv_string(sock, &request_id) < 0) {
00913     ERRPRINTF("gs_recv_string failed\n");
00914     return -1;
00915   }
00916 
00917   if(stat(request_id, &stbuf) == 0) {
00918     int fd, my_dsig = pvmgetdsig();
00919     char *filename;
00920 
00921     filename = (char *)malloc(strlen(request_id) + 13);
00922     if(!filename) {
00923       ERRPRINTF("malloc failed\n");
00924       return -1;
00925     }
00926 
00927     sprintf(filename, "%s/done", request_id);
00928 
00929     /* if the job is not finished */
00930     if(stat(filename, &stbuf) != 0) {
00931       int total_wait_time, wait_time, probe_status;
00932       char *err_filename;
00933 
00934       err_filename = (char *)malloc(strlen(request_id) + 13);
00935       if(!err_filename) {
00936         ERRPRINTF("malloc failed\n");
00937         return -1;
00938       }
00939 
00940       sprintf(err_filename, "%s/cancelled", request_id);
00941 
00942       wait_time = 1;
00943       total_wait_time = 0;
00944 
00945       do {
00946         sleep(wait_time);
00947         total_wait_time += wait_time;
00948         wait_time = total_wait_time/10 + 1;
00949         if(wait_time > GS_MAX_COMPLETION_POLL_FREQ) 
00950           wait_time = GS_MAX_COMPLETION_POLL_FREQ;
00951 
00952         /* look for "cancelled" file */
00953         if(stat(err_filename, &stbuf) == 0) {
00954           int err = GS_SVC_ERR_UNSPECIFIED;
00955           FILE *errfile;
00956 
00957           /* the service must have terminated abnormally.
00958            * look for an error file and read the code.
00959            */
00960           sprintf(err_filename, "%s/error", request_id);
00961 
00962           if((errfile = fopen(err_filename, "r")) != NULL) {
00963             fscanf(errfile, "%d", &err);
00964             fclose(errfile);
00965           }
00966 
00967           gs_send_tag(sock, err);
00968           free(request_id);
00969           free(filename);
00970           free(err_filename);
00971           return -1;
00972         }
00973 
00974         if(stat(request_id, &stbuf) != 0) {
00975           LOGPRINTF("Request directory was removed while waiting -- ");
00976           LOGPRINTF("the service probably terminated abnormally.\n");
00977 
00978           gs_send_tag(sock, GS_SVC_ERR_REQ_DIR_GONE);
00979           free(request_id);
00980           free(filename);
00981           free(err_filename);
00982           return -1;
00983         }
00984 
00985         probe_status = gs_probe_batch_request(request_id);
00986 
00987         if(probe_status == 2) {
00988           ERRPRINTF("Batch queue indicated that the job terminated abnormally.\n");
00989           gs_send_tag(sock, GS_SVC_ERR_UNSPECIFIED);
00990           free(request_id);
00991           free(filename);
00992           free(err_filename);
00993           return -1;
00994         }
00995         else if(probe_status == 1)
00996           break;
00997 
00998       } while(stat(filename, &stbuf) != 0);
00999 
01000       free(err_filename);
01001     }
01002 
01003     /* ok, at this point the job has completed and the
01004      * results are stored on disk.  we need to restore
01005      * them to the problem struct and send them back
01006      * to the client.  TODO: later it may be a good idea
01007      * to avoid writing to disk if wait is called before
01008      * the job completes.
01009      */
01010 
01011     if(chdir(request_id) < 0) {
01012       ERRPRINTF("Could not chdir to request dir '%s'\n", request_id);
01013       free(filename);
01014       return -1;
01015     }
01016 
01017     sprintf(filename, "data");
01018     if((fd = open(filename, O_RDONLY)) == -1) {
01019       free(request_id);
01020       free(filename);
01021       ERRPRINTF("failed to open output data\n");
01022       gs_send_tag(sock, GS_SVC_ERR_OPEN_DATA_FILE);
01023       return -1;
01024     }
01025 
01026     sprintf(filename, "problem.xml");
01027     problem = (gs_problem_t *)CALLOC(1, sizeof(gs_problem_t));
01028 
01029     if(!problem) {
01030       free(request_id);
01031       free(filename);
01032       ERRPRINTF("failed to malloc space for problem\n");
01033       gs_send_tag(sock, GS_SVC_ERR_MALLOC);
01034       return -1;
01035     }
01036 
01037     if(gs_read_problem_from_file(filename, problem) < 0) {
01038       gs_free_problem(problem);
01039       free(request_id);
01040       free(filename);
01041       ERRPRINTF("failed to get problem from '%s'\n", filename);
01042       gs_send_tag(sock, GS_SVC_ERR_READ_PROBLEM);
01043       return -1;
01044     }
01045 
01046 
01047 
01048 #ifdef GS_SMART_GRIDSOLVE
01049 
01050     gs_argument_t *argptr;
01051     for(argptr= problem->arglist;argptr!=NULL;argptr=argptr->next) {
01052       if(argptr->objecttype!=GS_SCALAR){
01053         if( (argptr->inout==GS_INOUT) || (argptr->inout==GS_OUT) ) {
01054           if(gs_recv_int(sock, &argptr->output_arg_sent_remotely) < 0) {
01055             ERRPRINTF("gs_recv output remote param\n");
01056             return -1;
01057           }
01058         }
01059       }
01060     }
01061   if(gs_smart_restore_output_args_from_file(fd, problem, my_dsig) < 0) {
01062     gs_free_problem(problem);
01063     free(request_id);
01064     free(filename);
01065     ERRPRINTF("failed to restore output data from disk\n");
01066     gs_send_tag(sock, GS_SVC_ERR_RESTORE_ARGS);
01067     return -1;
01068   }
01069 
01070 #else
01071 
01072 
01073     if(gs_restore_output_args_from_file(fd, problem, my_dsig) < 0) {
01074       gs_free_problem(problem);
01075       free(request_id);
01076       free(filename);
01077       ERRPRINTF("failed to restore output data from disk\n");
01078       gs_send_tag(sock, GS_SVC_ERR_RESTORE_ARGS);
01079       return -1;
01080     }
01081 #endif
01082 
01083     close(fd);
01084 
01085     if(gs_send_tag(sock, GS_PROT_OK) < 0) {
01086       free(request_id);
01087       free(filename);
01088       ERRPRINTF("gs_send_tag failed\n");
01089       return -1;
01090     }
01091 
01092 #ifdef GS_SMART_GRIDSOLVE
01093     if(gs_smart_send_output_args_to_client(sock, problem, my_dsig) < 0) {
01094       gs_free_problem(problem);
01095       free(request_id);
01096       free(filename);
01097       ERRPRINTF("failed to send output data to client\n");
01098       return -1;
01099     }
01100 #else
01101 
01102     if(gs_send_output_args(sock, problem, my_dsig) < 0) {
01103       gs_free_problem(problem);
01104       free(request_id);
01105       free(filename);
01106       ERRPRINTF("failed to send output data to client\n");
01107       return -1;
01108     }
01109 
01110 #endif
01111     gs_free_problem_and_data(problem);
01112 
01113     if(gs_create_timestamp_file(".", "retrieved", 0.0) < 0) {
01114       free(request_id);
01115       free(filename);
01116       ERRPRINTF("Could not create 'retrieved' file.\n");
01117       return -1;
01118     }
01119 
01120     free(filename);
01121   }
01122   else {
01123     /* no such request exists */
01124 
01125     if(gs_send_tag(sock, GS_SVC_ERR_UNKNOWN_REQ) < 0) {
01126       free(request_id);
01127       ERRPRINTF("gs_send_tag failed\n");
01128       return -1;
01129     }
01130   }
01131 
01132   free(request_id);
01133   gs_close_socket(sock);
01134   return 0;
01135 }
01136 
01152 static int
01153 gs_probe_batch_request(char *request_id)
01154 {
01155   gs_problem_t *problem;
01156   char buf[256], fname[256], *cmd;
01157   int status;
01158   FILE *f;
01159 
01160   sprintf(fname, "%s/gs_batch_id", request_id);
01161 
01162   if((f = fopen(fname, "r")) == NULL)
01163     return 3;
01164  
01165   /* don't treat as error... */
01166   if(!fgets(buf, 256, f))
01167     return 0;
01168 
01169   fclose(f);
01170 
01171   buf[strlen(buf)-1] = '\0';
01172 
01173   problem = (gs_problem_t *) malloc(sizeof(gs_problem_t));
01174 
01175   sprintf(fname, "%s/%s", request_id, GS_BATCH_XML);
01176 
01177   if(gs_read_problem_from_file(fname, problem) < 0) {
01178     ERRPRINTF("Error loading service: '%s'.\n", GS_BATCH_XML);
01179     return -1;
01180   }
01181 
01182   cmd = dstring_sprintf("%s/service/%s/gs_probe %s", gridsolve_root, 
01183     problem->name, buf);
01184 
01185   gs_free_problem(problem);
01186 
01187   if(!cmd) {
01188     ERRPRINTF("malloc");
01189     return -1;
01190   }
01191 
01192   status = system(cmd);
01193 
01194   if(status < 0) {
01195     ERRPRINTF("command failed: '%s'\n", cmd);
01196     return -1;
01197   }
01198 
01199   return WEXITSTATUS(status);
01200 }
01201 
01216 static int
01217 gs_cancel_batch_request(char *request_id)
01218 {
01219   gs_problem_t *problem;
01220   char buf[256], fname[256], *cmd;
01221   int status;
01222   FILE *f;
01223 
01224   sprintf(fname, "%s/gs_batch_id", request_id);
01225 
01226   if((f = fopen(fname, "r")) == NULL)
01227     return 3;
01228  
01229   /* don't treat as error */
01230   if(!fgets(buf, 256, f)) {
01231     ERRPRINTF("failed to read ID from file gs_batch_id\n");
01232     return -1;
01233   }
01234 
01235   fclose(f);
01236 
01237   buf[strlen(buf)-1] = '\0';
01238 
01239   problem = (gs_problem_t *) malloc(sizeof(gs_problem_t));
01240 
01241   sprintf(fname, "%s/%s", request_id, GS_BATCH_XML);
01242 
01243   if(gs_read_problem_from_file(fname, problem) < 0) {
01244     ERRPRINTF("Error loading service: '%s'.\n", GS_BATCH_XML);
01245     return -1;
01246   }
01247 
01248   cmd = dstring_sprintf("%s/service/%s/gs_cancel %s", gridsolve_root, 
01249     problem->name, buf);
01250 
01251   gs_free_problem(problem);
01252 
01253   if(!cmd) {
01254     ERRPRINTF("malloc");
01255     return -1;
01256   }
01257 
01258   status = system(cmd);
01259 
01260   if(status < 0) {
01261     ERRPRINTF("command failed: '%s'\n", cmd);
01262     return -1;
01263   }
01264 
01265   return WEXITSTATUS(status);
01266 }
01267 
01276 static int 
01277 process_probe_request(int sock)
01278 {
01279   char *request_id;
01280   struct stat stbuf;
01281   int probe_status, stat_rv;
01282 
01283   if(gs_recv_string(sock, &request_id) < 0) {
01284     ERRPRINTF("gs_recv_string failed\n");
01285     return -1;
01286   }
01287 
01288   if(stat(request_id, &stbuf) == 0) {
01289     char *filename;
01290 
01291     filename = (char *)malloc(strlen(request_id) + 13);
01292     if(!filename) {
01293       ERRPRINTF("malloc failed\n");
01294       return -1;
01295     }
01296 
01297     sprintf(filename, "%s/done", request_id);
01298 
01299     stat_rv = stat(filename, &stbuf);
01300 
01301     free(filename);
01302 
01303     if(stat_rv == 0) {
01304       /* the job is finished */
01305 
01306       free(request_id);
01307 
01308       if(gs_send_tag(sock, GS_PROT_OK) < 0) {
01309         ERRPRINTF("gs_send_tag failed\n");
01310         return -1;
01311       }
01312     }
01313     else {
01314       char *err_filename;
01315       int tag;
01316 
01317       err_filename = (char *)malloc(strlen(request_id) + 13);
01318       if(!err_filename) {
01319         ERRPRINTF("malloc failed\n");
01320         return -1;
01321       }
01322 
01323       sprintf(err_filename, "%s/cancelled", request_id);
01324 
01325       /* the request exists, but the job is not finished.
01326        * first check whether the service terminated
01327        * abnormally.
01328        */
01329 
01330       if(stat(err_filename, &stbuf) == 0) {
01331         int err = GS_SVC_ERR_UNSPECIFIED;
01332         FILE *errfile;
01333 
01334         /* the service didn't finish normally.
01335          * look for an error file and read the code.
01336          */
01337 
01338         sprintf(err_filename, "%s/error", request_id);
01339 
01340         if((errfile = fopen(err_filename, "r")) != NULL) {
01341           fscanf(errfile, "%d", &err);
01342           fclose(errfile);
01343         }
01344 
01345         gs_send_tag(sock, err);
01346 
01347         free(request_id);
01348         free(err_filename);
01349 
01350         return -1;
01351       }
01352 
01353       free(err_filename);
01354 
01355       probe_status = gs_probe_batch_request(request_id);
01356 
01357       free(request_id);
01358 
01359       switch(probe_status) {
01360         case 0:
01361           tag = GS_SVC_ERR_NOT_FINISHED;
01362           break;
01363         case 1:
01364           tag = GS_PROT_OK;
01365           break;
01366         case 3:
01367           tag = GS_SVC_ERR_NOT_FINISHED;
01368           break;
01369         default:
01370           tag = GS_SVC_ERR_UNSPECIFIED;
01371           break;
01372       }
01373 
01374       if(gs_send_tag(sock, tag) < 0) {
01375         ERRPRINTF("gs_send_tag failed\n");
01376         return -1;
01377       }
01378     }
01379   }
01380   else {
01381     /* no such request exists */
01382     free(request_id);
01383 
01384     if(gs_send_tag(sock, GS_SVC_ERR_UNKNOWN_REQ) < 0) {
01385       ERRPRINTF("gs_send_tag failed\n");
01386       return -1;
01387     }
01388   }
01389 
01390   gs_close_socket(sock);
01391   return 0;
01392 }
01393 
01402 static int 
01403 process_cancel_request(int sock)
01404 {
01405   int tag, cancel_status;
01406   char *request_id;
01407   struct stat stbuf;
01408 
01409   if(gs_recv_string(sock, &request_id) < 0) {
01410     ERRPRINTF("gs_recv_string failed\n");
01411     return -1;
01412   }
01413 
01414   cancel_status = gs_cancel_batch_request(request_id);
01415 
01416   switch(cancel_status) {
01417     case -1:
01418       ERRPRINTF("Internal error in gs_cancel_batch_request().\n");
01419       free(request_id);
01420       return -1;
01421 
01422     case 0:
01423       /* good, we cancelled the job */
01424       if(gs_send_tag(sock, GS_PROT_OK) < 0) {
01425         free(request_id);
01426         ERRPRINTF("gs_send_tag failed\n");
01427         return -1;
01428       }
01429 
01430       if(gs_create_timestamp_file(request_id, "cancelled", 0.0) < 0)
01431         ERRPRINTF("Could not create 'cancelled' file.\n");
01432 
01433       free(request_id);
01434       gs_close_socket(sock);
01435       return 0;
01436     case 1:
01437       ERRPRINTF("Failed to cancel the job via the batch system.\n");
01438       if(gs_send_tag(sock, GS_SVC_ERR_CANT_KILL) < 0) {
01439         free(request_id);
01440         ERRPRINTF("gs_send_tag failed\n");
01441         return -1;
01442       }
01443       free(request_id);
01444       gs_close_socket(sock);
01445       return 0;
01446     case 3:
01447       /* this isn't a batch job, so fall through to the normal code below */
01448       break;
01449     default:
01450       ERRPRINTF("Unexpected return value from gs_cancel_batch_request()\n");
01451       break;
01452   }
01453 
01454   if(stat(request_id, &stbuf) == 0) {
01455     char *filename;
01456     int stat_rv;
01457 
01458     filename = (char *)malloc(strlen(request_id) + 6);
01459     if(!filename) {
01460       ERRPRINTF("malloc failed\n");
01461       return -1;
01462     }
01463 
01464     sprintf(filename, "%s/done", request_id);
01465 
01466     stat_rv = stat(filename, &stbuf);
01467 
01468     free(filename);
01469 
01470     if(stat_rv == 0) {
01471       /* the job has already finished..  we didn't have to kill it, but 
01472        * we'll go ahead and return "KILLED" anyway.
01473        */
01474 
01475       if(gs_send_tag(sock, GS_PROT_OK) < 0) {
01476         free(request_id);
01477         ERRPRINTF("gs_send_tag failed\n");
01478         return -1;
01479       }
01480     }
01481     else {
01482       /* the job is not finished.  kill it. */
01483       int pid;
01484 
01485       if((pid = gs_parse_pid_from_requestid(request_id)) < 0) {
01486         free(request_id);
01487         ERRPRINTF("Failed to parse pid from request ID\n");
01488         gs_send_tag(sock, GS_SVC_ERR_INVALID_PID);
01489         return -1;
01490       }
01491 
01492       if(kill(pid, SIGTERM) < 0)
01493         tag = GS_SVC_ERR_CANT_KILL;
01494       else
01495         tag = GS_PROT_OK;
01496 
01497       if(gs_send_tag(sock, tag) < 0) {
01498         free(request_id);
01499         ERRPRINTF("gs_send_tag failed\n");
01500         return -1;
01501       }
01502 
01503       /* we went ahead and sent the response to the client to
01504        * give it the opportunity for a quick return, but we
01505        * just want to wait here to give the process a chance
01506        * to clean itself up and then we'll send the SIGKILL to
01507        * make sure it's dead.
01508        */
01509 
01510       sleep(10);
01511       kill(pid, SIGKILL);
01512     }
01513 
01514     if(gs_create_timestamp_file(request_id, "cancelled", 0.0) < 0)
01515       ERRPRINTF("Could not create 'cancelled' file.\n");
01516   }
01517   else {
01518     /* no such request exists */
01519 
01520     if(gs_send_tag(sock, GS_SVC_ERR_UNKNOWN_REQ) < 0) {
01521       ERRPRINTF("gs_send_tag failed\n");
01522       return -1;
01523     }
01524   }
01525 
01526   free(request_id);
01527   gs_close_socket(sock);
01528   return 0;
01529 }
01530 
01543 int
01544 gs_server_check_job_restriction(void *gs_server, gs_restriction_t *rest,
01545   char *msg, int *rtag)
01546 {
01547   int jcount;
01548 
01549   if(gs_get_job_count(GS_SERVER_JOB_COUNT_FILE, &jcount) < 0)
01550     return -1;
01551 
01552   if(jcount >= rest->restriction.job_restriction.max_jobs)
01553     *rtag = GS_SVC_ERR_RESTRICT_JOBS;
01554   else
01555     *rtag = GS_PROT_OK;
01556 
01557   return 0;
01558 }
01559 
01572 int
01573 gs_server_check_time_restriction(void *gs_server, gs_restriction_t *rest,
01574   char *msg, int *rtag)
01575 {
01576   struct tm *start, *end;
01577 
01578   start = &(rest->restriction.time_restriction.start);
01579   end = &(rest->restriction.time_restriction.end);
01580 
01581   if(!gs_is_current_time_in_range(start, end)) {
01582     LOGPRINTF("Rejecting job due to time restriction.\n");
01583     *rtag = GS_SVC_ERR_RESTRICT_TIME;
01584     return 0;
01585   }
01586 
01587   *rtag = GS_PROT_OK;
01588   return 0;
01589 }
01590 
01603 int
01604 gs_server_check_restrictions(gs_server_t *gs_server, char *msg, int *rtag)
01605 {
01606   gs_restriction_t *rp;
01607 
01608   for(rp = gs_server->restrictions; rp; rp = rp->next) {
01609     if(rp->check_func(gs_server, rp, msg, rtag) < 0)
01610       return -1;
01611 
01612     if(*rtag != GS_PROT_OK)
01613       return 0;
01614   }
01615 
01616   *rtag = GS_PROT_OK;
01617   return 0;
01618 }
01619 
01629 static int 
01630 process_problem_solve(gs_server_t *gs_server, int tag, int sock)
01631 {
01632   char *problem_name, *service_exe, *msg, **args,
01633     *user_name, *host_name, *client_cid, srv_cid[CID_LEN*2+1];
01634   int rtag, blocking_tag, client_dsig, blocking=1, saw_bad_tag = 0,
01635     agent_taskid;
01636   double agent_est_time;
01637 
01638   if(!gs_server)
01639     return -1;
01640 
01641   proxy_cid_to_str(srv_cid, gs_server->componentid);
01642 
01643   if(gs_recv_tag(sock, &blocking_tag) < 0) {
01644     ERRPRINTF("gs_recv_tag failed\n");
01645     return -1;
01646   }
01647 
01648   switch(blocking_tag) {
01649     case GS_PROT_BLOCKING:
01650       blocking = 1;
01651       break;
01652     case GS_PROT_NONBLOCKING:
01653       blocking = 0;
01654       break;
01655     default:
01656       fprintf(stderr,"Invalid blocking tag specified: %d\n", blocking_tag);
01657       saw_bad_tag = 1;
01658   }
01659 
01660   if(gs_recv_string(sock, &msg) < 0) {
01661     ERRPRINTF("gs_recv_string failed\n");
01662     return -1;
01663   }
01664 
01665   if(saw_bad_tag) {
01666     gs_send_tag(sock, GS_SVC_ERR_BAD_NB_TAG);
01667     free(msg);
01668     return -1;
01669   }
01670 
01671   rtag = GS_PROT_OK;
01672   if(gs_server_check_restrictions(gs_server, msg, &rtag) < 0)
01673     ERRPRINTF("Warning: failed to check server restrictions\n");
01674 
01675   if(rtag != GS_PROT_OK) {
01676     LOGPRINTF("Job rejected due to server restriction(s)\n");
01677     gs_send_tag(sock, rtag);
01678     return -1;
01679   }
01680 
01681   DBGPRINTF("msg = '%s'\n", msg);
01682 
01683   problem_name = (char *)malloc(strlen(msg));
01684   user_name = (char *)malloc(strlen(msg));
01685   host_name = (char *)malloc(strlen(msg));
01686   client_cid = (char *)malloc(strlen(msg));
01687 
01688   if(!problem_name || !user_name || !host_name || !client_cid) {
01689     ERRPRINTF("Failed to allocate memory.\n");
01690     return -1;
01691   }
01692 
01693   if(gs_decode_problem_solve_request(msg, &problem_name, &user_name, 
01694      &host_name, &client_cid, &client_dsig, &agent_taskid,
01695      &agent_est_time) < 0) 
01696   {
01697     free(problem_name);
01698     free(user_name);
01699     free(host_name);
01700     free(client_cid);
01701     ERRPRINTF("failed to decode request\n");
01702     return -1;
01703   }
01704 
01705   DBGPRINTF("problem_name = '%s'\n", problem_name);
01706 
01707   service_exe = dstring_sprintf("%s/service/%s/%s_service",gridsolve_root,
01708     problem_name, problem_name);
01709 
01710   if(!service_exe) {
01711     free(problem_name);
01712     free(user_name);
01713     free(host_name);
01714     free(client_cid);
01715     ERRPRINTF("Failure generating name of service executable.\n");
01716     return -1;
01717   }
01718 
01719   args = (char **)calloc(18, sizeof(char *));
01720 
01721   if(!args) {
01722     free(service_exe);
01723     free(problem_name);
01724     free(user_name);
01725     free(host_name);
01726     free(client_cid);
01727     ERRPRINTF("Failure allocating space for args.\n");
01728     return -1;
01729   }
01730 
01731   LOGPRINTF("Problem Solve: '%s' %s@%s (%s) %s\n", problem_name, user_name,
01732     host_name, blocking ? "blocking" : "non-blocking",
01733     tag == GS_PROT_PROBLEM_SOLVE_ASSIGNED ? "[assigned server request]" : "");
01734 
01735   args[0] = dstring_sprintf("%s_service", problem_name);
01736   args[1] = dstring_sprintf("%s", problem_name);
01737   args[2] = dstring_sprintf("%d", tag);
01738   args[3] = dstring_sprintf("%d", client_dsig);
01739   args[4] = dstring_sprintf("%d", sock);
01740   args[5] = gridsolve_root;
01741   args[6] = gridsolve_arch;
01742   args[7] = dstring_sprintf("%d", blocking);
01743   args[8] = dstring_sprintf("%s", gs_server->agenthost);
01744   args[9] = dstring_sprintf("%d", gs_server->agentport);
01745   args[10] = dstring_sprintf("%s", srv_cid);
01746   args[11] = dstring_sprintf("%s", user_name);
01747   args[12] = dstring_sprintf("%s", host_name);
01748   args[13] = dstring_sprintf("%s", client_cid);
01749   args[14] = dstring_sprintf("%s", gs_server->infodir ? gs_server->infodir : "-");
01750   args[15] = dstring_sprintf("%d", agent_taskid);
01751   args[16] = dstring_sprintf("%lf", agent_est_time);
01752   args[17] = NULL;
01753 
01754   if(execv(service_exe, args) < 0) {
01755     if(gs_send_tag(sock, GS_SVC_ERR_EXEC) < 0)
01756       ERRPRINTF("Error sending GS_SVC_ERR_EXEC\n");
01757     free(service_exe);
01758     free(problem_name);
01759     free(user_name);
01760     free(host_name);
01761     free(client_cid);
01762     return -1;
01763   }
01764 
01765   /* should not reach here */
01766   return 0;
01767 }
01768 
01779 int 
01780 gs_server_listen_and_process_messages(gs_server_t *gs_server, int srvsock)
01781 {
01782   int sock;
01783 
01784   DBGPRINTF("Entering\n");
01785 
01786   /* Recv and process connections */
01787   for (;;) {
01788     pid_t pid;
01789 
01790     DBGPRINTF("Waiting for a connection\n");
01791 
01792     /* if accept fails, go back to while loop */
01793     if((sock = gs_accept_connection(srvsock)) == -1) {
01794       ERRPRINTF("Failed to accept connection on socket, return to listening\n");
01795       continue;
01796     }
01797 
01798 
01799 #ifdef GS_SMART_GRIDSOLVE
01800 
01801   int tag;
01802   char *version_str;
01803   int  retval;
01804   int recv_transaction=0;
01805   if(gs_recv_tag(sock, &tag) < 0) {
01806     ERRPRINTF("error reading tag\n");
01807     return -1;
01808   }
01809 
01810   DBGPRINTF("Waiting for message on socket %d\n", sock);
01811 
01812   if((tag!= GS_SMART_STORE_ARG_TO_FILE) && 
01813     (tag!= GS_SMART_STORE_ARG_TO_MEMORY) &&
01814     (tag!= GS_SMART_RECV_ARG_FROM_MEMORY) &&
01815     (tag!= GS_SMART_DELETE_ARG_FROM_FILE) &&
01816      (tag!=GS_SMART_DELETE_ARG_FROM_MEMORY)){
01817     if((gs_recv_string(sock, &version_str)) < 0) {
01818       ERRPRINTF("could not read version string\n");
01819       return -1;
01820     }
01821     if(gs_versions_incompatible(version_str, VERSION))
01822       retval = gs_send_tag(sock, GS_PROT_VERSION_MISMATCH);
01823     else
01824      retval = gs_send_tag(sock, GS_PROT_OK);
01825 
01826      free(version_str);
01827    } 
01828    else{
01829      retval=0;
01830    }
01831    if(retval==-1){
01832      ERRPRINTF("SMART : Version error problem\n");
01833      return -1;
01834    } 
01835    if(tag==GS_SMART_DELETE_ARG_FROM_MEMORY){
01836      retval = process_smart_delete_arg_from_memory(sock);
01837      recv_transaction=1;
01838    }
01839    if(tag==GS_SMART_STORE_ARG_TO_MEMORY){
01840      retval = process_smart_store_arg_to_memory(sock);
01841       recv_transaction=1;
01842    }
01843    if(tag==GS_SMART_DELETE_ARG_FROM_FILE){
01844      retval = process_smart_delete_arg_from_file(sock);
01845      recv_transaction=1;
01846    }
01847 
01848 #endif
01849 
01850 
01851 
01852 
01853 
01854 
01855     pid = fork();
01856 
01857     switch(pid) {
01858       case -1:     /* error */
01859         ERRPRINTF("Failed to fork\n");
01860         continue;
01861       case 0:      /* child */
01862         gs_close_socket(srvsock);
01863 #ifdef GS_SMART_GRIDSOLVE 
01864        if(recv_transaction==0){
01865           gs_smart_server_process_message(gs_server, sock, tag);
01866         }
01867 #else
01868         gs_server_process_message(gs_server, sock);
01869 #endif
01870         _exit(0);
01871       default:     /* parent */
01872         gs_close_socket(sock);
01873     }
01874     
01875     fflush(stderr);
01876     fflush(stdout);
01877   }
01878 
01879   /* should not reach here */
01880   return 0;
01881 }
01882 
01893 int
01894 gs_find_coefficient_files(gs_server_t *server, icl_list_t *cfiles)
01895 {
01896   int i, globflags;
01897   char *globpattern;
01898   glob_t *pglob;
01899 
01900   if(!cfiles || !server)
01901     return -1;
01902 
01903   if(!server->infodir)
01904     return 0;
01905 
01906   /* glob the info directory to find coefficient files  */
01907 
01908   globflags = GLOB_NOSORT;
01909   globpattern = dstring_sprintf("%s/*.coe", server->infodir);
01910 
01911   if(!globpattern)
01912     return -1;
01913 
01914   pglob = (glob_t*)MALLOC(sizeof(glob_t));
01915 
01916   if(!pglob) {
01917     free(globpattern);
01918     return -1;
01919   }
01920 
01921   /* Glob for files */
01922   if((i=glob(globpattern, globflags,  NULL, pglob)) != 0) {
01923     free(globpattern);
01924     globfree(pglob);
01925     free(pglob);
01926     return 0;
01927   }
01928  
01929   free(globpattern);
01930  
01931   /* For each file containing a problem description */
01932   for (i=0; i < pglob->gl_pathc; i++)
01933     icl_list_append(cfiles, strdup(pglob->gl_pathv[i]));
01934 
01935   globfree(pglob);
01936   free(pglob);
01937 
01938   return 0;
01939 }
01940 
01951 int
01952 gs_find_service_directories(icl_list_t *services, int *count)
01953 {
01954   int i, globflags;
01955   char *globpattern;
01956   glob_t *pglob;
01957 
01958   *count = 0;
01959 
01960   if(!services)
01961     return -1;
01962 
01963   DBGPRINTF("Entering\n");
01964 
01965   /* glob the services directory to find services  */
01966 
01967   globflags = GLOB_NOSORT;
01968   globpattern = dstring_sprintf("%s/service/*/*.xml",
01969     gridsolve_root);
01970 
01971   if(!globpattern)
01972     return -1;
01973 
01974   pglob = (glob_t*)MALLOC(sizeof(glob_t));
01975 
01976   if(!pglob) {
01977     free(globpattern);
01978     return -1;
01979   }
01980 
01981   /* Glob for files */
01982   if((i=glob(globpattern, globflags,  NULL, pglob)) != 0) {
01983     ERRPRINTF("No problems or services found using path: %s\n ", globpattern);
01984     ERRPRINTF("\t glob returned %d\n", i);
01985     free(globpattern);
01986     globfree(pglob);
01987     free(pglob);
01988     return -1;
01989   }
01990  
01991   free(globpattern);
01992  
01993   /* For each file containing a problem description */
01994   for (i=0; i < pglob->gl_pathc; i++) {
01995     icl_list_append(services, strdup(pglob->gl_pathv[i]));
01996     (*count)++;
01997   }
01998 
01999   globfree(pglob);
02000   free(pglob);
02001 
02002   return 0;
02003 }
02004 
02005 char *
02006 gs_get_service_name_from_path(char *data)
02007 {
02008   char *tok, *prevtok, *path;
02009 
02010   if(!data) return NULL;
02011 
02012   tok = strchr(data, '/');
02013 
02014   if(tok) {
02015     do {
02016       tok++;
02017       prevtok = tok;
02018     } while((tok = strchr(tok, '/')));
02019   }
02020   else
02021     prevtok = data;
02022 
02023   path = strdup(prevtok);
02024 
02025   if(!path) return NULL;
02026 
02027   tok = strchr(path, '.');
02028 
02029   if(!tok) {
02030     free(path);
02031     return NULL;
02032   }
02033 
02034   *tok = 0;
02035 
02036   return path;
02037 }
02038 
02039 int
02040 gs_server_prepare_model_update_message(int sock, gs_server_t *gs_server, gs_problem_t *problem,
02041   char **msg)
02042 {
02043   char *pfile, *expr;
02044 
02045   if(!gs_server || !problem)
02046     return -1;
02047 
02048   if(!gs_server->infodir)
02049     return -1;
02050 
02051   if(!strcmp(gs_server->infodir, "-"))
02052     return -1;
02053 
02054   pfile = dstring_sprintf("%s/%s.coe", gs_server->infodir, problem->name);
02055 
02056   if(!pfile)
02057     return -1;
02058 
02059   if(gs_get_contents_of_file(pfile, &expr) < 0)
02060     return -1;
02061 
02062   *msg = expr;
02063 
02064   return 0;
02065 }
02066 
02079 int 
02080 gs_server_register_problems(gs_server_t *gs_server)     
02081 {
02082   int i, count, sock_agent, reply_tag, problem_already_exists, total_services;
02083   char *problemstring, temp_cid[CID_LEN*2+1], **model_msg;
02084   gs_problem_t *problem, *pp, *prev;
02085   icl_list_t *services, *l;
02086 
02087   DBGPRINTF("Entering\n");
02088 
02089   services = icl_list_new();
02090   total_services = 0;
02091 
02092   if(!services)
02093     return -1;
02094   
02095   if(gs_find_service_directories(services, &total_services) < 0)
02096     ERRPRINTF("Warning: no services found.\n");
02097 
02098   model_msg = NULL;
02099 
02100   if(total_services > 0) {
02101     model_msg = (char **)malloc(total_services * sizeof(char *));
02102     if(!model_msg) {
02103       ERRPRINTF("malloc failed.\n");
02104       goto error_registering_problems;
02105     }
02106   }
02107 
02108   proxy_cid_to_str(temp_cid, gs_server->componentid);
02109 
02110   sock_agent = gs_connect_direct(gs_server->agenthost, gs_server->agentport);
02111 
02112   if(sock_agent < 0) {
02113     ERRPRINTF("Unable to connect to agent.\n");
02114     goto error_registering_problems;
02115   }
02116 
02117   if((gs_send_tag(sock_agent, GS_PROT_PROBLEM_REGISTER) < 0) ||
02118      (gs_send_string(sock_agent, VERSION) < 0))
02119   {
02120     ERRPRINTF("Error communicating with agent.\n");
02121     gs_close_socket(sock_agent);
02122     goto error_registering_problems;
02123   }
02124 
02125   if(gs_recv_tag(sock_agent, &reply_tag) < 0) {
02126     ERRPRINTF("Error communicating with agent.\n");
02127     gs_close_socket(sock_agent);
02128     goto error_registering_problems;
02129   }
02130 
02131   if(reply_tag != GS_PROT_OK) {
02132     if(reply_tag == GS_PROT_VERSION_MISMATCH) 
02133       ERRPRINTF("Agent refused this incompatible version of GridSolve\n");
02134     else
02135       ERRPRINTF("Error code %d: Could not register problem\n", reply_tag);
02136     gs_close_socket(sock_agent);
02137     goto error_registering_problems;
02138   }    
02139 
02140   if((gs_send_string(sock_agent, temp_cid) < 0) ||
02141      (gs_send_int(sock_agent, total_services) < 0)) {
02142     ERRPRINTF("Error communicating with agent.\n");
02143     gs_close_socket(sock_agent);
02144     goto error_registering_problems;
02145   }
02146 
02147   i = 0;
02148   for (l=icl_list_first(services); l!=NULL; l=icl_list_next(services, l)) {
02149     char *path = (char *)l->data;
02150 
02151     /* For each problem description file, find size and slurp it into 
02152      * an allocated buffer  
02153      */
02154 
02155     problem = (gs_problem_t *)CALLOC(1, sizeof(gs_problem_t));
02156 
02157     if(!problem) {
02158       ERRPRINTF("Couldn't allocate memory for problem\n");
02159       goto error_registering_problems;
02160     }
02161 
02162     if(gs_read_problem_from_file(path, problem) < 0) {
02163       ERRPRINTF("failed to get problem from '%s'\n", path);
02164       continue;
02165     }
02166 
02167     /* add problem to the end of the problemlist if it does not exist */
02168     problem_already_exists=0;
02169 
02170     for(prev=pp=gs_server->problemlist; pp; pp=pp->next) {
02171       if(strcmp(pp->name,problem->name) == 0) { 
02172     problem_already_exists = 1;
02173     break;
02174       }
02175       prev = pp;
02176     }
02177 
02178     if(problem_already_exists) {
02179       char *pstr1, *pstr2;
02180       int diff;
02181 
02182       pstr1 = pstr2 = NULL;
02183 
02184       if((gs_encode_problem(&pstr1, problem) < 0) ||
02185          (gs_encode_problem(&pstr2, pp) < 0)) {
02186         if(pstr1) free(pstr1);
02187         if(pstr2) free(pstr2);
02188         continue;
02189       }
02190 
02191       diff = strcmp(pstr1, pstr2);
02192 
02193       free(pstr1);
02194       free(pstr2);
02195      
02196       if(!diff) {
02197         gs_free_problem(problem);
02198         continue;
02199       }
02200 
02201       LOGPRINTF("Problem %s has been changed.\n", problem->name);
02202 
02203       /* remove the problem from the server's problem list and 
02204        * fall through to the problem registration below.
02205        */
02206       if(pp == gs_server->problemlist)
02207         gs_server->problemlist = pp->next;
02208       else
02209         prev->next = pp->next;
02210 
02211       gs_server->nproblems--;
02212 
02213       pp->next = NULL;
02214       gs_free_problem(pp);
02215     }
02216 
02217     LOGPRINTF("Registering new service %s\n", path);
02218 
02219     if(gs_server->problemlist == NULL) 
02220       gs_server->problemlist = problem;
02221     else {
02222       problem->next = gs_server->problemlist;
02223       gs_server->problemlist = problem;
02224     }
02225 
02226     gs_server->nproblems++;
02227 
02228     if(gs_encode_problem(&problemstring, problem) < 0) {
02229       ERRPRINTF("Failed to encode problem.\n");
02230       goto error_registering_problems;
02231     }
02232 
02233     /* Register problem at agent */
02234     if(gs_send_string(sock_agent, problemstring) < 0) {
02235       gs_close_socket(sock_agent);
02236       FREE(problemstring);
02237       ERRPRINTF("Error communicating with agent.\n");
02238       goto error_registering_problems;
02239     }
02240 
02241     if(gs_server_prepare_model_update_message(sock_agent, gs_server, problem, &model_msg[i]) < 0)
02242       model_msg[i] = strdup(GS_NO_MODEL_UPDATE);
02243     i++;
02244   }
02245 
02246   if(gs_send_string(sock_agent, GS_END_PROB_REG) < 0) {
02247     ERRPRINTF("Error communicating with agent.\n");
02248     gs_close_socket(sock_agent);
02249     goto error_registering_problems;
02250   }
02251 
02252   count = i;
02253 
02254   for(i=0;i<count;i++) {
02255     if(model_msg && model_msg[i]) {
02256       if(gs_send_string(sock_agent, model_msg[i]) < 0) {
02257         ERRPRINTF("Error communicating with agent.\n");
02258         gs_close_socket(sock_agent);
02259         goto error_registering_problems;
02260       }
02261     }
02262   }
02263 
02264   if(gs_send_string(sock_agent, GS_END_PROB_REG) < 0) {
02265     ERRPRINTF("Error communicating with agent.\n");
02266     gs_close_socket(sock_agent);
02267     goto error_registering_problems;
02268   }
02269 
02270   /* look for removed services */
02271   for(prev=pp=gs_server->problemlist; pp; pp=pp->next) {
02272     int service_found;
02273     char *sname;
02274 
02275     service_found = 0;
02276 
02277     for(l=icl_list_first(services); l!=NULL; l=icl_list_next(services, l)) {
02278       sname = gs_get_service_name_from_path((char*)l->data);
02279 
02280       if(!sname) continue;
02281 
02282       if(!strcmp(sname, pp->name)) {
02283         service_found = 1;
02284         free(sname);
02285         break;
02286       }
02287 
02288       free(sname);
02289     }
02290 
02291     if(!service_found) {
02292       if(gs_send_string(sock_agent, pp->name) < 0) {
02293         ERRPRINTF("Error communicating with agent.\n");
02294         gs_close_socket(sock_agent);
02295         goto error_registering_problems;
02296       }
02297 
02298       LOGPRINTF("Service '%s' was removed.. unregistering.\n", pp->name);
02299 
02300       if(pp == gs_server->problemlist)
02301         gs_server->problemlist = pp->next;
02302       else
02303         prev->next = pp->next;
02304 
02305       gs_server->nproblems--;
02306 
02307       pp->next = NULL;
02308       gs_free_problem(pp);
02309       pp = prev;
02310     }
02311 
02312     prev = pp;
02313   }
02314 
02315   if(gs_send_string(sock_agent, GS_END_PROB_REG) < 0) {
02316     ERRPRINTF("Error communicating with agent.\n");
02317     gs_close_socket(sock_agent);
02318     goto error_registering_problems;
02319   }
02320 
02321   if(gs_recv_tag(sock_agent, &reply_tag) < 0) {
02322     ERRPRINTF("Failed to recv tag.\n");
02323     goto error_registering_problems;
02324   }
02325 
02326   if (reply_tag != GS_PROT_OK) {
02327     ERRPRINTF("Could not register problems\n");
02328     goto error_registering_problems;
02329   }
02330 
02331   if(services) icl_list_destroy(services, free);
02332 
02333   /* disconnect from agent */
02334   gs_close_socket(sock_agent);
02335 
02336   return 0;
02337 
02338 error_registering_problems:
02339   if(services) icl_list_destroy(services, free);
02340   return -1;
02341 }
02342 
02351 int 
02352 gs_server_register(gs_server_t *gs_server)
02353 {
02354   int sock_agent, reply_tag;
02355   char *serverstr;
02356 
02357   sock_agent = gs_connect_direct(gs_server->agenthost, gs_server->agentport);
02358 
02359   if(sock_agent < 0) {
02360     ERRPRINTF("Could not connect to the agent\n");
02361     return -1;
02362   }
02363 
02364   /* upload server info to agent */
02365   if(gs_encode_server(&serverstr, gs_server) < 0) {
02366     ERRPRINTF("Failed to encode the server struct\n");
02367     return -1;
02368   }
02369 
02370   DBGPRINTF("serverstr: %s\n", serverstr);
02371 
02372   if((gs_send_tag(sock_agent, GS_PROT_SERVER_REGISTER) < 0) ||
02373      (gs_send_string(sock_agent, VERSION) < 0))
02374   {
02375     FREE(serverstr);
02376     ERRPRINTF("Error communicating with the agent.\n");
02377     return -1;
02378   }
02379   
02380   /* if reply not OK, check for more info */
02381   if(gs_recv_tag(sock_agent, &reply_tag) < 0) {
02382     FREE(serverstr);
02383     ERRPRINTF("Error communicating with the agent.\n");
02384     return -1;
02385   }
02386 
02387   if(reply_tag != GS_PROT_OK) {
02388     if(reply_tag == GS_PROT_VERSION_MISMATCH) 
02389       ERRPRINTF("Agent refused this incompatible version of GridSolve\n");
02390     else
02391       ERRPRINTF("Error code %d: Could not register server\n", reply_tag);
02392     FREE(serverstr);
02393     return -1;
02394   }    
02395 
02396   if(gs_send_string(sock_agent, serverstr) < 0) {
02397     ERRPRINTF("Error communicating with the agent.\n");
02398     FREE(serverstr);
02399     return -1;
02400   }
02401 
02402   FREE(serverstr);
02403 
02404   /* if reply not OK, check for more info */
02405   if(gs_recv_tag(sock_agent, &reply_tag) < 0) {
02406     ERRPRINTF("Error communicating with the agent.\n");
02407     return -1;
02408   }
02409 
02410   if(reply_tag != GS_PROT_OK) {
02411     ERRPRINTF("Error code %d: Could not register server\n", reply_tag);
02412     return -1;
02413   }    
02414   gs_close_socket(sock_agent);
02415 
02416   DBGPRINTF("returning\n");
02417   return 0;
02418 }
02419 
02430 int
02431 gs_server_add_restriction(gs_server_t *gs_server, char *type, char *value)
02432 {
02433   gs_restriction_t *new;
02434 
02435   if(!gs_server || !type || !value)
02436     return -1;
02437 
02438   new = (gs_restriction_t *)calloc(1, sizeof(gs_restriction_t));
02439 
02440   if(!new) return -1;
02441 
02442   if(!strcasecmp(type, "RESTRICT_JOBS")) {
02443     new->restriction_type = GS_JOB_RESTRICT;
02444     new->restriction.job_restriction.max_jobs = atoi(value);
02445     new->check_func = gs_server_check_job_restriction;
02446   }
02447   else if(!strcasecmp(type, "RESTRICT_TIME")) {
02448     struct tm *start, *end;
02449 
02450     new->restriction_type = GS_TIME_RESTRICT;
02451 
02452     start = &(new->restriction.time_restriction.start);
02453     end = &(new->restriction.time_restriction.end);
02454 
02455     if(gs_parse_time_range(value, start, end) < 0) {
02456       ERRPRINTF("Skipping time restriction '%s' ", value);
02457       ERRPRINTF("since the time(s) could not be parsed\n");
02458       free(new);
02459       return -1;
02460     }
02461 
02462     new->check_func = gs_server_check_time_restriction;
02463   }
02464   else {
02465     ERRPRINTF("Invalid restriction type '%s'\n", type);
02466     free(new);
02467     return -1;
02468   }
02469 
02470   new->next = gs_server->restrictions;
02471   gs_server->restrictions = new;
02472 
02473   return 0;
02474 }
02475 
02488 int
02489 gs_server_create_info_dir(gs_server_t *gs_server)
02490 {
02491   if(gs_create_info_dir(gs_server->componentid, gs_server->ipaddress,
02492        gs_server->port, &(gs_server->infodir)) < 0) {
02493     ERRPRINTF("Creating server infodir failed.\n");
02494     return -1;
02495   }
02496 
02497   return 0;
02498 }
02499 
02509 int
02510 gs_server_save_encoding(gs_server_t *server)
02511 {
02512   char *strp = NULL, *filename;
02513   FILE *sfile;
02514 
02515   filename = dstring_sprintf(GS_SERVER_XML_TEMPLATE, server->infodir);
02516 
02517   if(!filename)
02518     return -1;
02519 
02520   sfile = fopen(filename, "w");
02521 
02522   free(filename);
02523 
02524   if(!sfile) {
02525     ERRPRINTF("Could not create server xml file.\n");
02526     return -1;
02527   }
02528 
02529   if(gs_encode_server(&strp, server) < 0) {
02530     ERRPRINTF("Failed to encode the server struct\n");
02531     return -1;
02532   }
02533 
02534   fprintf(sfile, "%s\n", strp);
02535 
02536   fclose(sfile);
02537 
02538   if(strp) free(strp);
02539 
02540   return 0;
02541 }
02542 
02553 gs_server_t* 
02554 gs_server_init(char *server_config)
02555 {
02556   char *strp, *gs_agent_copy, *gs_agent_env, *gs_agent_cfg,
02557     *srv_port_env, *srv_port_cfg, *data_dir_env, *data_dir;
02558   gs_server_t *gs_server;
02559   pid_t pid;
02560 
02561   gridsolve_agent = gridsolve_root = gridsolve_arch = data_dir = NULL;
02562   gs_agent_env = gs_agent_cfg = srv_port_env = srv_port_cfg = NULL;
02563 
02564   gs_server = (gs_server_t*)CALLOC(1, sizeof(gs_server_t));
02565 
02566   if(!gs_server) {
02567     ERRPRINTF("Could not allocate memory.\n");
02568     return NULL;
02569   }
02570 
02571   gridsolve_root = getenv("GRIDSOLVE_ROOT");
02572   if(!gridsolve_root)
02573     gridsolve_root = GRIDSOLVE_TOP_BUILD_DIR;
02574 
02575   gridsolve_arch = getenv("GRIDSOLVE_ARCH");
02576   if(!gridsolve_arch)
02577     gridsolve_arch = GRIDSOLVE_ARCH_FROM_CONFIGURE;
02578 
02579   data_dir_env = getenv("GRIDSOLVE_DATA_DIR");
02580 
02581   /* if SMART_GRIDSOLVE enabled, make the default gs_server->smart setting 1 */
02582 #ifdef GS_SMART_GRIDSOLVE
02583   gs_server->smart = 1;
02584 
02585   struct stat stbuf;
02586   if(stat(smart_obj_file_dir, &stbuf) != 0) {
02587     if(mkdir(smart_obj_file_dir, 0700) < 0) {
02588       ERRPRINTF("Could not create directory '%s' ", smart_obj_file_dir);
02589       return NULL;
02590     }
02591   }
02592   total_bytes_stored=0;
02593   stored_arg_list=NULL;
02594   last_stored_arg=stored_arg_list;
02595 
02596 
02597 #endif
02598 
02599   /* Parse server config file */
02600 
02601   if(!server_config) {
02602     gs_server_free(gs_server);
02603     ERRPRINTF("Failed to generate server_config file name\n");
02604     return NULL;
02605   }
02606 
02607   if(gs_parse_config_file(server_config, &(gs_server->sa_list)) == 0) {
02608     if(gs_server->sa_list) {
02609       gs_info_t *p;
02610       int rlen;
02611 
02612       rlen = strlen("RESTRICT_");
02613 
02614       for(p = gs_server->sa_list; p != NULL; p = p->next) {
02615         if(!strcasecmp(p->type, "AGENT"))
02616           gs_agent_cfg = p->value;
02617         else if(!strcasecmp(p->type, "PORT"))
02618           srv_port_cfg = p->value;
02619         else if(!strcasecmp(p->type, "OUTPUT_TTL"))
02620           gs_server->output_ttl = atol(p->value);
02621         else if(!strncasecmp(p->type, "RESTRICT_", rlen))
02622           gs_server_add_restriction(gs_server, p->type, p->value);
02623         else if(!strcasecmp(p->type, "GRIDSOLVE_DATA_DIR"))
02624           data_dir = p->value;
02625         else if(!strcasecmp(p->type, "SMART_GRIDSOLVE"))
02626           gs_server->smart = atoi(p->value);
02627 #ifdef GS_SMART_GRIDSOLVE
02628         else if(!strcasecmp(p->type, "TOTAL_BYTES"))
02629           total_allowed_bytes = atoi(p->value);
02630 #endif
02631 
02632       }
02633     }
02634   }
02635 
02636   /* override config file setting if environment variable is set */
02637   if(data_dir_env)
02638     data_dir = data_dir_env;
02639 
02640   /* if SmartGridSolve wasn't enabled at configuration time, then 
02641    * make sure any setting parsed above is clobbered.
02642    */
02643 #ifndef GS_SMART_GRIDSOLVE
02644   gs_server->smart = 0;
02645 #endif
02646 
02647   /* Setup agent name: 
02648    * if GRIDSOLVE_AGENT is set in the environment, we use
02649    * that value, otherwise use the value set in the config
02650    * file.  If neither can be found, then return an error.
02651    */
02652   gs_agent_env = getenv("GRIDSOLVE_AGENT");
02653 
02654   if(gs_agent_env)
02655     gridsolve_agent = gs_agent_env;
02656   else if(gs_agent_cfg)
02657     gridsolve_agent = gs_agent_cfg;
02658   else {
02659     ERRPRINTF("Could not determine GRIDSOLVE_AGENT.\n");
02660     return NULL;
02661   }
02662  
02663   /* Do some final sanity checks, even though we don't
02664    * expect any of these to be NULL at this point.
02665    */
02666   if(!gridsolve_root) {
02667     ERRPRINTF("Could not determine GRIDSOLVE_ROOT.\n");
02668     return NULL;
02669   }
02670 
02671   if(!gridsolve_arch) {
02672     ERRPRINTF("Could not determine GRIDSOLVE_ARCH.\n");
02673     return NULL;
02674   }
02675 
02676   if(!gridsolve_agent) {
02677     ERRPRINTF("Could not determine GRIDSOLVE_AGENT.\n");
02678     return NULL;
02679   }
02680 
02681   /* set up server port number */
02682 
02683   srv_port_env = getenv("GRIDSOLVE_SERVER_PORT");
02684 
02685   if(srv_port_env)
02686     gs_server->port = atoi(srv_port_env);
02687   else if(srv_port_cfg)
02688     gs_server->port = atoi(srv_port_cfg);
02689   else
02690     gs_server->port = GRIDSOLVE_SERVER_PORT_DEFAULT;
02691 
02692   /* Initialize the proxy library */
02693   proxy_init("");           
02694 
02695   gs_server->hostname = gs_get_machine_name();
02696   gs_server->ipaddress = proxy_get_my_ipaddr();
02697 
02698   gs_server->proxyport = ntohs(proxy_get_proxy_port());
02699   gs_server->data_format = pvmgetdsig();
02700   LOGPRINTF("Running benchmark on %s\n", gs_server->hostname);
02701   gs_server->kflops = kflops();
02702   LOGPRINTF("%s kflops %d\n", gs_server->hostname, gs_server->kflops);  
02703   gs_server->ncpu = 1;      /* TODO */
02704   gs_server->status = -1;   /* TODO */
02705   gs_server->availcpu = -1;     /* TODO */
02706   gs_server->availmem = -1;     /* TODO */
02707   gs_server->problemlist = NULL;
02708   gs_server->nproblems = 0;
02709   gs_server->agenthost = NULL;
02710   gs_server->arch = gridsolve_arch;
02711 
02712   /* Parse the gridsolve_agent to get agent:port or use agent and default port */
02713   gs_agent_copy = strdup(gridsolve_agent);
02714 
02715   if(!gs_agent_copy) {
02716     gs_server_free(gs_server);
02717     ERRPRINTF("strdup failed\n");
02718     return NULL;
02719   }
02720 
02721   DBGPRINTF("gs_agent %s \n", gs_agent_copy);
02722 
02723   if((strp = strchr(gs_agent_copy, ':')) != NULL) {
02724     gs_server->agentport = atoi(strp+1);
02725     *strp = '\0';
02726   } else {
02727     gs_server->agentport = getenv_int("GRIDSOLVE_AGENT_PORT", GRIDSOLVE_AGENT_PORT_DEFAULT);
02728   }
02729 
02730   gs_server->agenthost = strdup(gs_agent_copy);
02731   if(!gs_server->agenthost) {
02732     gs_server_free(gs_server);
02733     free(gs_agent_copy);
02734     ERRPRINTF("strdup failed\n");
02735     return NULL;
02736   }
02737 
02738   FREE(gs_agent_copy);
02739 
02740   if(gs_server_create_info_dir(gs_server) < 0) {
02741     ERRPRINTF("Warning: failed to create and/or get info from server info dir\n");
02742     gs_server->infodir = NULL;
02743   }
02744 
02745   gs_clean_up_old_temp_files(gs_server->infodir);
02746 
02747   pid = getpid();
02748   snprintf(GS_SERVER_JOB_COUNT_FILE, FN_LEN, "%s/%s.%d", 
02749      gs_server->infodir ? gs_server->infodir : GS_INFODIR_PATH,
02750      GS_SERVER_JOB_COUNT_FILE_PREFIX, pid);
02751 
02752 #ifdef GS_SMART_GRIDSOLVE
02753  snprintf(GS_SMART_OBJ_FILE_EXT, FN_LEN, "%s/%s.%d",
02754      gs_server->infodir ? gs_server->infodir : GS_INFODIR_PATH,
02755      GS_SMART_OBJ_FILE_PREFIX, pid);
02756 #endif
02757 
02758 
02759   if(gs_init_job_count(GS_SERVER_JOB_COUNT_FILE) < 0) {
02760     ERRPRINTF("Failed to initialize job count file '%s'\n",
02761        GS_SERVER_JOB_COUNT_FILE);
02762     return NULL;
02763   }
02764 
02765   if(gs_server_save_encoding(gs_server) < 0)
02766     ERRPRINTF("Warning: Could not save server encoding.\n");
02767 
02768   if(data_dir) {
02769     if(chdir(data_dir) < 0) {
02770       ERRPRINTF("Could not chdir to specified data directory '%s'\n", data_dir);
02771       return NULL;
02772     }
02773   }
02774 
02775   return gs_server;
02776 }
02777 
02786 int 
02787 gs_server_dump(gs_server_t* s)
02788 {
02789   char cid_string[2*CID_LEN+1], server_dottedIP[20], proxy_dottedIP[20];
02790 
02791   proxy_cid_to_str(cid_string, s->componentid);
02792   proxy_ip_to_str(s->ipaddress, server_dottedIP);
02793   proxy_ip_to_str(s->proxyip, proxy_dottedIP);
02794 
02795   fprintf(stderr, "SERVER: ");
02796   fprintf(stderr, "hostname %s ipaddress %s port %hu proxyip %s proxyport %hu componentid %s arch %s data_format %d kflops %d workload %d ncpu %d status %d availcpu %g availmem %g nproblems %d agenthost %s agentport %d score %g\n", s->hostname, server_dottedIP, s->port, proxy_dottedIP, s->proxyport, cid_string, s->arch, s->data_format, s->kflops, s->workload, s->ncpu, s->status, s->availcpu, s->availmem, s->nproblems, s->agenthost, s->agentport, s->score);
02797   return 0;
02798 }
02799 
02811 int 
02812 gs_parse_time(const char *time, struct tm *ptm)
02813 {
02814   int n = 0, nchars = 0;
02815 
02816   memset(ptm, 0, sizeof(*ptm));
02817   ptm->tm_isdst = -1;
02818 
02819   n = sscanf(time, "%2u:%2u:%2u%n",
02820      &ptm->tm_hour, &ptm->tm_min, &ptm->tm_sec, &nchars);
02821   
02822   if(n != 3) {
02823     n = sscanf(time, "%2u:%2u%n", &ptm->tm_hour, &ptm->tm_min, &nchars);
02824   
02825     if(n != 2) {
02826       n = sscanf(time, "%2u%n", &ptm->tm_hour, &nchars);
02827 
02828       if(n != 1)
02829         return -1;
02830     }
02831   }
02832 
02833   time += nchars;
02834   if(*time) {
02835     char *ampm;
02836    
02837     ampm = (char *)malloc(strlen(time));
02838 
02839     if(!ampm) return -1;
02840 
02841     if(*time && sscanf(time, "%s", ampm)) {
02842       if(!strcasecmp(ampm, "pm"))
02843         ptm->tm_hour += 12;
02844     }
02845 
02846     free(ampm);
02847   }
02848 
02849   if(ptm->tm_hour < 0  || ptm->tm_hour > 23   ||
02850      ptm->tm_min  < 0  || ptm->tm_min  > 59   ||
02851      ptm->tm_sec  < 0  || ptm->tm_sec  > 61)
02852     return -1;
02853 
02854   return 0;
02855 }
02856 
02868 int
02869 gs_parse_time_range(char *range, struct tm *start, struct tm *end)
02870 {
02871   char *copy, *endtok;
02872 
02873   if(!range || !start || !end) return -1;
02874 
02875   copy = strdup(range);
02876 
02877   if(!copy) return -1;
02878 
02879   endtok = strchr(copy, '-');
02880 
02881   if(!endtok) {
02882     free(copy);
02883     return -1;
02884   }
02885 
02886   *endtok = 0;
02887   endtok++;
02888 
02889   if(*endtok == 0) {
02890     free(copy);
02891     return -1;
02892   } 
02893 
02894   if(gs_parse_time(copy, start) < 0) {
02895     fprintf(stderr, "Error parsing start time\n");
02896     free(copy);
02897     return -1;
02898   }
02899 
02900   if(gs_parse_time(endtok, end) < 0) {
02901     fprintf(stderr, "Error parsing end time\n");
02902     free(copy);
02903     return -1;
02904   }
02905 
02906   free(copy);
02907   return 0;
02908 }
02909 
02920 int
02921 gs_is_current_time_in_range(struct tm *start, struct tm *end)
02922 {
02923   int start_time, end_time, cur_time;
02924   struct tm *local_time;
02925   time_t ct;
02926 
02927   time(&ct);
02928   local_time = localtime(&ct);
02929 
02930 #define GS_MKTIME(t) ((t)->tm_hour*10000 + (t)->tm_min*100 + (t)->tm_sec)
02931 
02932   start_time = GS_MKTIME(start);
02933   end_time = GS_MKTIME(end);
02934   cur_time = GS_MKTIME(local_time);
02935 
02936   if(start_time <= end_time)
02937     return (cur_time >= start_time) && (cur_time <= end_time);
02938   else
02939     return (cur_time <= end_time) || (cur_time >= start_time);
02940 
02941   return 0;
02942 }