XrdProtLoad.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                        X r d P r o t L o a d . c c                         */
00004 /*                                                                            */
00005 /* (c) 2006 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*       All Rights Reserved. See XrdInfo.cc for complete License Terms       */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*              DE-AC03-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010 
00011 //        $Id: XrdProtLoad.cc 29874 2009-08-21 16:56:04Z ganis $  
00012 
00013 const char *XrdProtLoadCVSID = "$Id: XrdProtLoad.cc 29874 2009-08-21 16:56:04Z ganis $";
00014 
00015 #include "XrdSys/XrdSysError.hh"
00016 #include "XrdSys/XrdSysPlugin.hh"
00017 
00018 #include "Xrd/XrdLink.hh"
00019 #include "Xrd/XrdPoll.hh"
00020 #include "Xrd/XrdProtLoad.hh"
00021 #include "Xrd/XrdTrace.hh"
00022  
00023 /******************************************************************************/
00024 /*                        G l o b a l   O b j e c t s                         */
00025 /******************************************************************************/
00026 
00027 extern XrdSysError XrdLog;
00028 
00029 extern XrdOucTrace XrdTrace;
00030 
00031 XrdProtocol *XrdProtLoad::ProtoWAN[ProtoMax] = {0};
00032 XrdProtocol *XrdProtLoad::Protocol[ProtoMax] = {0};
00033 char        *XrdProtLoad::ProtName[ProtoMax] = {0};
00034 int          XrdProtLoad::ProtPort[ProtoMax] = {0};
00035 
00036 int          XrdProtLoad::ProtoCnt = 0;
00037 int          XrdProtLoad::ProtWCnt = 0;
00038 
00039 char         *XrdProtLoad::liblist[ProtoMax];
00040 XrdSysPlugin *XrdProtLoad::libhndl[ProtoMax];
00041 
00042 int           XrdProtLoad::libcnt = 0;
00043 
00044 /******************************************************************************/
00045 /*            C o n s t r u c t o r   a n d   D e s t r u c t o r             */
00046 /******************************************************************************/
00047   
00048  XrdProtLoad::XrdProtLoad(int port) :
00049               XrdProtocol("protocol loader") {myPort = port;}
00050 
00051  XrdProtLoad::~XrdProtLoad() {}
00052  
00053 /******************************************************************************/
00054 /*                                  L o a d                                   */
00055 /******************************************************************************/
00056 
00057 int XrdProtLoad::Load(const char *lname, const char *pname,
00058                       char *parms, XrdProtocol_Config *pi)
00059 {
00060    XrdProtocol *xp;
00061    int i, j, port = pi->Port;
00062    int wanopt = pi->WANPort;
00063 
00064 // Trace this load if so wanted
00065 //
00066    if (TRACING(TRACE_DEBUG))
00067       {XrdTrace.Beg("Protocol");
00068        cerr <<"getting protocol object " <<pname;
00069        XrdTrace.End();
00070       }
00071 
00072 // First check to see that we haven't exceeded our protocol count
00073 //
00074    if (ProtoCnt >= ProtoMax)
00075       {XrdLog.Emsg("Protocol", "Too many protocols have been defined.");
00076        return 0;
00077       }
00078 
00079 // Obtain an instance of this protocol
00080 //
00081    if (lname)  xp =    getProtocol(lname, pname, parms, pi);
00082       else     xp = XrdgetProtocol(pname, parms, pi);
00083    if (!xp) {XrdLog.Emsg("Protocol","Protocol", pname, "could not be loaded");
00084              return 0;
00085             }
00086 
00087 // If this is a WAN enabled protocol then add it to the WAN table
00088 //
00089    if (wanopt) ProtoWAN[ProtWCnt++] = xp;
00090 
00091 // Find a port associated slot in the table
00092 //
00093    for (i = ProtoCnt-1; i >= 0; i--) if (port == ProtPort[i]) break;
00094    for (j = ProtoCnt-1; j > i; j--)
00095        {ProtName[j+1] = ProtName[j];
00096         ProtPort[j+1] = ProtPort[j];
00097         Protocol[j+1] = Protocol[j];
00098        }
00099 
00100 // Add protocol to our table of protocols
00101 //
00102    ProtName[j+1] = strdup(pname);
00103    ProtPort[j+1] = port;
00104    Protocol[j+1] = xp;
00105    ProtoCnt++;
00106    return 1;
00107 }
00108   
00109 /******************************************************************************/
00110 /*                                  P o r t                                   */
00111 /******************************************************************************/
00112 
00113 int XrdProtLoad::Port(const char *lname, const char *pname,
00114                       char *parms, XrdProtocol_Config *pi)
00115 {
00116    int port;
00117 
00118 // Trace this load if so wanted
00119 //
00120    if (TRACING(TRACE_DEBUG))
00121       {XrdTrace.Beg("Protocol");
00122        cerr <<"getting port from protocol " <<pname;
00123        XrdTrace.End();
00124       }
00125 
00126 // Obtain the port number to be used by this protocol
00127 //
00128    if (lname)  port =    getProtocolPort(lname, pname, parms, pi);
00129       else     port = XrdgetProtocolPort(pname, parms, pi);
00130    if (port < 0) XrdLog.Emsg("Protocol","Protocol", pname,
00131                              "port number could not be determined");
00132    return port;
00133 }
00134   
00135 /******************************************************************************/
00136 /*                               P r o c e s s                                */
00137 /******************************************************************************/
00138   
00139 int XrdProtLoad::Process(XrdLink *lp)
00140 {
00141      XrdProtocol *pp = 0;
00142      int i;
00143 
00144 // Check if this is a WAN lookup or standard lookup
00145 //
00146    if (myPort < 0)
00147       {for (i = 0; i < ProtWCnt; i++)
00148            if ((pp = ProtoWAN[i]->Match(lp))) break;
00149               else if (lp->isFlawed()) return -1;
00150       } else {
00151        for (i = 0; i < ProtoCnt; i++)
00152            if (myPort == ProtPort[i] && (pp = Protocol[i]->Match(lp))) break;
00153                else if (lp->isFlawed()) return -1;
00154       }
00155    if (!pp) {lp->setEtext("matching protocol not found"); return -1;}
00156 
00157 // Now attach the new protocol object to the link
00158 //
00159    lp->setProtocol(pp);
00160 
00161 // Trace this load if so wanted
00162 //                                                x
00163    if (TRACING(TRACE_DEBUG))
00164       {XrdTrace.Beg("Protocol");
00165        cerr <<"matched protocol " <<ProtName[i];
00166        XrdTrace.End();
00167       }
00168 
00169 // Attach this link to the appropriate poller
00170 //
00171    if (!XrdPoll::Attach(lp)) {lp->setEtext("attach failed"); return -1;}
00172 
00173 // Take a short-cut and process the initial request as a sticky request
00174 //
00175    return pp->Process(lp);
00176 }
00177  
00178 /******************************************************************************/
00179 /*                               R e c y c l e                                */
00180 /******************************************************************************/
00181   
00182 void XrdProtLoad::Recycle(XrdLink *lp, int ctime, const char *reason)
00183 {
00184 
00185 // Document non-protocol errors
00186 //
00187    if (lp && reason)
00188       XrdLog.Emsg("Protocol", lp->ID, "terminated", reason);
00189 }
00190 
00191 /******************************************************************************/
00192 /*                                 S t a t s                                  */
00193 /******************************************************************************/
00194 
00195 int XrdProtLoad::Stats(char *buff, int blen, int do_sync)
00196 {
00197     int i, k, totlen = 0;
00198 
00199     for (i = 0; i < ProtoCnt && (blen > 0 || !buff); i++)
00200         {k = Protocol[i]->Stats(buff, blen, do_sync);
00201          totlen += k; buff += k; blen -= k;
00202         }
00203 
00204     return totlen;
00205 }
00206 
00207 /******************************************************************************/
00208 /*                       P r i v a t e   M e t h o d s                        */
00209 /******************************************************************************/
00210 /******************************************************************************/
00211 /*                           g e t P r o t o c o l                            */
00212 /******************************************************************************/
00213   
00214 XrdProtocol *XrdProtLoad::getProtocol(const char *lname,
00215                                       const char *pname,
00216                                             char *parms,
00217                               XrdProtocol_Config *pi)
00218 {
00219    XrdProtocol *(*ep)(const char *, char *, XrdProtocol_Config *);
00220    void *epvoid;
00221    int i;
00222 
00223 // Find the matching library. It must be here because getPort was already called
00224 //
00225    for (i = 0; i < libcnt; i++) if (!strcmp(lname, liblist[i])) break;
00226    if (i >= libcnt)
00227       {XrdLog.Emsg("Protocol", pname, "was lost during loading", lname);
00228        return 0;
00229       }
00230 
00231 // Obtain an instance of the protocol object and return it
00232 //
00233    if (!(epvoid = libhndl[i]->getPlugin("XrdgetProtocol"))) return 0;
00234    ep = (XrdProtocol *(*)(const char*,char*,XrdProtocol_Config*))epvoid;
00235    return ep(pname, parms, pi);
00236 }
00237 
00238 /******************************************************************************/
00239 /*                       g e t P r o t o c o l P o r t                        */
00240 /******************************************************************************/
00241   
00242 int XrdProtLoad::getProtocolPort(const char *lname,
00243                                  const char *pname,
00244                                        char *parms,
00245                          XrdProtocol_Config *pi)
00246 {
00247    int (*ep)(const char *, char *, XrdProtocol_Config *);
00248    void *epvoid;
00249    int i;
00250 
00251 // See if the library is already opened, if not open it
00252 //
00253    for (i = 0; i < libcnt; i++) if (!strcmp(lname, liblist[i])) break;
00254    if (i >= libcnt)
00255       {if (libcnt >= ProtoMax)
00256           {XrdLog.Emsg("Protocol", "Too many protocols have been defined.");
00257            return -1;
00258           }
00259        if (!(libhndl[i] = new XrdSysPlugin(&XrdLog, lname))) return -1;
00260        liblist[i] = strdup(lname);
00261        libcnt++;
00262       }
00263 
00264 // Get the port number to be used
00265 //
00266    if (!(epvoid = libhndl[i]->getPlugin("XrdgetProtocolPort", 1))) 
00267       return (pi->Port < 0 ? 0 : pi->Port);
00268    ep = (int (*)(const char*,char*,XrdProtocol_Config*))epvoid;
00269    return ep(pname, parms, pi);
00270 }

Generated on Tue Jul 5 14:46:15 2011 for ROOT_528-00b_version by  doxygen 1.5.1