Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

Client.cpp

Go to the documentation of this file.
00001 //Client.cpp  : implementation of the client service class
00002 
00003 #include "defs.h"
00004 #include "Client.h"
00005 #include "messages.h"
00006 #include "keywords.h"
00007 #include "xmlstorage.h"
00008 #include "ClientServ.h"
00009 #ifdef HAVE_OPENSSL
00010 #include "crypter/RSAcrypter.h"
00011 #endif
00012 #include <stdio.h>  // sprintf()
00013 
00014 #ifdef _WIN32
00015 #include <direct.h>
00016 #else
00017 #include <unistd.h>
00018 #endif
00019 
00020 #define K_MASTER_HOST           0
00021 #define K_MASTER_PORT           1
00022 #define K_MASTER_TIMEOUT        2
00023 #define K_MASTER_PUBLICKEYFILE  3
00024 #define K_DBUG_FILE             4
00025 #define K_RANDOM_FILE           5
00026 #define K_DBUG_LOG_ON           6
00027 
00028 #define N_CLIENT_CFG_KWS        7
00029 
00030 #define DEFAULT_MASTER_HOST            "localhost"
00031 #define DEFAULT_MASTER_KEYFILE         "pubkey"
00032 #define DEFAULT_CLIENT_CONFIG_FILE     "client.cfg"
00033 #define DEFAULT_DBUG_FILE              "client.log"
00034 #define DEFAULT_DBUG_LOG_ON            0
00035 #define DEFAULT_RANDOM_FILE            "random.bin"
00036 #define DEFAULT_MASTER_TIMEOUT         15000        // msecs, time the master has for reply
00037 
00038 static keyword_str kws[N_CLIENT_CFG_KWS] = {
00039     { "master_host", STRING_KEYWORD, 0, {0} },
00040     { "master_port", LONG_KEYWORD, 0, {0}, {MASTER_PORT}},
00041     { "master_timeout", LONG_KEYWORD, 0, {0}, {DEFAULT_MASTER_TIMEOUT}},
00042     { "master_publickey_file", STRING_KEYWORD, 0, {0}, {0}},
00043     { "dbug_file", STRING_KEYWORD, 0, {0}, {0}},
00044     { "dbug_log_on", LONG_KEYWORD, 0, {0}, {DEFAULT_DBUG_LOG_ON}},
00045     { "random_file", STRING_KEYWORD, 0, {0}, {0}} };
00046 
00047 Client::Client ()
00048 {
00049 
00050     // read the client config file
00051     kws[K_MASTER_HOST].default_value.as_string = DEFAULT_MASTER_HOST;
00052     kws[K_MASTER_PUBLICKEYFILE].default_value.as_string = DEFAULT_MASTER_KEYFILE;
00053     kws[K_DBUG_FILE].default_value.as_string = DEFAULT_DBUG_FILE;
00054     kws[K_RANDOM_FILE].default_value.as_string = DEFAULT_RANDOM_FILE;
00055     read_config(DEFAULT_CLIENT_CONFIG_FILE, N_CLIENT_CFG_KWS, kws);
00056     if (kws[K_DBUG_LOG_ON].value.as_long) 
00057       DBUG_SETFILE(kws[K_DBUG_FILE].value.as_string);
00058     master = new Address(kws[K_MASTER_HOST].value.as_string, 
00059                          kws[K_MASTER_PORT].value.as_long);
00060     master_timeout = 1000 * kws[K_MASTER_TIMEOUT].value.as_long;
00061     
00062 #ifdef HAVE_OPENSSL
00063     //TODO: try to download the file with master key from qadpz server
00064     //      still not too nice - when the local key is updated, user has
00065     //      to delete it manually - perhaps some automatic discovery of new
00066     //      new version key would be suitable when the locally saved key fails...
00067     master_crypter = new RSAcrypter(RSAcrypter::publickey, 
00068                           kws[K_MASTER_PUBLICKEYFILE].value.as_string
00069 #if !defined(HAVE_OS_Linux) && !defined(_WIN32)
00070                          ,kws[K_RANDOM_FILE].value.as_string
00071 #endif
00072                          );
00073 #endif
00074 
00075     DBUG_PRINT("info", ("Client: master is at %s:%ld\n",
00076                          kws[K_MASTER_HOST].value.as_string, 
00077                          kws[K_MASTER_PORT].value.as_long));
00078 
00079     user = 0;
00080     passwd = 0;
00081 
00082     //create postoffice
00083 #ifdef HAVE_OPENSSL
00084     po = new PostOffice(0, 1, UDP_PORT_ITERATE, master_crypter);   
00085 #else
00086     po = new PostOffice(0, 1, UDP_PORT_ITERATE);   
00087 #endif
00088     if (!po->initialized())
00089     {
00090       DBUG_PRINT("err", ("Error initializing post office"));
00091       exit(1);
00092     }
00093 
00094     //use master as default destination
00095     po->setRemote(*master);
00096 
00097     //initialize local address
00098     uint p;
00099     po->getLocalPort(&p);
00100     addr = Address::getAddress(p);
00101 
00102     // this indicates that the client is not on
00103     jobID.id = -1;
00104 
00105     // no message received from master yet
00106     firsttime = 1;
00107 
00108     //initialize statistics info
00109     stat.tasksRequested = stat.tasksStarted = stat.tasksRefused = 
00110     stat.tasksFinished = stat.tasksCrashed = stat.tasksStopped = 
00111     stat.slavesReserved = stat.slavesProvided = 0;
00112 }
00113 
00114 
00115 Client::~Client ()
00116 {
00117     if (po) delete po;
00118     delete master;
00119     delete addr;
00120 #ifdef HAVE_OPENSSL
00121     delete master_crypter;
00122 #endif
00123     if (user) delete[] user;
00124     if (passwd) delete[] passwd;
00125     free_messages();
00126 }
00127 
00128 XMLData *Client::wait_for(CharStr *msg_type)
00129 {
00130     XMLData *m;
00131     //wait for message of required type, after MASTER_TIMEOUT milliseconds return
00132     int recOK = 0;
00133     do {
00134         if (firsttime) 
00135         {
00136             m = po->receive_any(*master, master_timeout);
00137             if ((m != PostOffice::Timeout) && (m != XMLData::Nil))
00138             {
00139                po->setRemote(*master);
00140                firsttime = 0;
00141             }
00142         }
00143         else    
00144             m = po->receive(master, master_timeout);
00145     
00146         //timeout or error?
00147         if ((m == PostOffice::Timeout) ||
00148             (m == XMLData::Nil))
00149         {
00150             DBUG_PRINT("info", ("po.receive() returned Timeout or Nil"))
00151             jobID.id = -1;
00152             return XMLData::Nil;
00153         }
00154         //if not expected type, put back
00155         if (!msgType(m, msg_type))
00156         {
00157             //SLEEP_MSEC(10);
00158             //DBUG_PRINT("info", ("po.receive() returned message, but it is not of expected type %s", msg_type->str))
00159             po->put_back(*master, m);
00160         }
00161         else recOK = 1;
00162     } while (!recOK);
00163     //DBUG_PRINT("info", ("Client: wait_for() returning message"))
00164     return m;
00165 }
00166 
00167 void Client::setUserPswd(const char *user, const char *passwd)
00168 {
00169     this->user = new char[strlen(user) + 1];
00170     strcpy(this->user, user);
00171     this->passwd = new char[strlen(passwd) + 1];
00172     strcpy(this->passwd, passwd);
00173 }
00174 
00175 
00176 JobId *Client::clientOn(const char *user, const char *passwd,
00177                         const char *JobID_name, const int jobNumber)
00178 {
00179     int sentOK;
00180     static JobId previous_jobID("Client::noJob", -1);        // here the previous JobId to clientOn() is stored
00181     XMLData *m_job_status;
00182 
00183     //if client is already on, it has to be clientOffed first
00184     if (jobID.id != -1) return 0;
00185 
00186     setUserPswd (user, passwd);
00187 
00188     jobID.name(JobID_name);
00189     jobID.id = jobNumber;
00190 
00191     //taking over old job?
00192     if (jobNumber >= 0)
00193     {
00194         //yes->see if the job is currently abandonded
00195         
00196         //ask master with M_JOB_CTRL for job status
00197         JobStatus *js = jobCtrl(jobID, get_job_status);
00198         //error?
00199         if (js->state == job_refused) 
00200         {
00201             jobID.id = -1;
00202             return 0;
00203         }
00204 
00205         //controlled by other job?
00206         if (js->state == job_running)
00207             //if not forced steal of other job, return with JOB_A.._C..
00208             if ((previous_jobID.id == -1) || (jobID != previous_jobID))
00209             {
00210                 previous_jobID = jobID;
00211                 jobID.id = -1;
00212                 return JOB_ALREADY_CONTROLLED;
00213             }
00214         //old job, but OK to take over...
00215         DBUG_PRINT("info", ("stealing an old job %s,%d",jobID.name(), jobID.id));
00216     }
00217 
00218     //send M_CLIENT_STATUS(On)
00219         
00220     XMLData *m_client_on = xmlmsg(p_M_CLIENT_STATUS, o2x(jobID));
00221     m_client_on->add(new XMLData(p_ClientStatus, p_On));
00222     char ip[26];
00223     addr->getIP(ip);
00224     m_client_on->add(new XMLData(p_Address, ip));
00225     sentOK = send(m_client_on);
00226         
00227     if (!sentOK)    //error sending?
00228     {
00229         DBUG_PRINT("info", ("Client: send() failed"))
00230         jobID.id = -1;
00231         return 0;
00232     }
00233 
00234     //wait for M_JOB_STATUS reply from master
00235     m_job_status = wait_for(p_M_JOB_STATUS);
00236 
00237     //error or timeout?
00238     if (m_job_status == XMLData::Nil) 
00239     {
00240         DBUG_PRINT("info", ("Client: po.receive() error or timeout"))
00241         return 0;
00242     }
00243 
00244     //job did not start?
00245     if (strcmp(m_job_status->sub(p_JobStatus)->sub(p_Status)->getString()->str, p_Running->str) != 0)
00246     {
00247         jobID.id = -1;
00248         DBUG_PRINT("info", ("Client: M_JOB_STATUS doesn't contain JobStatus(Running)"))
00249         return 0;
00250     }
00251    
00252     //remember the full JobID
00253     x2o(m_job_status->sub(p_JobID), jobID);
00254 
00255     //and return a pointer to it
00256     return &jobID;
00257 }
00258 
00259 int Client::clientOff(int terminate_job)
00260 {
00261     int sentOK;
00262     XMLData *m_job_status;
00263 
00264     //if client is not On, return 0
00265     if (jobID.id == -1) return 0;
00266 
00267     if (!terminate_job)
00268     {
00269       //send M_CLIENT_STATUS(Off)
00270       XMLData *m_client_off = xmlmsg(p_M_CLIENT_STATUS, o2x(jobID));
00271       m_client_off->add(new XMLData(p_ClientStatus, p_Off));
00272       sentOK = send(m_client_off);
00273         
00274       //error sending?
00275       if (!sentOK) return 0;
00276     
00277       //wait for M_JOB_STATUS from master
00278       m_job_status = wait_for(p_M_JOB_STATUS);
00279 
00280       //error or timeout?
00281       if (m_job_status == XMLData::Nil) return 0;
00282 
00283       //expecting job to be Abandoned, if not error
00284       if (strcmp(m_job_status->sub(p_JobStatus)->sub(p_Status)->getString()->str, p_Abandoned->str) != 0)
00285       {
00286         delete m_job_status;
00287         return 0;
00288       }
00289         delete m_job_status;
00290     }
00291     else //send M_TASK_STAtUS(job), if the job is to be terminated  
00292       delete jobCtrl(jobID, stop_job);
00293 
00294     jobID.id = -1;
00295     return 1;
00296 }
00297 
00298 JobStatus *Client::jobCtrl(const JobId &jobID, const job_ctrl_action action)
00299 {
00300     XMLData *m_job_status;
00301     int sentOK;
00302 
00303     //send M_JOB_CTRL
00304     XMLData *m_job_ctrl = xmlmsg(p_M_JOB_CTRL, o2x(jobID));
00305     m_job_ctrl->add(new XMLData(p_Action, o2x(action)));
00306     sentOK = send(m_job_ctrl);
00307     if (!sentOK) return new JobStatus(0, 0, job_refused);
00308 
00309     //wait for m_job_status from master
00310     m_job_status = wait_for(p_M_JOB_STATUS);
00311 
00312     // error or timeout?
00313     if (m_job_status == XMLData::Nil) return new JobStatus(0, 0, job_refused);
00314 
00315     //return received message
00316     JobStatus *js = new JobStatus();
00317     x2o(m_job_status->sub(p_JobStatus), *js);
00318     return js;
00319 }
00320 
00321 TaskStatus *Client::_taskCreate (const TaskId &taskID, XMLData *listTaskInfo, 
00322                         const char *data, const Address *slaveAddress)
00323 {
00324     int sentOK;
00325 
00326     //if client not on, return task_refused
00327     if (jobID.id == -1) 
00328     {
00329         delete listTaskInfo;
00330         return new TaskStatus(taskID, task_refused, "Client not On");
00331     }
00332 
00333     //send M_TASK_INIT
00334     XMLData *m_task_init = xmlmsg(p_M_TASK_INIT, o2x(taskID));
00335     m_task_init->add(listTaskInfo);
00336     if (data)  m_task_init->add(new XMLData(XMLData::CDATA, data));
00337     if (slaveAddress)
00338     {
00339         char addr[26];
00340         slaveAddress->getIP(addr);
00341         m_task_init->add(new XMLData(p_Address, addr));
00342     }
00343     sentOK = send(m_task_init);
00344 
00345     if (!sentOK)
00346         return new TaskStatus(taskID, task_refused, "Could not send M_TASK_INIT to master");
00347 
00348     DBUG_PRINT("info", ("Client: createTask(): M_TASK_INIT sent, waiting for M_TASK_STATUS..."))
00349     stat.tasksRequested++;
00350     
00351     XMLData *m_task_status;
00352     TaskId matchTaskId;
00353     int correctTaskID = 0;
00354     do {
00355         //wait for M_TASK_STATUS from master
00356         m_task_status = wait_for(p_M_TASK_STATUS);
00357 
00358         //if TaskId doesn't match, put it back sleep a bit and wait again
00359         x2o(m_task_status->sub(p_TaskID), matchTaskId);
00360         if (!(taskID == matchTaskId))
00361         {
00362             //SLEEP_MSEC(5);
00363             //DBUG_PRINT("info", ("Client: createTask(): M_TASK_STATUS, but for a different task, putting back..."))
00364             po->put_back(*master, m_task_status);
00365         }
00366         else correctTaskID = 1;
00367     } while (!correctTaskID);
00368 
00369     //error or timeout?
00370     if (m_task_status == XMLData::Nil) 
00371     {
00372         DBUG_PRINT("info", ("Client: taskCreate(): no M_TASK_STATUS: error or timeout..."))
00373         stat.tasksRefused++;
00374         return new TaskStatus(taskID, task_refused, "Master not responding: timeout or error");
00375     }
00376 
00377     DBUG_PRINT("info", ("Client: createTask(): M_TASK_STATUS ok"))
00378     
00379     //return the task status
00380     TaskStatus *tstatus = new TaskStatus();
00381     x2o(m_task_status, *tstatus);
00382     if (tstatus->state == task_refused) stat.tasksRefused++;
00383 
00384     return tstatus;
00385 }
00386 
00387 TaskStatus *Client::taskCreate (const TaskId &taskID, List &listTaskInfo, 
00388                         const char *data, const Address *slaveAddress)
00389 {
00390     XMLData *xmlTaskInfo = new XMLData(p_TaskInfo, XMLData::Nil);
00391     listTaskInfo.Start_Get();
00392     for (int i = 1; i < listTaskInfo.Count(); i++)
00393         xmlTaskInfo->add(o2x( *( (TaskInfo *)(listTaskInfo.Get_Next()) ) ));
00394 
00395     return _taskCreate(taskID, xmlTaskInfo->sub(), data, slaveAddress);
00396 }
00397 
00398 TaskStatus *Client::taskCreate (const TaskId &taskID, XMLData *listTaskInfo, 
00399                         const char *data, const Address *slaveAddress)
00400 {
00401     return _taskCreate(taskID, listTaskInfo, data, slaveAddress);
00402 }
00403 
00404 TaskStatus *Client::taskCtrl (const TaskId &taskID, const task_ctrl_action action, const char *arg)
00405 {
00406     int sentOK;
00407 
00408     //if client not on, return 0
00409     //however, we should be able to send a TaskCtrl(stop) without being connected?!
00410     if ((jobID.id == -1) && (action != stop_task)) 
00411       return new TaskStatus(taskID, task_refused, "Client not On");
00412 
00413     //send M_TASK_CTRL
00414     XMLData *m_task_ctrl = xmlmsg(p_M_TASK_CTRL, o2x(taskID));
00415     m_task_ctrl->add(new XMLData(p_Action, o2x(action)));
00416     if (arg)  m_task_ctrl->add(new XMLData(p_Argument, arg));
00417     sentOK = send(m_task_ctrl);
00418 
00419     if (!sentOK) return new TaskStatus(taskID, task_refused, "Could not send M_TASK_CTRL to master");
00420 
00421     //wait for M_TASK_STATUS from master
00422     XMLData *m_task_status;
00423     TaskId matchTaskId;
00424     int correctTaskID = 0;
00425     do {   
00426         m_task_status = wait_for(p_M_TASK_STATUS);
00427 
00428         //if TaskId doesn't match, put it back sleep a bit and wait again
00429         x2o(m_task_status->sub(p_TaskID), matchTaskId);
00430         if (!(taskID == matchTaskId))
00431         {
00432             //SLEEP_MSEC(5);
00433             //DBUG_PRINT("info", ("Client: taskCtrl(): M_TASK_STATUS, but for a different task, putting back..."))
00434             po->put_back(*master, m_task_status);
00435         }
00436         else correctTaskID = 1;
00437     } while (!correctTaskID);
00438 
00439     //error or timeout?
00440     if (m_task_status == XMLData::Nil) return new TaskStatus(taskID, task_refused, "master not responding: error or timeout");
00441 
00442     //return the task status
00443     TaskStatus *tstatus = new TaskStatus();
00444     x2o(m_task_status, *tstatus);
00445     return tstatus;
00446 }
00447 
00448 
00449 ReserveId *Client::slaveReserve (const char *reserveName, const int slavesRequired, const int parallel, const int nSlaveInfos, const SlaveInfo *slaveInfos)
00450 {
00451     XMLData *infos = new XMLData(p_On, XMLData::Nil);   //note: p_On doesn't have meening here
00452     for (int i = 0; i < nSlaveInfos; i++)
00453         infos->add(o2x(slaveInfos[i]));
00454     return slaveReserve(reserveName, slavesRequired, parallel, nSlaveInfos, infos->sub());
00455 }
00456 
00457 ReserveId *Client::slaveReserve (const char *reserveName, const int slavesRequired, const int parallel, const int nSlaveInfos, XMLData *slaveInfo)
00458 {
00459     int sentOK;
00460     
00461     //if client not on, return 0
00462     if (jobID.id == -1) return 0;
00463 
00464     ReserveId *resID = new ReserveId(reserveName, -1);
00465 
00466     //send M_SLAVE_RESERVE
00467     XMLData *m_slave_reserve = xmlmsg(p_M_SLAVE_RESERVE, o2x(*resID));
00468     m_slave_reserve->add(new XMLData(p_SlavesRequired, slavesRequired));
00469     if (parallel) 
00470         m_slave_reserve->add(new XMLData(p_Parallel, XMLData::Nil));
00471     m_slave_reserve->add(o2x(jobID));
00472     m_slave_reserve->add(slaveInfo);
00473     
00474     sentOK = send(m_slave_reserve);
00475     if (!sentOK) 
00476     {
00477         delete resID;
00478         return 0;
00479     }
00480     stat.slavesReserved += slavesRequired;
00481 
00482     //wait for M_JOB_STATUS from master
00483     XMLData *m_job_status = wait_for(p_M_JOB_STATUS);
00484 
00485     //error or timeout?
00486     if (m_job_status == XMLData::Nil) 
00487     {
00488         delete resID;
00489         return 0;
00490     }
00491 
00492     //request refused?
00493     if (strcmp(m_job_status->sub(p_JobStatus)->getString(p_Status)->str, p_Refused->str) == 0)
00494     {
00495         DBUG_PRINT("info", ("Client:M_JOB_STATUS(Refused) reply to M_SLAVE_RESERVE, error:%s", 
00496                            m_job_status->getString(p_Error)->str));
00497         delete resID;
00498         return 0;
00499     }
00500     
00501     //extract and return reserveID
00502     XMLData *x = m_job_status->reset()->sub(p_JobStatus)->sub(p_ReserveID);
00503     
00504     if (x == XMLData::Nil)
00505     {
00506         DBUG_PRINT("err", ("Client:M_JOB_STATUS reply to M_SLAVE_RESERVE doesn't have ReserveID..."))
00507         delete resID;
00508         return 0;
00509     }
00510     x2o(x, *resID);
00511     return resID;
00512 }
00513 
00514 wait_master_result Client::waitMaster(Object *&result, long timeout)
00515 {
00516     if (timeout == 0) timeout = NO_TIMEOUT;
00517 
00518     do {
00519     
00520         XMLData *x = po->receive(master, timeout);
00521 
00522         if (x == PostOffice::Timeout) return wait_timeout;
00523         if (x == XMLData::Nil) return waitmaster_error;
00524 
00525         if (msgType(x, p_M_TASK_FINISH))
00526         {
00527             TaskFinish *tfin = new TaskFinish();
00528             x2o(x, *tfin);
00529             result = tfin;
00530             delete x;
00531             stat.tasksFinished++;
00532             return task_finish;
00533         }
00534         if (msgType(x, p_M_TASK_STATUS))
00535         {
00536             TaskStatus *tstat = new TaskStatus();
00537             x2o(x, *tstat);
00538             result = tstat;
00539             delete x;
00540             if (tstat->state == task_started) stat.tasksStarted++;
00541             else if (tstat->state == task_refused) stat.tasksRefused++;
00542             else if (tstat->state == task_crashed) stat.tasksCrashed++;
00543             else if (tstat->state == task_stopped) stat.tasksStopped++;
00544             return task_status;
00545         }
00546         if (msgType(x, p_M_SLAVE_AVAIL))
00547         {
00548             SlaveAvail *sav = new SlaveAvail();
00549             x2o(x, *sav);
00550             result = sav;
00551             delete x;
00552             stat.slavesProvided += sav->slavesRequired;
00553             return slave_avail;
00554         }
00555         if (msgType(x, p_M_JOB_STATUS))
00556         {
00557             JobStatus *jstat = new JobStatus();
00558             x2o(x->sub(p_JobStatus), *jstat);
00559             result = jstat;
00560             delete x;
00561             return job_status;
00562         }
00563         if (msgType(x, p_M_SLAVE_STATUS))
00564         {
00565             if (strcmp(x->getString(p_Status)->str, p_Ok->str) == 0)
00566               result = new Object;
00567             else result = 0;
00568             delete x;
00569             return slave_status;
00570         }
00571         DBUG_PRINT("err", ("Client: error invalid message Type=%s",
00572                    x->getAttrib ("Type")->str));    
00573         delete x;
00574     } while (1);
00575 }
00576 
00577 //uploads given file to a QADPZ data server at given address, if 0, then default
00578 //data server is used
00579 //returns 0 if error, otherwise non-zero
00580 int Client::put_data(const char *fileName, int taskId, const char *url_upload)
00581 {
00582   char str_job_name[100];    // 10+strlen(jobName)
00583   char str_job_id[20];      //  8+
00584   char str_task_id[20];     //  9+
00585   char str_task_file[200];  // 12+strlen(fileName)
00586 
00587   sprintf (str_job_name, "job_name=%s", jobID.name());
00588   sprintf (str_job_id, "job_id=%d", jobID.id);
00589   sprintf (str_task_id, "task_id=%d", taskId);
00590   //extract filename without path (needed to supply to cgi-script)
00591   const char *onlyName;
00592   EXTRACT_FILENAME(fileName, onlyName);
00593   sprintf (str_task_file, "task_file=@%s", onlyName);
00594   //extract upload path (we will chdir there because script doesn't accept path)
00595   char *onlyPath = new char[onlyName - fileName + 1];
00596   strncpy(onlyPath, fileName, onlyName - fileName);
00597   onlyPath[onlyName - fileName] = '\0';
00598   //save the current directory
00599   char savePath[256];
00600 #ifdef _WIN32
00601   _getcwd(savePath, 255);
00602   _chdir(onlyPath);
00603 #else
00604   getcwd(savePath, 255);
00605   chdir(onlyPath);
00606 #endif
00607 
00608   //perform upload
00609   int rv = postURL (url_upload, "upload.txt", 
00610              str_job_name,
00611              str_job_id,
00612              str_task_id,
00613              str_task_file,
00614              "submit=send", 0);
00615 
00616   //restore current directory
00617 #ifdef _WIN32
00618   _chdir(savePath);
00619 #else
00620   chdir(savePath);
00621 #endif
00622 
00623   delete [] onlyPath;
00624   return rv;
00625 }
00626 
00627 //dowwnloads given file from a QADPZ data server at given address, if 0, default
00628 //data server is used
00629 //returns 0 if error, otherwise non-zero
00630 int Client::get_data(const char *fileName, int taskId, const char *url_download)
00631 {
00632   char str_job_name[100];    // 10+strlen(jobName)
00633   char str_job_id[20];      //  8+
00634   char str_task_id[20];     //  9+
00635   char str_task_file[200];  // 12+strlen(fileName)
00636 
00637   sprintf (str_job_name, "job_name=%s", jobID.name());
00638   sprintf (str_job_id, "job_id=%d", jobID.id);
00639   sprintf (str_task_id, "task_id=%d", taskId);
00640   const char *onlyName;   // remove the path from the filename if any
00641   EXTRACT_FILENAME(fileName, onlyName);
00642   sprintf (str_task_file, "task_file=@%s", onlyName);
00643 
00644   return postURL (url_download, fileName,
00645            str_job_name,
00646            str_job_id,
00647            str_task_id,
00648            str_task_file,
00649            "submit=send", 0);
00650 }
00651 
00652 void Client::statistics(qadpz_cli_stat *stat)
00653 {
00654   *stat = this->stat;    // full structure copy
00655 }
00656 
00657 int Client::send(XMLData *msg)
00658 {
00659   XMLData *data = new XMLData(p_Data,
00660                         new XMLData(p_UserInfo,
00661                             new XMLData(p_User, user,
00662                             new XMLData(p_Pswd, passwd)),
00663                         msg));
00664                            
00665 #ifdef HAVE_OPENSSL
00666   int retval = po->send(data, 0, sm_crypt);
00667 #else
00668   int retval = po->send(data, 0, sm_plain);
00669 #endif
00670   delete data;
00671   return retval;
00672 }

Generated on Mon Nov 25 12:46:28 2002 for qadpz by doxygen1.2.18