Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-02 08:21:08

0001 
0002 #include "rcdaq_rpc.h"
0003 #include "rcdaq_actions.h"
0004 
0005 #include "parseargument.h"
0006 #include "rcdaq.h"
0007 #include "daq_device.h" 
0008 #include "rcdaq_plugin.h" 
0009 #include "all.h" 
0010 
0011 
0012 #include <iostream>
0013 #include <sstream>
0014 #include <iomanip>
0015 #include <fstream>
0016 #include <string.h>
0017 #include <stdlib.h>
0018 #include <dlfcn.h>
0019 
0020 #include <rpc/pmap_clnt.h>
0021 
0022 #include <stdio.h>
0023 #include <string.h>
0024 #include <unistd.h>
0025 #include "pthread.h"
0026 #include "signal.h"
0027 
0028 #include <sys/file.h>
0029 #include <errno.h>
0030 #include <sys/stat.h>
0031 #include <sys/types.h>
0032 
0033 
0034 #include <vector>
0035 
0036 
0037 #include <set>
0038 #include <iostream>
0039 
0040 using namespace std;
0041 
0042 static pthread_mutex_t M_output;
0043 
0044 std::vector<RCDAQPlugin *> pluginlist;
0045 
0046 static unsigned long  my_servernumber = 0;
0047 
0048 extern "C"  void rcdaq_1(struct svc_req *rqstp, SVCXPRT *transp);
0049 
0050 static int pid_fd = 0;
0051 
0052 
0053 void sig_handler(int i)
0054 {
0055   if (pid_fd)
0056     {
0057       char *pidfilename = obtain_pidfilename();
0058       unlink (pidfilename);
0059     }
0060   exit(0);
0061 }
0062 
0063 
0064 
0065 
0066 //-------------------------------------------------------------
0067 
0068 
0069 void plugin_register(RCDAQPlugin * p )
0070 {
0071   pluginlist.push_back(p);
0072 }
0073 
0074 void plugin_unregister(RCDAQPlugin * p )
0075 {
0076   // do nothing for now
0077   // we need to implement this once we add unloading of plugins
0078   // as a feature (don't see why at this point)
0079 }
0080 
0081 int daq_load_plugin( const char *sharedlib, std::ostream& os)
0082 {
0083   void * v = dlopen(sharedlib, RTLD_GLOBAL | RTLD_NOW | RTLD_NOLOAD);
0084   if (v) 
0085     {
0086       std::cout << "Plugin " 
0087         << sharedlib << " already loaded" << std::endl;
0088       os << "Plugin " 
0089         << sharedlib << " already loaded" << std::endl;
0090       return 0;
0091     }
0092     
0093   void * voidpointer = dlopen(sharedlib, RTLD_GLOBAL | RTLD_NOW);
0094   if (!voidpointer) 
0095     {
0096       std::cout << "Loading of the plugin " 
0097         << sharedlib << " failed: " << dlerror() << std::endl;
0098       os << "Loading of the plugin " 
0099         << sharedlib << " failed: " << dlerror() << std::endl;
0100       return -1;
0101       
0102     }
0103   os << "Plugin " << sharedlib << " successfully loaded" << std::endl;
0104   cout  << "Plugin " << sharedlib << " successfully loaded" << std::endl;
0105   return 0;
0106 
0107 }
0108 
0109 //-------------------------------------------------------------
0110 
0111 // for certain flags we add some info to the status output
0112 // with this routine. It is called from daq_status. 
0113 
0114 int daq_status_plugin (const int flag, std::ostream& os )
0115 {
0116 
0117   // in case we do have plugins, list them
0118   // if not, we just say "no plugins loded"
0119   if (   pluginlist.size() )
0120     {
0121       os << "  List of loaded Plugins:" << endl;
0122     }
0123   else
0124     {
0125       os << "   No Plugins loaded" << endl;
0126     }
0127 
0128 
0129   std::vector<RCDAQPlugin *>::iterator it;
0130 
0131   for ( it=pluginlist.begin(); it != pluginlist.end(); ++it)
0132     {
0133       os << "  ";
0134       (*it)->identify(os, flag);
0135     }
0136   return 0;
0137 }
0138 
0139 //-------------------------------------------------------------
0140 
0141 
0142 shortResult * r_create_device_1_svc(deviceblock *db, struct svc_req *rqstp)
0143 {
0144   static shortResult  result, error;
0145   static char e_string[512];
0146   static char r_string[512];
0147   error.str = e_string;
0148   result.str = r_string;
0149   strcpy ( r_string, " ");
0150   
0151   if ( daq_running() )
0152     {
0153       strcpy(e_string, "Run is active\n");
0154       error.content = 1;
0155       error.what    = 0;
0156       error.status  = -1;
0157       return &error;
0158     }
0159 
0160   strcpy(e_string, "Device needs at least 2 parameters\n");
0161   error.content = 1;
0162   error.what    = 0;
0163   error.status  = -1;
0164 
0165   result.status = 0;
0166   result.what   = 0;
0167   result.content= 0;
0168 
0169 
0170   int eventtype;
0171   int subid;
0172 
0173 
0174   if ( db->npar < 3)
0175     {
0176       strcpy(r_string, "Device needs at least 2 parameters\n");
0177       return &error;
0178     }
0179   
0180       
0181   strcpy(r_string, "Wrong number of parameters\n");
0182 
0183   // and we decode the event type and subid
0184   eventtype  = get_value ( db->argv1); // event type
0185   subid = get_value ( db->argv2); // subevent id
0186 
0187 
0188   // now we will see what device we are supposed to set up.
0189   // we first check if it is one of our built-in ones, such as
0190   // device_random, or device_file or so.
0191   
0192 
0193   if ( strcasecmp(db->argv0,"device_random") == 0 ) 
0194     {
0195 
0196       // this happens to be the most complex contructor part
0197       // so far since there are a few variants, 2-6 parameters
0198       switch ( db->npar)
0199     {
0200     case 3:
0201           add_readoutdevice ( new daq_device_random( eventtype,
0202                                                      subid ));
0203           break;
0204 
0205         case 4:
0206           add_readoutdevice ( new daq_device_random( eventtype,
0207                                                      subid,
0208                              get_value ( db->argv3)));
0209           break;
0210 
0211         case 5:
0212           add_readoutdevice ( new daq_device_random( eventtype,
0213                                                      subid, 
0214                              get_value ( db->argv3),
0215                              get_value ( db->argv4)));
0216           break;
0217 
0218         case 6:
0219           add_readoutdevice ( new daq_device_random( eventtype,
0220                                                      subid, 
0221                              get_value ( db->argv3),
0222                              get_value ( db->argv4),
0223                              get_value ( db->argv5)));
0224           break;
0225 
0226         case 7:
0227           add_readoutdevice ( new daq_device_random( eventtype,
0228                                                      subid, 
0229                              get_value ( db->argv3),
0230                              get_value ( db->argv4),
0231                              get_value ( db->argv5),
0232                              get_value ( db->argv6)));
0233           break;
0234 
0235        default:
0236           return &error;
0237           break;
0238         }
0239 
0240       return &result;
0241     }
0242 
0243   if ( strcasecmp(db->argv0,"device_deadtime") == 0 ) 
0244     {
0245 
0246       // this happens to be the most complex contructor part
0247       // so far since there are a few variants, 2-6 parameters
0248       switch ( db->npar)
0249     {
0250     case 3:
0251           add_readoutdevice ( new daq_device_deadtime( eventtype,
0252                                subid ));
0253           break;
0254 
0255         case 4:  // plus number of ticks
0256           add_readoutdevice ( new daq_device_deadtime( eventtype,
0257                                subid,
0258                                get_value ( db->argv3)));
0259           break;
0260 
0261         case 5:  // plus number of words
0262           add_readoutdevice ( new daq_device_deadtime( eventtype,
0263                                subid, 
0264                                get_value ( db->argv3),
0265                                get_value ( db->argv4)));
0266           break;
0267 
0268         case 6:   // plus trigger flag
0269           add_readoutdevice ( new daq_device_deadtime( eventtype,
0270                                subid, 
0271                                get_value ( db->argv3),
0272                                get_value ( db->argv4),
0273                                get_value ( db->argv5)));
0274           break;
0275 
0276        default:
0277           return &error;
0278           break;
0279         }
0280 
0281       return &result;
0282     }
0283 
0284 
0285   else if ( strcasecmp(db->argv0,"device_file") == 0 )  
0286     {
0287 
0288       if ( db->npar < 4) return &error;
0289 
0290       if ( db->npar >= 5) 
0291     {
0292       // we give the size in kbytes but we want it in words 
0293       int s = 1024*(get_value(db->argv4)+3)/4;
0294       if ( s < 4*1024) s = 4*1024;    // this is the default size
0295       add_readoutdevice ( new daq_device_file( eventtype,
0296                            subid,
0297                            db->argv3,
0298                            0, // no delete
0299                            s ) );
0300       return &result;
0301     }
0302       else 
0303     {
0304 
0305       add_readoutdevice ( new daq_device_file( eventtype,
0306                            subid,
0307                            db->argv3));
0308       return &result;
0309     }
0310 
0311     }
0312   // --------------------------------------------------------------------------
0313   // although this logic is very similar to device_file, since the consequences
0314   // of a misplaced parameter are so severe, we make a new device
0315   else if ( strcasecmp(db->argv0,"device_file_delete") == 0 )  
0316     {
0317 
0318       if ( db->npar < 4) return &error;
0319 
0320       if ( db->npar >= 5) 
0321     {
0322       // we give the size in kbytes but we want it in words 
0323       int s = 1024*(get_value(db->argv4)+3)/4;
0324       if ( s < 4*1024) s = 4*1024;    // this is the default size
0325       add_readoutdevice ( new daq_device_file( eventtype,
0326                            subid,
0327                            db->argv3,
0328                            1,  // we add the delete flag
0329                            s ) );
0330       return &result;
0331     }
0332       else 
0333     {
0334 
0335       add_readoutdevice ( new daq_device_file( eventtype,
0336                            subid,
0337                            db->argv3,
0338                            1) );
0339       return &result;
0340     }
0341 
0342     }
0343 
0344 
0345   // --------------------------------------------------------------------------
0346 
0347 
0348   else if ( strcasecmp(db->argv0,"device_filenumbers") == 0 )  
0349     {
0350 
0351       if ( db->npar < 4) return &error;
0352 
0353       if ( db->npar >= 5) 
0354     {
0355       int s = 1024*(get_value(db->argv4)+3)/4;
0356       if ( s < 256) s = 256;    // this is the default size
0357 
0358       add_readoutdevice ( new daq_device_filenumbers( eventtype,
0359                               subid,
0360                               db->argv3,
0361                               0,  // no delete
0362                               s));
0363       return &result;
0364     }
0365       else 
0366     {
0367 
0368       add_readoutdevice ( new daq_device_filenumbers( eventtype,
0369                               subid,
0370                               db->argv3));
0371       return &result;
0372     }
0373 
0374     }
0375 
0376   // --------------------------------------------------------------------------
0377 
0378 
0379   else if ( strcasecmp(db->argv0,"device_filenumbers_delete") == 0 )  
0380     {
0381 
0382       if ( db->npar < 4) return &error;
0383 
0384       if ( db->npar >= 5) 
0385     {
0386       int s = 1024*(get_value(db->argv4)+3)/4;
0387       if ( s < 256) s = 256;    // this is the default size
0388 
0389       add_readoutdevice ( new daq_device_filenumbers( eventtype,
0390                               subid,
0391                               db->argv3,
0392                               1,  // we add the delete flag
0393                               s));
0394       return &result;
0395     }
0396       else 
0397     {
0398 
0399       add_readoutdevice ( new daq_device_filenumbers( eventtype,
0400                               subid,
0401                               db->argv3,
0402                               1) );
0403       return &result;
0404     }
0405 
0406     }
0407 
0408 
0409   else if ( strcasecmp(db->argv0,"device_command") == 0 )  
0410     {
0411 
0412       if ( db->npar < 4) return &error;
0413 
0414       if ( db->npar >= 5) 
0415     {
0416       int s = (get_value(db->argv4)+3)/4;
0417       if ( s < 1280) s = 1280;    // this is the default size
0418       add_readoutdevice ( new daq_device_file( eventtype,
0419                            subid,
0420                            db->argv3,
0421                            get_value(db->argv4) ) );
0422       return &result;
0423     }
0424       else 
0425     {
0426 
0427       add_readoutdevice ( new daq_device_command( eventtype,
0428                            subid,
0429                            db->argv3));
0430       return &result;
0431     }
0432 
0433     }
0434   else if ( strcasecmp(db->argv0,"device_rtclock") == 0 )  
0435     {
0436       
0437       add_readoutdevice ( new daq_device_rtclock( eventtype,
0438                            subid));
0439               
0440       return &result;
0441     }
0442 
0443 
0444   // nada, it was none of the built-in ones if we arrive here.
0445 
0446   // we now go through through the list of plugins and see if any one of
0447   // our plugins can make the device.
0448 
0449   // there are three possibilities:
0450   //  1) the plugin can make the device, all done. In that case, return = 0 
0451   //  2) the plugin can make the device but the parameters are wrong, return  = 1 
0452   //  3) the plugin dosn not knwo about tha device, we keep on going...  return = 2
0453 
0454   // we keep doing that until we either find a plugin that knows the device or  we run
0455   // out of plugins
0456   
0457   std::vector<RCDAQPlugin *>::iterator it;
0458 
0459   int status;
0460   for ( it=pluginlist.begin(); it != pluginlist.end(); ++it)
0461     {
0462       status = (*it)->create_device(db);
0463       // in both of the following cases we are done here:
0464       if (status == 0) return &result;  // sucessfully created 
0465       else if ( status == 1) return &error;  // it's my device but wrong params
0466       // in all other cases we continue and try the next plugin
0467     }
0468 
0469   result.content=1;
0470   strcpy(r_string, "Unknown device");
0471   return &result;
0472 
0473 }
0474 
0475 //-------------------------------------------------------------
0476 
0477 shortResult * r_action_1_svc(actionblock *ab, struct svc_req *rqstp)
0478 {
0479 
0480   static shortResult  result;
0481 
0482   static std::ostringstream outputstream;
0483   static unsigned int currentmaxresultlength = 10*2048;
0484   static char *resultstring = new char[currentmaxresultlength+1];
0485 
0486   // to avoid a race condition with the asynchronous
0487   // begin or "end requested" feature, wait here...
0488   daq_wait_for_begin_done();
0489   daq_wait_for_actual_end();
0490 
0491   
0492   if ( outputstream.str().size() > currentmaxresultlength )
0493     {
0494       currentmaxresultlength = outputstream.str().size();
0495       std::cout << __LINE__<< "  " << __FILE__ 
0496         << " *** warning: extended result string to " << currentmaxresultlength << std::endl;
0497       delete [] resultstring;
0498       resultstring = new char[currentmaxresultlength+1];
0499     }
0500 
0501 
0502   pthread_mutex_lock(&M_output);
0503   result.str=resultstring;
0504   strcpy(resultstring," ");
0505   result.content = 0;
0506   result.what = 0;
0507   result.status = 0;
0508 
0509   outputstream.str("");
0510 
0511   switch ( ab->action)
0512     {
0513       
0514     case DAQ_SYNC:
0515       pthread_mutex_unlock(&M_output);
0516 
0517       return &result;
0518       break;
0519 
0520     case DAQ_BEGIN:
0521       result.status = daq_begin (  ab->ipar[0], outputstream);
0522       outputstream.str().copy(resultstring,outputstream.str().size());
0523       resultstring[outputstream.str().size()] = 0;
0524       result.str = resultstring;
0525       result.content = 1;
0526       pthread_mutex_unlock(&M_output);
0527       return &result;
0528       break;
0529 
0530     case DAQ_BEGIN_IMMEDIATE:
0531       result.status = daq_begin_immediate (  ab->ipar[0], outputstream);
0532       outputstream.str().copy(resultstring,outputstream.str().size());
0533       resultstring[outputstream.str().size()] = 0;
0534       result.str = resultstring;
0535       result.content = 1;
0536       pthread_mutex_unlock(&M_output);
0537       return &result;
0538       break;
0539 
0540     case DAQ_END:
0541       result.status = daq_end_interactive(outputstream);
0542       outputstream.str().copy(resultstring,outputstream.str().size());
0543       resultstring[outputstream.str().size()] = 0;
0544       result.str = resultstring;
0545       result.content = 1;
0546       pthread_mutex_unlock(&M_output);
0547       return &result;
0548       break;
0549 
0550     case DAQ_END_IMMEDIATE:
0551       result.status = daq_end_immediate(outputstream);
0552       outputstream.str().copy(resultstring,outputstream.str().size());
0553       resultstring[outputstream.str().size()] = 0;
0554       result.str = resultstring;
0555       result.content = 1;
0556       pthread_mutex_unlock(&M_output);
0557       return &result;
0558       break;
0559 
0560     case DAQ_RUNNUMBERFILE:
0561       daq_set_runnumberfile(ab->spar, ab->ipar[0]);
0562       break;
0563 
0564     case DAQ_SETRUNNUMBERAPP:
0565       daq_set_runnumberApp(ab->spar, ab->ipar[0]);
0566       break;
0567 
0568     case DAQ_SETFILERULE:
0569       result.status = daq_set_filerule(ab->spar, outputstream);
0570       if ( result.status)
0571     {
0572       outputstream.str().copy(resultstring,outputstream.str().size());
0573       resultstring[outputstream.str().size()] = 0;
0574       result.str = resultstring;
0575       result.content = 1;
0576     }
0577       pthread_mutex_unlock(&M_output);
0578       return &result;
0579       break;
0580 
0581     case DAQ_SETNAME:
0582       daq_set_name(ab->spar);
0583       break;
0584 
0585 #ifdef HAVE_MOSQUITTO_H
0586       
0587     case DAQ_SET_MQTT_HOST:
0588       result.status = daq_set_mqtt_host(ab->spar, ab->ipar[0], outputstream);
0589       if ( result.status)
0590     {
0591       outputstream.str().copy(resultstring,outputstream.str().size());
0592       resultstring[outputstream.str().size()] = 0;
0593       result.str = resultstring;
0594       result.content = 1;
0595     }
0596       pthread_mutex_unlock(&M_output);
0597       return &result;
0598       break;
0599 
0600 
0601     case DAQ_GET_MQTT_HOST:
0602       result.status = daq_get_mqtt_host(outputstream);
0603       outputstream.str().copy(resultstring,outputstream.str().size());
0604       resultstring[outputstream.str().size()] = 0;
0605       result.str = resultstring;
0606       result.content = 1;
0607       pthread_mutex_unlock(&M_output);
0608       return &result;
0609       break;
0610 #endif
0611       
0612     case DAQ_SETRUNTYPE:
0613       result.status = daq_setruntype(ab->spar,outputstream);
0614       if ( result.status)
0615     {
0616       outputstream.str().copy(resultstring,outputstream.str().size());
0617       resultstring[outputstream.str().size()] = 0;
0618       result.str = resultstring;
0619       result.content = 1;
0620     }
0621       pthread_mutex_unlock(&M_output);
0622       return &result; 
0623       break;
0624 
0625     case DAQ_GETRUNTYPE:
0626       result.status = daq_getruntype(ab->ipar[0], outputstream);
0627       outputstream.str().copy(resultstring,outputstream.str().size());
0628       resultstring[outputstream.str().size()] = 0;
0629       result.str = resultstring;
0630       result.content = 1;
0631       pthread_mutex_unlock(&M_output);
0632       return &result;
0633       break;
0634 
0635     case DAQ_DEFINERUNTYPE:
0636       daq_define_runtype(ab->spar, ab->spar2);
0637       break;
0638 
0639     case DAQ_LISTRUNTYPES:
0640       result.status = daq_list_runtypes(ab->ipar[0], outputstream);
0641       outputstream.str().copy(resultstring,outputstream.str().size());
0642       resultstring[outputstream.str().size()] = 0;
0643       result.str = resultstring;
0644       result.content = 1;
0645       pthread_mutex_unlock(&M_output);
0646       return &result;
0647       break;
0648 
0649     case DAQ_GETNAME:
0650       result.status = daq_get_name(outputstream);
0651       outputstream.str().copy(resultstring,outputstream.str().size());
0652       resultstring[outputstream.str().size()] = 0;
0653       result.str = resultstring;
0654       result.content = 1;
0655       pthread_mutex_unlock(&M_output);
0656       return &result;
0657       break;
0658 
0659       
0660     case DAQ_OPEN:
0661       result.status = daq_open(outputstream);
0662       if (result.status) 
0663     {
0664       outputstream.str().copy(resultstring,outputstream.str().size());
0665       resultstring[outputstream.str().size()] = 0;
0666       result.str = resultstring;
0667       result.content = 1;
0668     }
0669       pthread_mutex_unlock(&M_output);
0670       return &result;
0671       break;
0672 
0673     case DAQ_SET_SERVER:
0674       result.status = daq_set_server(ab->spar, ab->ipar[0], outputstream);
0675       if (result.status) 
0676     {
0677       outputstream.str().copy(resultstring,outputstream.str().size());
0678       resultstring[outputstream.str().size()] = 0;
0679       result.str = resultstring;
0680       result.content = 1;
0681     }
0682       pthread_mutex_unlock(&M_output);
0683       return &result;
0684       break;
0685 
0686     case DAQ_CLOSE:
0687       result.status = daq_close(outputstream);
0688       if (result.status) 
0689     {
0690       outputstream.str().copy(resultstring,outputstream.str().size());
0691       resultstring[outputstream.str().size()] = 0;
0692       result.str = resultstring;
0693       result.content = 1;
0694     }
0695       pthread_mutex_unlock(&M_output);
0696       return &result;
0697       break;
0698 
0699     case DAQ_SET_COMPRESSION:
0700       result.status = daq_set_compression (  ab->ipar[0], outputstream);
0701       outputstream.str().copy(resultstring,outputstream.str().size());
0702       resultstring[outputstream.str().size()] = 0;
0703       result.str = resultstring;
0704       result.content = 1;
0705       pthread_mutex_unlock(&M_output);
0706       return &result;
0707       break;
0708 
0709     case DAQ_SET_NR_THREADS:
0710       result.status = 0; //daq_set_nr_threads (  ab->ipar[0], outputstream);
0711       // outputstream.str().copy(resultstring,outputstream.str().size());
0712       // resultstring[outputstream.str().size()] = 0;
0713       // result.str = resultstring;
0714       // result.content = 1;
0715       pthread_mutex_unlock(&M_output);
0716       return &result;
0717       break;
0718 
0719 
0720     case DAQ_SET_MD5ENABLE:
0721       result.status = daq_set_md5enable (  ab->ipar[0], outputstream);
0722       outputstream.str().copy(resultstring,outputstream.str().size());
0723       resultstring[outputstream.str().size()] = 0;
0724       result.str = resultstring;
0725       result.content = 1;
0726       pthread_mutex_unlock(&M_output);
0727       return &result;
0728       break;
0729 
0730     case DAQ_SET_MD5ALLOWTURNOFF:
0731       result.status = daq_set_md5allowturnoff (  ab->ipar[0], outputstream);
0732       outputstream.str().copy(resultstring,outputstream.str().size());
0733       resultstring[outputstream.str().size()] = 0;
0734       result.str = resultstring;
0735       result.content = 1;
0736       pthread_mutex_unlock(&M_output);
0737       return &result;
0738       break;
0739 
0740 
0741       
0742     case DAQ_FAKETRIGGER:
0743       result.status =  daq_fake_trigger (ab->ipar[0], ab->ipar[1]);
0744       break;
0745 
0746     case DAQ_LISTREADLIST:
0747       result.status = daq_list_readlist(outputstream);
0748       outputstream.str().copy(resultstring,outputstream.str().size());
0749       resultstring[outputstream.str().size()] = 0;
0750       result.str = resultstring;
0751       result.content = 1;
0752       pthread_mutex_unlock(&M_output);
0753       return &result;
0754       break;
0755 
0756     case DAQ_CLEARREADLIST:
0757       result.status = daq_clear_readlist(outputstream);
0758       outputstream.str().copy(resultstring,outputstream.str().size());
0759       resultstring[outputstream.str().size()] = 0;
0760       result.str = resultstring;
0761       result.content = 1;
0762       pthread_mutex_unlock(&M_output);
0763       return &result;
0764       break;
0765 
0766     case DAQ_STATUS:
0767       result.status = daq_status(ab->ipar[0], outputstream);
0768       outputstream.str().copy(resultstring,outputstream.str().size());
0769       resultstring[outputstream.str().size()] = 0;
0770       result.str = resultstring;
0771       result.content = 1;
0772       pthread_mutex_unlock(&M_output);
0773       return &result;
0774       break;
0775 
0776     case DAQ_SETMAXEVENTS:
0777       result.status = daq_setmaxevents (  ab->ipar[0], outputstream);
0778       if (result.status) 
0779     {
0780       outputstream.str().copy(resultstring,outputstream.str().size());
0781       resultstring[outputstream.str().size()] = 0;
0782       result.str = resultstring;
0783       result.content = 1;
0784     }
0785       pthread_mutex_unlock(&M_output);
0786       return &result;
0787       break;
0788 
0789     case DAQ_SETMAXVOLUME:
0790       result.status = daq_setmaxvolume (  ab->ipar[0], outputstream);
0791       if (result.status) 
0792     {
0793       outputstream.str().copy(resultstring,outputstream.str().size());
0794       resultstring[outputstream.str().size()] = 0;
0795       result.str = resultstring;
0796       result.content = 1;
0797     }
0798       pthread_mutex_unlock(&M_output);
0799       return &result;
0800       break;
0801 
0802     case DAQ_ROLLOVERLIMIT:
0803       result.status = daq_setrolloverlimit (  ab->ipar[0], outputstream);
0804       if (result.status) 
0805     {
0806       outputstream.str().copy(resultstring,outputstream.str().size());
0807       resultstring[outputstream.str().size()] = 0;
0808       result.str = resultstring;
0809       result.content = 1;
0810     }
0811       pthread_mutex_unlock(&M_output);
0812       return &result;
0813       break;
0814 
0815     case DAQ_SETMAXBUFFERSIZE:
0816       result.status = daq_setmaxbuffersize (  ab->ipar[0], outputstream);
0817       if (result.status) 
0818     {
0819       outputstream.str().copy(resultstring,outputstream.str().size());
0820       resultstring[outputstream.str().size()] = 0;
0821       result.str = resultstring;
0822       result.content = 1;
0823     }
0824       pthread_mutex_unlock(&M_output);
0825       return &result;
0826       break;
0827 
0828     case DAQ_SETADAPTIVEBUFFER:
0829       result.status = daq_setadaptivebuffering (  ab->ipar[0], outputstream);
0830       if (result.status) 
0831     {
0832       outputstream.str().copy(resultstring,outputstream.str().size());
0833       resultstring[outputstream.str().size()] = 0;
0834       result.str = resultstring;
0835       result.content = 1;
0836     }
0837       pthread_mutex_unlock(&M_output);
0838       return &result;
0839       break;
0840 
0841 
0842     case DAQ_ELOG:
0843       daq_set_eloghandler( ab->spar,  ab->ipar[0], ab->spar2);
0844       break;
0845 
0846     case DAQ_LOAD:
0847       result.status = daq_load_plugin( ab->spar, outputstream );
0848       if (result.status) 
0849     {
0850       outputstream.str().copy(resultstring,outputstream.str().size());
0851       resultstring[outputstream.str().size()] = 0;
0852       result.str = resultstring;
0853       result.content = 1;
0854     }
0855       pthread_mutex_unlock(&M_output);
0856       return &result;
0857       break;
0858 
0859     case DAQ_WEBCONTROL:
0860       result.status = daq_webcontrol (  ab->ipar[0], outputstream);
0861       outputstream.str().copy(resultstring,outputstream.str().size());
0862       resultstring[outputstream.str().size()] = 0;
0863       result.str = resultstring;
0864       result.content = 1;
0865       pthread_mutex_unlock(&M_output);
0866       return &result;
0867       break;
0868 
0869     case DAQ_GETLASTFILENAME:
0870       result.status = daq_getlastfilename ( outputstream);
0871       if ( result.status )
0872     {
0873       pthread_mutex_unlock(&M_output);
0874       result.content = 0;
0875       return &result;
0876     }
0877       outputstream.str().copy(resultstring,outputstream.str().size());
0878       resultstring[outputstream.str().size()] = 0;
0879       result.str = resultstring;
0880       result.content = 1;
0881       pthread_mutex_unlock(&M_output);
0882       return &result;
0883       break;
0884 
0885     case DAQ_GETLASTEVENTNUMBER:
0886       result.what = daq_getlastevent_number ( outputstream);
0887       outputstream.str().copy(resultstring,outputstream.str().size());
0888       resultstring[outputstream.str().size()] = 0;
0889       result.str = resultstring;
0890       result.content = 1;
0891       result.status = 0;
0892       pthread_mutex_unlock(&M_output);
0893       return &result;
0894       break;
0895 
0896     case DAQ_SETEVENTFORMAT:
0897       result.status = daq_setEventFormat ( ab->ipar[0], outputstream);
0898       if (result.status) 
0899     {
0900       outputstream.str().copy(resultstring,outputstream.str().size());
0901       resultstring[outputstream.str().size()] = 0;
0902       result.str = resultstring;
0903       result.content = 1;
0904     }
0905       pthread_mutex_unlock(&M_output);
0906       return &result;
0907       break;
0908 
0909     case DAQ_SET_RUNCONTROLMODE:
0910       result.status = daq_setRunControlMode ( ab->ipar[0], outputstream);
0911       if (result.status) 
0912     {
0913       outputstream.str().copy(resultstring,outputstream.str().size());
0914       resultstring[outputstream.str().size()] = 0;
0915       result.str = resultstring;
0916       result.content = 1;
0917     }
0918       pthread_mutex_unlock(&M_output);
0919       return &result;
0920       break;
0921 
0922     case DAQ_GET_RUNCONTROLMODE:
0923       result.status = daq_getRunControlMode (outputstream);
0924       outputstream.str().copy(resultstring,outputstream.str().size());
0925       resultstring[outputstream.str().size()] = 0;
0926       result.str = resultstring;
0927       result.content = 1;
0928       pthread_mutex_unlock(&M_output);
0929       return &result;
0930       break;
0931 
0932     case DAQ_SET_USERVALUE:
0933       result.status = daq_set_uservalue (  ab->ipar[0], ab->ipar[1],  outputstream);
0934       if ( result.status)
0935     {
0936       outputstream.str().copy(resultstring,outputstream.str().size());
0937       resultstring[outputstream.str().size()] = 0;
0938       result.str = resultstring;
0939       result.content = 1;
0940     }
0941       pthread_mutex_unlock(&M_output);
0942       return &result;
0943       break;
0944 
0945     case DAQ_GET_USERVALUE:
0946       result.status = daq_get_uservalue (  ab->ipar[0],  outputstream);
0947       outputstream.str().copy(resultstring,outputstream.str().size());
0948       resultstring[outputstream.str().size()] = 0;
0949       result.str = resultstring;
0950       result.content = 1;
0951       pthread_mutex_unlock(&M_output);
0952       return &result;
0953       break;
0954 
0955       
0956     default:
0957       strcpy(resultstring, "Unknown action");
0958       result.content = 1;
0959       result.status = 1;
0960       break;
0961 
0962     }
0963   
0964   pthread_mutex_unlock(&M_output);
0965   return &result;
0966   
0967 
0968 }
0969 
0970 shortResult * r_shutdown_1_svc(void *x, struct svc_req *rqstp)
0971 {
0972 
0973   static shortResult  result;
0974   
0975   static std::ostringstream outputstream;
0976   
0977   static char resultstring[256];
0978 
0979   pthread_mutex_lock(&M_output);
0980 
0981   
0982   result.content = 0;
0983   result.what = 0;
0984   result.status = 0;
0985 
0986   outputstream.str("");
0987 
0988   result.str = (char *) outputstream.str().c_str();
0989 
0990   result.status = daq_shutdown ( my_servernumber, RCDAQ_VERS, pid_fd, outputstream);
0991   cout << "daq_shutdown status = " << result.status  << endl;
0992   if (result.status) 
0993     {
0994       outputstream.str().copy(resultstring,outputstream.str().size());
0995       resultstring[outputstream.str().size()] = 0;
0996       result.str = resultstring;
0997       result.content = 1;
0998     }
0999   pthread_mutex_unlock(&M_output);
1000   return &result;
1001 
1002 }
1003 
1004 //-------------------------------------------------------------
1005 
1006 
1007 int
1008 main (int argc, char **argv)
1009 {
1010 
1011   int servernumber = 0;
1012 
1013   mode_t mask = umask(0);
1014   int i = mkdir ( "/tmp/rcdaq", 0777);
1015   if ( i && errno != EEXIST)
1016     {
1017       std::cerr << "Error accessing the lock directory /tmp/rcdaq" << std::endl;
1018       return 2;
1019     }
1020 
1021   umask(mask);
1022   
1023   if ( argc > 1)
1024     {
1025       servernumber = get_value(argv[1]);
1026     }
1027 
1028   char *pidfilename = obtain_pidfilename();
1029   
1030   sprintf (pidfilename, "/tmp/rcdaq/rcdaq_%d", servernumber);
1031 
1032   pid_fd = open(pidfilename, O_CREAT | O_RDWR, 0666);
1033   if ( pid_fd < 0)
1034     {
1035 
1036       ifstream pidfile = ifstream(pidfilename);
1037       if ( pidfile.is_open())
1038     {
1039       int ipid;
1040       pidfile >> ipid;
1041       std::cerr << "Another server is already running, PID= " << ipid << std::endl;
1042       return 2;
1043     }
1044   
1045       std::cerr << "Error creating the lock file" << std::endl;
1046       return 2;
1047     }
1048   
1049   int rc = flock(pid_fd, LOCK_EX | LOCK_NB);
1050   if(rc)
1051     {
1052       if (errno == EWOULDBLOCK)
1053     {
1054       ifstream pidfile = ifstream(pidfilename);
1055       if ( pidfile.is_open())
1056         {
1057           int ipid;
1058           pidfile >> ipid;
1059           std::cerr << "Another server is already running, PID= " << ipid << std::endl;
1060           return 3;
1061         }
1062       
1063       std::cerr << "Another server is already running" << std::endl;
1064       return 3;
1065     }
1066     }
1067 
1068   // we write out pid in here, for good measure
1069   char pid[64];
1070   int x = sprintf(pid,"%d\n", getpid());
1071   write (pid_fd, pid, x);
1072   
1073   
1074   std::cout << "Server number is " << servernumber << std::endl;
1075 
1076   signal(SIGKILL, sig_handler);
1077   signal(SIGTERM, sig_handler);
1078   signal(SIGINT,  sig_handler);
1079   
1080   
1081   pthread_mutex_init(&M_output, 0); 
1082 
1083   rcdaq_init( servernumber, M_output);
1084 
1085   my_servernumber = RCDAQ+servernumber;  // remember who we are for later
1086 
1087   SVCXPRT *transp;
1088   
1089   pmap_unset (my_servernumber, RCDAQ_VERS);
1090 
1091   transp = svctcp_create(RPC_ANYSOCK, 0, 0);
1092   if (transp == NULL) {
1093     fprintf (stderr, "%s", "cannot create tcp service.");
1094     exit(1);
1095   }
1096   if (!svc_register(transp, my_servernumber, RCDAQ_VERS, rcdaq_1, IPPROTO_TCP)) {
1097     fprintf (stderr, "%s", "unable to register (RCDAQ+servernumber, RCDAQ_VERS, tcp).");
1098     exit(1);
1099   }
1100 
1101   // char hostname[1024];
1102   // gethostname(hostname, 1024);
1103   // daq_set_name(hostname);
1104 
1105   svc_run ();
1106   fprintf (stderr, "%s", "svc_run returned");
1107   exit (1);
1108   /* NOTREACHED */
1109 }
1110