00001
00002
00003 const char *XrdSutBufferCVSID = "$Id: XrdSutBuffer.cc 30949 2009-11-02 16:37:58Z ganis $";
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <stdio.h>
00015 #include <string.h>
00016 #include <errno.h>
00017
00018 #include <XrdSec/XrdSecInterface.hh>
00019 #include <XrdOuc/XrdOucString.hh>
00020 #include <XrdSut/XrdSutBuffer.hh>
00021 #include <XrdSut/XrdSutTrace.hh>
00022
00023
00024
00025
00026
00027
00028
00029
00030 XrdSutBuffer::XrdSutBuffer(const char *buf, kXR_int32 len)
00031 {
00032
00033
00034
00035
00036
00037 EPNAME("Buffer::XrdSutBuffer");
00038
00039 bool ok = 1;
00040
00041
00042 fOptions = "";
00043 fProtocol = "";
00044 fStep = 0;
00045
00046
00047
00048 if (!strncmp(buf,"&P=",3)) {
00049
00050
00051
00052 int cur = 3;
00053 int k = 0;
00054 while (buf[cur+k] && buf[cur+k] != ',' &&
00055 k < XrdSecPROTOIDSIZE && (cur+k) < len) k++;
00056 if (!k) {
00057 PRINT("no protocol name - do nothing");
00058 } else {
00059
00060
00061 char proto[XrdSecPROTOIDSIZE];
00062 strncpy(proto,buf+cur,k);
00063 proto[k] = 0;
00064 fProtocol = proto;
00065 cur += (k+1);
00066
00067
00068 if (cur < len) {
00069 k = 0;
00070 while ((cur+k) < len && buf[cur+k])
00071 k++;
00072 if (k) {
00073 char *opts = new char[k+1];
00074 if (opts) {
00075 strncpy(opts,buf+cur,k);
00076 opts[k] = 0;
00077 fOptions = opts;
00078 delete[] opts;
00079 }
00080 }
00081 cur += (k+1);
00082 }
00083 }
00084
00085 } else {
00086
00087
00088
00089 int k = 0;
00090 while (buf[k] && k < XrdSecPROTOIDSIZE && k < len) { k++; }
00091 if (!k || k == XrdSecPROTOIDSIZE) {
00092 PRINT("no protocol name: do nothing");
00093 ok = 0;
00094 }
00095 int cur = k+1;
00096 if (ok) {
00097
00098
00099 char proto[XrdSecPROTOIDSIZE];
00100 strcpy(proto,buf);
00101 fProtocol = proto;
00102
00103
00104
00105 kXR_int32 step;
00106 memcpy(&step,&buf[cur],sizeof(kXR_int32));
00107 fStep = ntohl(step);
00108 cur += sizeof(kXR_int32);
00109 }
00110
00111
00112
00113 int ltot = len - sizeof(kXR_int32);
00114 TRACE(Dump,"ltot: " <<ltot);
00115
00116
00117
00118 kXR_int32 type;
00119 kXR_int32 blen;
00120 XrdSutBucket *tmp = 0;
00121 char *buck = 0;
00122 while (ok) {
00123
00124
00125
00126 memcpy(&type,&buf[cur],sizeof(kXR_int32));
00127 type = ntohl(type);
00128 TRACE(Dump,"type: " <<XrdSutBuckStr(type));
00129
00130 if (type == kXRS_none) {
00131
00132
00133 ok = 0;
00134 } else {
00135
00136 cur += sizeof(kXR_int32);
00137
00138
00139 memcpy(&blen,&buf[cur],sizeof(kXR_int32));
00140 blen = ntohl(blen);
00141 TRACE(Dump,"blen: " <<blen);
00142
00143 cur += sizeof(kXR_int32);
00144 TRACE(Dump,"cur: " <<cur);
00145 if ((cur-1+blen) > ltot)
00146 ok = 0;
00147 else {
00148
00149
00150 if (type != kXRS_inactive){
00151
00152
00153 if ((buck = new char[blen])) {
00154 memcpy(buck,&buf[cur],blen);
00155 if ((tmp = new XrdSutBucket(buck,blen,type))) {
00156 fBuckets.PushBack(tmp);
00157 } else {
00158 PRINT("error creating bucket: "<<XrdSutBuckStr(type)
00159 <<" (size: "<<blen<<", !buck:"<<(!buck)<<")");
00160 }
00161 } else {
00162 PRINT("error allocating buffer for bucket: "
00163 <<XrdSutBuckStr(type)<<" (size:"<<blen<<")");
00164 }
00165 }
00166 cur += blen;
00167 }
00168 }
00169 }
00170 }
00171 }
00172
00173
00174 XrdSutBuffer::~XrdSutBuffer()
00175 {
00176
00177
00178 EPNAME("Buffer::~XrdSutBuffer");
00179
00180 XrdSutBucket *bp = fBuckets.Begin();
00181 while (bp) {
00182 TRACE(Dump,"type: " << bp->type);
00183 delete bp;
00184
00185 bp = fBuckets.Next();
00186 }
00187 }
00188
00189
00190 int XrdSutBuffer::UpdateBucket(const char *b, int sz, int ty)
00191 {
00192
00193
00194
00195 EPNAME("Buffer::UpdateBucket");
00196
00197 XrdSutBucket *bp = GetBucket(ty);
00198 if (!bp) {
00199 bp = new XrdSutBucket(0,0,ty);
00200 if (!bp) {
00201 DEBUG("Out-Of-Memory allocating bucket");
00202 return -1;
00203 }
00204 AddBucket(bp);
00205 }
00206 bp->SetBuf(b,sz);
00207
00208 return 0;
00209 }
00210
00211
00212 int XrdSutBuffer::UpdateBucket(XrdOucString s, int ty)
00213 {
00214
00215
00216
00217
00218 return UpdateBucket(s.c_str(),s.length(),ty);
00219 }
00220
00221
00222 void XrdSutBuffer::Dump(const char *stepstr)
00223 {
00224
00225 EPNAME("Buffer::Dump");
00226
00227 PRINT("//-----------------------------------------------------//");
00228 PRINT("// //")
00229 PRINT("// XrdSutBuffer DUMP //")
00230 PRINT("// //")
00231
00232 int nbuck = fBuckets.Size();
00233
00234 PRINT("// Buffer : " <<this);
00235 PRINT("// ");
00236 PRINT("// Proto : " <<fProtocol.c_str());
00237 if (fOptions.length()) {
00238 PRINT("// Options : " <<fOptions.c_str());
00239 } else {
00240 PRINT("// Options : none");
00241 }
00242 if (stepstr) {
00243 PRINT("// Step : " <<stepstr);
00244 } else {
00245 PRINT("// Step : " <<fStep);
00246 }
00247 PRINT("// # of buckets : " <<nbuck);
00248 PRINT("// ");
00249
00250 int kb = 0;
00251 XrdSutBucket *bp = fBuckets.Begin();
00252 while (bp) {
00253 PRINT("// ");
00254 PRINT("// buck: " <<kb++);
00255 bp->Dump(0);
00256
00257 bp = fBuckets.Next();
00258 }
00259 PRINT("// //")
00260 PRINT("//-----------------------------------------------------//");
00261 }
00262
00263
00264 void XrdSutBuffer::Message(const char *prepose)
00265 {
00266
00267
00268
00269 bool pripre = 0;
00270 if (prepose)
00271 pripre = 1;
00272
00273 XrdSutBucket *bp = fBuckets.Begin();
00274 while (bp) {
00275 if (bp->type == kXRS_message) {
00276 if (bp->size > 0 && bp->buffer) {
00277 if (pripre) {
00278 XrdOucString premsg(prepose);
00279 cerr << premsg << endl;
00280 pripre = 0;
00281 }
00282 XrdOucString msg(bp->buffer,bp->size);
00283 cerr << msg << endl;
00284 }
00285 }
00286
00287 bp = fBuckets.Next();
00288 }
00289 }
00290
00291
00292 kXR_int32 XrdSutBuffer::MarshalBucket(kXR_int32 type, kXR_int32 code)
00293 {
00294
00295
00296
00297
00298
00299 EPNAME("Buffer::MarshalBucket");
00300
00301
00302 kXR_int32 mcod = htonl(code);
00303
00304
00305 XrdSutBucket *bck = GetBucket(type);
00306 if (!bck) {
00307
00308 bck = new XrdSutBucket(0,0,type);
00309 if (!bck) {
00310 DEBUG("could not allocate new bucket of type:"<<XrdSutBuckStr(type));
00311 errno = ENOMEM;
00312 return -1;
00313 }
00314
00315 AddBucket(bck);
00316 }
00317
00318
00319 bck->SetBuf((char *)(&mcod),sizeof(kXR_int32));
00320
00321
00322 return 0;
00323 }
00324
00325
00326 kXR_int32 XrdSutBuffer::UnmarshalBucket(kXR_int32 type, kXR_int32 &code)
00327 {
00328
00329
00330
00331
00332
00333
00334 EPNAME("Buffer::UnmarshalBucket");
00335
00336 code = 0;
00337
00338 XrdSutBucket *bck = GetBucket(type);
00339 if (!bck) {
00340 DEBUG("could not find a bucket of type:"<<XrdSutBuckStr(type));
00341 errno = ENOENT;
00342 return -1;
00343 }
00344 if (bck->size != sizeof(kXR_int32)) {
00345 DEBUG("Wrong size: type:"<<XrdSutBuckStr(type)
00346 <<", size:"<<bck->size<<", expected:"<<sizeof(kXR_int32));
00347 errno = EINVAL;
00348 return -2;
00349 }
00350
00351
00352 memcpy(&code,bck->buffer,sizeof(kXR_int32));
00353
00354
00355 code = ntohl(code);
00356
00357
00358 return 0;
00359 }
00360
00361
00362 XrdSutBucket *XrdSutBuffer::GetBucket(kXR_int32 type, const char *tag)
00363 {
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 int ltag = (tag) ? strlen(tag) : 0;
00374
00375
00376 XrdSutBucket *bp = fBuckets.Begin();
00377 while (bp) {
00378 if (type == bp->type && (!tag || (ltag < bp->size &&
00379 !strncmp(bp->buffer,tag,ltag) &&
00380 (bp->buffer)[ltag] == '\0')))
00381 return bp;
00382
00383 bp = fBuckets.Next();
00384 }
00385
00386
00387 return 0;
00388 }
00389
00390
00391 void XrdSutBuffer::Deactivate(kXR_int32 type)
00392 {
00393
00394
00395
00396
00397
00398 XrdSutBucket *bp = fBuckets.Begin();
00399 while (bp) {
00400 if (type == bp->type) {
00401 bp->type = kXRS_inactive;
00402 break;
00403 } else if (type == -1) {
00404 bp->type = kXRS_inactive;
00405 }
00406
00407 bp = fBuckets.Next();
00408 }
00409 }
00410
00411
00412 int XrdSutBuffer::Serialized(char **buffer, char opt)
00413 {
00414
00415
00416
00417
00418
00419 EPNAME("Buffer::Serialized");
00420
00421
00422
00423 if (!buffer) {
00424 DEBUG("invalid input argument");
00425 errno = EINVAL;
00426 return -1;
00427 }
00428
00429
00430
00431 int blen = fProtocol.length() + 1 + 2*sizeof(kXR_int32);
00432
00433 XrdSutBucket *bp = fBuckets.Begin();
00434 while (bp) {
00435 if (bp->type != kXRS_inactive) {
00436 blen += 2*sizeof(kXR_int32);
00437 blen += bp->size;
00438 }
00439
00440 bp = fBuckets.Next();
00441 }
00442
00443
00444
00445 *buffer = (opt == 'n') ? (new char[blen]) : (char *)malloc(blen);
00446 if (!(*buffer))
00447 return -1;
00448 char *tbuf = *buffer;
00449 int cur = 0;
00450
00451
00452
00453 memcpy(tbuf,fProtocol.c_str(),fProtocol.length());
00454 tbuf[fProtocol.length()] = 0;
00455 cur += fProtocol.length() + 1;
00456
00457
00458
00459 kXR_int32 step = htonl(fStep);
00460 memcpy(tbuf+cur,&step,sizeof(kXR_int32));
00461 cur += sizeof(kXR_int32);
00462
00463
00464
00465 bp = fBuckets.Begin();
00466 while (bp) {
00467 if (bp->type != kXRS_inactive) {
00468 kXR_int32 type = htonl(bp->type);
00469 memcpy(tbuf+cur,&type,sizeof(kXR_int32));
00470 cur += sizeof(kXR_int32);
00471 kXR_int32 size = htonl(bp->size);
00472 memcpy(tbuf+cur,&size,sizeof(kXR_int32));
00473 cur += sizeof(kXR_int32);
00474 memcpy(tbuf+cur,bp->buffer,bp->size);
00475 cur += bp->size;
00476 }
00477
00478 bp = fBuckets.Next();
00479 }
00480
00481
00482
00483 kXR_int32 ltmp = htonl(kXRS_none);
00484 memcpy(tbuf+cur,<mp,sizeof(kXR_int32));
00485
00486
00487 return blen;
00488 }