~ubuntu-branches/ubuntu/utopic/gridengine/utopic

« back to all changes in this revision

Viewing changes to source/libs/cull/pack.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2008-06-25 22:36:13 UTC
  • Revision ID: james.westby@ubuntu.com-20080625223613-tvd9xlhuoct9kyhm
Tags: upstream-6.2~beta2
ImportĀ upstreamĀ versionĀ 6.2~beta2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*___INFO__MARK_BEGIN__*/
 
2
/*************************************************************************
 
3
 * 
 
4
 *  The Contents of this file are made available subject to the terms of
 
5
 *  the Sun Industry Standards Source License Version 1.2
 
6
 * 
 
7
 *  Sun Microsystems Inc., March, 2001
 
8
 * 
 
9
 * 
 
10
 *  Sun Industry Standards Source License Version 1.2
 
11
 *  =================================================
 
12
 *  The contents of this file are subject to the Sun Industry Standards
 
13
 *  Source License Version 1.2 (the "License"); You may not use this file
 
14
 *  except in compliance with the License. You may obtain a copy of the
 
15
 *  License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
 
16
 * 
 
17
 *  Software provided under this License is provided on an "AS IS" basis,
 
18
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 
19
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 
20
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 
21
 *  See the License for the specific provisions governing your rights and
 
22
 *  obligations concerning the Software.
 
23
 * 
 
24
 *   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 
25
 * 
 
26
 *   Copyright: 2001 by Sun Microsystems, Inc.
 
27
 * 
 
28
 *   All Rights Reserved.
 
29
 * 
 
30
 ************************************************************************/
 
31
/*___INFO__MARK_END__*/
 
32
 
 
33
#include "pack.h"
 
34
 
 
35
#include <stdio.h>
 
36
#include <string.h>
 
37
#include <stdlib.h>
 
38
#include <sys/types.h>
 
39
#include <netinet/in.h>
 
40
#include <rpc/rpc.h>
 
41
#include <rpc/types.h>
 
42
 
 
43
#if defined(INTERIX)
 
44
#include <arpa/inet.h>
 
45
#include "wingrid.h"
 
46
#endif
 
47
 
 
48
#ifdef HPUX
 
49
#include <arpa/inet.h>
 
50
#endif
 
51
 
 
52
/* do not compile in monitoring code */
 
53
#ifndef NO_SGE_COMPILE_DEBUG
 
54
#define NO_SGE_COMPILE_DEBUG
 
55
#endif
 
56
 
 
57
#include "basis_types.h"
 
58
#include "sgermon.h"
 
59
#include "cull_listP.h"
 
60
#include "sge_log.h"
 
61
#include "msg_cull.h"
 
62
#include "cull_state.h"
 
63
 
 
64
#include "uti/sge_stdlib.h"
 
65
 
 
66
#if 0
 
67
#   undef PACK_LAYER
 
68
#   define PACK_LAYER BASIS_LAYER
 
69
#endif
 
70
 
 
71
 
 
72
/****** cull/pack/--CULL_Packing ***************************************
 
73
*
 
74
*  NAME
 
75
*     CULL_Packing -- platform independent exchange format
 
76
*
 
77
*  FUNCTION
 
78
*     The cull packing functions provide a framework for a 
 
79
*     platform independent data representation.
 
80
*
 
81
*     Data is written into a packbuffer. Individual data words
 
82
*     are written in network byte order.
 
83
*
 
84
*     Data in the packbuffer can be compressed.
 
85
*
 
86
*  NOTES
 
87
*     Other platform independent formats, like XML, should be 
 
88
*     implemented.
 
89
*
 
90
*  SEE ALSO
 
91
*     cull/pack/-Versioncontrol
 
92
*
 
93
*     cull/pack/packbitfield()
 
94
*     cull/pack/unpackbitfield()
 
95
****************************************************************************
 
96
*/
 
97
 
 
98
/* -------------------------------
 
99
 
 
100
   get chunk_size
 
101
 
 
102
 */
 
103
int pack_get_chunk(void)
 
104
{
 
105
   return CHUNK;
 
106
}
 
107
 
 
108
/****** cull/pack/init_packbuffer() *******************************************
 
109
*  NAME
 
110
*     init_packbuffer() -- initialize packing buffer
 
111
*
 
112
*  SYNOPSIS
 
113
*     int init_packbuffer(sge_pack_buffer *pb, int initial_size, 
 
114
*                         int just_count) 
 
115
*
 
116
*  FUNCTION
 
117
*     Initialize a packing buffer.
 
118
*     Allocates the necessary memory. If more memory is needed during the use
 
119
*     of the packbuffer, it will be reallocated increasing the size by 
 
120
*     chunk_size (see function pack_set_chunk).
 
121
*
 
122
*     Since version 6.0, version information is provided in the packbuffer and 
 
123
*     is included in sent messages.
 
124
*     For best possible backward interoperability with former versions, an 
 
125
*     integer with value 0 is padded before the version information as first 
 
126
*     word in the packbuffer. This triggeres error handling in former versions.
 
127
*
 
128
*     Functions using packing buffers in GDI or related code should use the 
 
129
*     function sge_gdi_packet_get_pb_size() to find the correct
 
130
*     "initial_size".  
 
131
*
 
132
*  INPUTS
 
133
*     sge_pack_buffer *pb - the packbuffer to initialize
 
134
*     int initial_size    - the amount of memory to be allocated at 
 
135
*                           initialization.
 
136
*                           If a value of 0 is given as initial_size, a size 
 
137
*                           of chunk_size (global variable, see function 
 
138
*                           pack_set_chunk) will be used.
 
139
*     int just_count      - if true, no memory will be allocated and the 
 
140
*                           "just_count" property of the packbuffer will 
 
141
*                           be set.
 
142
*
 
143
*  RESULT
 
144
*     int - PACK_SUCCESS on success
 
145
*           PACK_ENOMEM  if memory allocation fails
 
146
*           PACK_FORMAT  if no valid packbuffer is passed
 
147
*
 
148
*  NOTES
 
149
*     MT-NOTE: init_packbuffer() is MT safe (assumptions)
 
150
*  
 
151
*  SEE ALSO
 
152
*     cull/pack/-Packing-typedefs
 
153
*     cull/pack/pack_set_chunk()
 
154
*     gdi/request_internal/sge_gdi_packet_get_pb_size()
 
155
*******************************************************************************/
 
156
int 
 
157
init_packbuffer(sge_pack_buffer *pb, int initial_size, int just_count) 
 
158
{
 
159
   DENTER(PACK_LAYER, "init_packbuffer");
 
160
 
 
161
   if (pb == NULL) {
 
162
      ERROR((SGE_EVENT, MSG_CULL_ERRORININITPACKBUFFER_S, MSG_CULL_PACK_FORMAT));
 
163
      DEXIT;
 
164
      return PACK_FORMAT;
 
165
   }   
 
166
 
 
167
   if (!just_count) {
 
168
      if (initial_size == 0) {
 
169
         initial_size = CHUNK;
 
170
      } else {
 
171
         initial_size += 2 * INTSIZE;  /* space for version information */
 
172
      }
 
173
      
 
174
      memset(pb, 0, sizeof(sge_pack_buffer));
 
175
 
 
176
      pb->head_ptr = malloc(initial_size);
 
177
      if (!pb->head_ptr) {
 
178
         ERROR((SGE_EVENT, MSG_CULL_NOTENOUGHMEMORY_D, initial_size));
 
179
         DEXIT;
 
180
         return PACK_ENOMEM;
 
181
      }
 
182
      pb->cur_ptr = pb->head_ptr;
 
183
      pb->mem_size = initial_size;
 
184
 
 
185
      pb->cur_ptr = pb->head_ptr;
 
186
      pb->mem_size = initial_size;
 
187
 
 
188
      pb->bytes_used = 0;
 
189
      pb->just_count = 0;
 
190
      pb->version = CULL_VERSION;
 
191
      packint(pb, 0);              /* pad 0 byte -> error handing in former versions */
 
192
      packint(pb, pb->version);    /* version information is included in buffer      */
 
193
   } else {
 
194
      pb->head_ptr = pb->cur_ptr = NULL;
 
195
      pb->mem_size = 0;
 
196
      pb->bytes_used = 0;
 
197
      pb->just_count = 1;
 
198
   }
 
199
 
 
200
   DRETURN(PACK_SUCCESS);
 
201
}
 
202
 
 
203
/**************************************************************
 
204
 initialize packing buffer out of a normal character buffer
 
205
 set read/write pointer to the beginning
 
206
 
 
207
 NOTES
 
208
    MT-NOTE: init_packbuffer_from_buffer() is MT safe (assumptions)
 
209
 **************************************************************/
 
210
int 
 
211
init_packbuffer_from_buffer(sge_pack_buffer *pb, char *buf, u_long32 buflen) 
 
212
{
 
213
   DENTER(PACK_LAYER, "init_packbuffer_from_buffer");
 
214
 
 
215
   if (!pb && !buf) {
 
216
      DRETURN(PACK_FORMAT);
 
217
   }   
 
218
 
 
219
   memset(pb, 0, sizeof(sge_pack_buffer));
 
220
 
 
221
   pb->head_ptr = buf;
 
222
   pb->cur_ptr = buf;
 
223
   pb->mem_size = buflen;
 
224
   pb->bytes_used = 0;
 
225
 
 
226
   /* check cull version (only if buffer contains any data) */
 
227
   if (buflen > 0) {
 
228
      int ret;
 
229
      u_long32 pad, version;
 
230
 
 
231
      if((ret = unpackint(pb, &pad)) != PACK_SUCCESS) {
 
232
         DEXIT;
 
233
         return ret;
 
234
      } 
 
235
 
 
236
      if((ret = unpackint(pb, &version)) != PACK_SUCCESS) {
 
237
         DEXIT;
 
238
         return ret;
 
239
      }
 
240
 
 
241
      if(pad != 0 || version != CULL_VERSION) {
 
242
         ERROR((SGE_EVENT, MSG_CULL_PACK_WRONG_VERSION_XX, (unsigned int) version, CULL_VERSION));
 
243
         DEXIT;
 
244
         return PACK_VERSION;
 
245
      }
 
246
 
 
247
      pb->version = version;
 
248
   } else {
 
249
      pb->version = CULL_VERSION;
 
250
   }
 
251
 
 
252
   DEXIT;
 
253
   return PACK_SUCCESS;
 
254
}
 
255
 
 
256
/**************************************************************/
 
257
/* MT-NOTE: clear_packbuffer() is MT safe */
 
258
void clear_packbuffer(sge_pack_buffer *pb) {
 
259
   if (pb != NULL) {
 
260
      FREE(pb->head_ptr);
 
261
   }
 
262
   return;
 
263
}
 
264
 
 
265
/*************************************************************
 
266
 look whether pb is filled
 
267
 *************************************************************/
 
268
int pb_filled(
 
269
sge_pack_buffer *pb 
 
270
) {
 
271
   /* do we have more bytes used than the version information? */
 
272
   return (pb_used(pb) > (2 * INTSIZE));
 
273
}
 
274
 
 
275
/*************************************************************
 
276
 look for the number of bytes that are unused
 
277
 i.e. that are not yet consumed
 
278
 *************************************************************/
 
279
int pb_unused(
 
280
sge_pack_buffer *pb 
 
281
) {
 
282
   return (pb->mem_size - pb->bytes_used);
 
283
}
 
284
 
 
285
/*************************************************************
 
286
 look for the number of bytes that are used
 
287
 *************************************************************/
 
288
int pb_used(
 
289
sge_pack_buffer *pb 
 
290
) {
 
291
   return pb->bytes_used;
 
292
}
 
293
 
 
294
/* --------------------------------------------------------- */
 
295
/*                                                           */
 
296
/*            low level functions for packing                */
 
297
/*                                                           */
 
298
/* --------------------------------------------------------- */
 
299
 
 
300
/*
 
301
   return values:
 
302
   PACK_SUCCESS
 
303
   PACK_ENOMEM
 
304
   PACK_FORMAT
 
305
 */
 
306
int packint(sge_pack_buffer *pb, u_long32 i) 
 
307
{
 
308
   u_long32 J=0;
 
309
 
 
310
   DENTER(PACK_LAYER, "packint");
 
311
 
 
312
   if (!pb->just_count) {
 
313
      if (pb->bytes_used + INTSIZE > pb->mem_size) {
 
314
         DPRINTF(("realloc(%d + %d)\n", pb->mem_size, CHUNK));
 
315
         pb->mem_size += CHUNK;
 
316
         pb->head_ptr = sge_realloc(pb->head_ptr, pb->mem_size, 0);
 
317
         if (!pb->head_ptr) {
 
318
            DEXIT;
 
319
            return PACK_ENOMEM;
 
320
         }
 
321
         pb->cur_ptr = &(pb->head_ptr[pb->bytes_used]);
 
322
      }
 
323
 
 
324
      /* copy in packing buffer */
 
325
      J = htonl(i);
 
326
      memcpy(pb->cur_ptr, (((char *) &J) + INTOFF), INTSIZE);
 
327
      pb->cur_ptr = &(pb->cur_ptr[INTSIZE]);
 
328
   }
 
329
   pb->bytes_used += INTSIZE;
 
330
 
 
331
   DEXIT;
 
332
   return PACK_SUCCESS;
 
333
}
 
334
 
 
335
int repackint(sge_pack_buffer *pb, u_long32 i) 
 
336
{
 
337
   u_long32 J=0;
 
338
 
 
339
   DENTER(PACK_LAYER, "repackint");
 
340
 
 
341
   if (!pb->just_count) {
 
342
      J = htonl(i);
 
343
      memcpy(pb->cur_ptr, (((char *) &J) + INTOFF), INTSIZE);
 
344
      pb->cur_ptr = &(pb->cur_ptr[INTSIZE]);
 
345
   }
 
346
 
 
347
   DEXIT;
 
348
   return PACK_SUCCESS;
 
349
}
 
350
 
 
351
#define DOUBLESIZE 8
 
352
 
 
353
/*
 
354
   return values:
 
355
   PACK_SUCCESS
 
356
   PACK_ENOMEM
 
357
   PACK_FORMAT
 
358
 */
 
359
int packdouble(sge_pack_buffer *pb, double d) {
 
360
/* CygWin does not know RPC u. XDR */
 
361
   char buf[32];
 
362
#if !(defined(WIN32))                                         /* var not needed */
 
363
   XDR xdrs;
 
364
#endif
 
365
 
 
366
   DENTER(PACK_LAYER, "packdouble");
 
367
 
 
368
   if (!pb->just_count) {
 
369
      if (pb->bytes_used + DOUBLESIZE > pb->mem_size) {
 
370
         DPRINTF(("realloc(%d + %d)\n", pb->mem_size, CHUNK));
 
371
         pb->mem_size += CHUNK;
 
372
         pb->head_ptr = sge_realloc(pb->head_ptr, pb->mem_size, 0);
 
373
         if (!pb->head_ptr) {
 
374
            DEXIT;
 
375
            return PACK_ENOMEM;
 
376
         }
 
377
         pb->cur_ptr = &(pb->head_ptr[pb->bytes_used]);
 
378
      }
 
379
 
 
380
      /* copy in packing buffer */
 
381
#if !(defined(WIN32) || defined(INTERIX))                      /* XDR not called */
 
382
      xdrmem_create(&xdrs, (caddr_t)buf, sizeof(buf), XDR_ENCODE);
 
383
 
 
384
      if (!(xdr_double(&xdrs, &d))) {
 
385
         DPRINTF(("error - XDR of double failed\n"));
 
386
         xdr_destroy(&xdrs);
 
387
         DEXIT;
 
388
         return PACK_FORMAT;
 
389
      }
 
390
 
 
391
      if (xdr_getpos(&xdrs) != DOUBLESIZE) {
 
392
         DPRINTF(("error - size of XDRed double is %d\n", xdr_getpos(&xdrs)));
 
393
         xdr_destroy(&xdrs);
 
394
         DEXIT;
 
395
         return PACK_FORMAT;
 
396
      }
 
397
#endif/* WIN32 || INTERIX */
 
398
#if defined(INTERIX)
 
399
      wl_xdrmem_create(&xdrs, (caddr_t)buf, sizeof(buf), XDR_ENCODE);
 
400
 
 
401
      if (!(wl_xdr_double(&xdrs, &d))) {
 
402
         DPRINTF(("error - XDR of double failed\n"));
 
403
         wl_xdr_destroy(&xdrs);
 
404
         DEXIT;
 
405
         return PACK_FORMAT;
 
406
      }
 
407
 
 
408
      if (wl_xdr_getpos(&xdrs) != DOUBLESIZE) {
 
409
         DPRINTF(("error - size of XDRed double is %d\n", wl_xdr_getpos(&xdrs)));
 
410
         wl_xdr_destroy(&xdrs);
 
411
         DEXIT;
 
412
         return PACK_FORMAT;
 
413
      }
 
414
#endif
 
415
 
 
416
      memcpy(pb->cur_ptr, buf, DOUBLESIZE);
 
417
      /* we have to increment the buffer even through WIN32 will not use it */
 
418
      pb->cur_ptr = &(pb->cur_ptr[DOUBLESIZE]);
 
419
 
 
420
#if !(defined(WIN32) || defined(INTERIX)) /* XDR not called */
 
421
      xdr_destroy(&xdrs);
 
422
#endif
 
423
#if defined(INTERIX)
 
424
      wl_xdr_destroy(&xdrs);
 
425
#endif
 
426
   }
 
427
   pb->bytes_used += DOUBLESIZE;
 
428
 
 
429
   DEXIT;
 
430
   return PACK_SUCCESS;
 
431
}
 
432
 
 
433
/* ---------------------------------------------------------
 
434
 
 
435
   return values:
 
436
   PACK_SUCCESS
 
437
   PACK_ENOMEM
 
438
   PACK_FORMAT
 
439
 
 
440
 */
 
441
int packstr(sge_pack_buffer *pb, const char *str) 
 
442
{
 
443
   DENTER(PACK_LAYER, "packstr");
 
444
 
 
445
   /* determine string length */
 
446
   if (str == NULL) {
 
447
      if (!pb->just_count) {
 
448
         /* is realloc necessary */
 
449
         if ((pb->bytes_used + 1) > pb->mem_size) {
 
450
 
 
451
            /* realloc */
 
452
            DPRINTF(("realloc(%d + %d)\n", pb->mem_size, CHUNK));
 
453
            pb->mem_size += CHUNK;
 
454
            pb->head_ptr = sge_realloc(pb->head_ptr, pb->mem_size, 0);
 
455
            if (!pb->head_ptr) {
 
456
               DEXIT;
 
457
               return PACK_ENOMEM;
 
458
            }
 
459
 
 
460
            /* update cur_ptr */
 
461
            pb->cur_ptr = &(pb->head_ptr[pb->bytes_used]);
 
462
         }
 
463
         pb->cur_ptr[0] = '\0';
 
464
         /* update cur_ptr & bytes_packed */
 
465
         pb->cur_ptr = &(pb->cur_ptr[1]);
 
466
      }
 
467
      pb->bytes_used++;
 
468
   } else {
 
469
      size_t n = strlen(str) + 1;
 
470
 
 
471
      if (!pb->just_count) {
 
472
         /* is realloc necessary */
 
473
         if ((pb->bytes_used + n) > pb->mem_size) {
 
474
            /* realloc */
 
475
            DPRINTF(("realloc(%d + %d)\n", pb->mem_size, CHUNK));
 
476
            while ((pb->bytes_used + n) > pb->mem_size)
 
477
               pb->mem_size += CHUNK;
 
478
            pb->head_ptr = sge_realloc(pb->head_ptr, pb->mem_size, 0);
 
479
            if (!pb->head_ptr) {
 
480
               DEXIT;
 
481
               return PACK_ENOMEM;
 
482
            }
 
483
 
 
484
            /* update cur_ptr */
 
485
            pb->cur_ptr = &(pb->head_ptr[pb->bytes_used]);
 
486
         }
 
487
         memcpy(pb->cur_ptr, str, n);
 
488
         /* update cur_ptr & bytes_packed */
 
489
         pb->cur_ptr = &(pb->cur_ptr[n]);
 
490
      }
 
491
      pb->bytes_used += n;
 
492
   }
 
493
 
 
494
   DEXIT;
 
495
   return PACK_SUCCESS;
 
496
}
 
497
 
 
498
 
 
499
/****** cull/pack/packbitfield() ****************************************************
 
500
*  NAME
 
501
*     packbitfield() -- pack a bitfield 
 
502
*
 
503
*  SYNOPSIS
 
504
*     int packbitfield(sge_pack_buffer *pb, const bitfield *bitfield) 
 
505
*
 
506
*  FUNCTION
 
507
*     Writes the bitfield into the given packbuffer.
 
508
*     The following information will be written:
 
509
*        - the size of the bitfield in bits
 
510
*        - the bitfield itself as binary buffer
 
511
*
 
512
*  INPUTS
 
513
*     sge_pack_buffer *pb - the target packbuffer
 
514
*     const bitfield *bitfield   - the bitfield to pack
 
515
*
 
516
*  RESULT
 
517
*     int - PACK_SUCCESS on success,
 
518
*           else PACK_* error codes
 
519
*
 
520
*  SEE ALSO
 
521
*     uti/bitfield/--Bitfield
 
522
*     cull/pack/unpackbitfield()
 
523
*******************************************************************************/
 
524
int packbitfield(sge_pack_buffer *pb, const bitfield *bitfield)
 
525
{
 
526
   int ret;
 
527
   u_long32 size;
 
528
   u_long32 char_size;
 
529
 
 
530
   DENTER(PACK_LAYER, "packbitfield");
 
531
 
 
532
   size = sge_bitfield_get_size(bitfield);
 
533
   char_size = sge_bitfield_get_size_bytes(size);
 
534
 
 
535
   if((ret = packint(pb, size)) != PACK_SUCCESS) {
 
536
      DEXIT;
 
537
      return ret;
 
538
   }
 
539
   
 
540
   if((ret = packbuf(pb, sge_bitfield_get_buffer(bitfield),
 
541
                     char_size)) != PACK_SUCCESS) {
 
542
      DEXIT;
 
543
      return ret;
 
544
   }
 
545
 
 
546
   DEXIT;
 
547
   return PACK_SUCCESS;
 
548
}
 
549
 
 
550
/* ---------------------------------------------------------
 
551
 
 
552
   return values:
 
553
   PACK_SUCCESS
 
554
   PACK_ENOMEM
 
555
   PACK_FORMAT
 
556
 
 
557
 */
 
558
int packbuf(
 
559
sge_pack_buffer *pb,
 
560
const char *buf_ptr,
 
561
u_long32 buf_size 
 
562
) {
 
563
 
 
564
   DENTER(PACK_LAYER, "packbuf");
 
565
 
 
566
   if (!pb->just_count) {
 
567
      /* is realloc necessary */
 
568
#if !(defined(WIN32)) /* cast */
 
569
      if (buf_size + (u_long32) pb->bytes_used > (u_long32) pb->mem_size) {
 
570
#else
 
571
      if (buf_size + pb->bytes_used > pb->mem_size) {
 
572
#endif /* WIN32 */
 
573
 
 
574
         /* realloc */
 
575
         DPRINTF(("realloc(%d + %d)\n", pb->mem_size, CHUNK));
 
576
         pb->mem_size += CHUNK;
 
577
         pb->head_ptr = sge_realloc(pb->head_ptr, pb->mem_size, 0);
 
578
         if (!(pb->head_ptr)) {
 
579
            DEXIT;
 
580
            return PACK_ENOMEM;
 
581
         }
 
582
 
 
583
         /* update cur_ptr */
 
584
         pb->cur_ptr = &(pb->head_ptr[pb->bytes_used]);
 
585
      }
 
586
 
 
587
      /* copy in packing buffer */
 
588
      memcpy(pb->cur_ptr, buf_ptr, buf_size);
 
589
      /* update cur_ptr & bytes_packed */
 
590
      pb->cur_ptr = &(pb->cur_ptr[buf_size]);
 
591
   }
 
592
   pb->bytes_used += buf_size;
 
593
 
 
594
   DEXIT;
 
595
   return PACK_SUCCESS;
 
596
}
 
597
 
 
598
 
 
599
/* --------------------------------------------------------- */
 
600
/*                                                           */
 
601
/*            low level functions for unpacking              */
 
602
/*                                                           */
 
603
/* --------------------------------------------------------- */
 
604
 
 
605
/* ---------------------------------------------------------
 
606
 
 
607
   return values:
 
608
   PACK_SUCCESS
 
609
   (PACK_ENOMEM)
 
610
   PACK_FORMAT
 
611
 
 
612
 */
 
613
int unpackint(sge_pack_buffer *pb, u_long32 *ip) 
 
614
{
 
615
   DENTER(PACK_LAYER, "unpackint");
 
616
 
 
617
   /* are there enough bytes ? */
 
618
   if (pb->bytes_used + INTSIZE > pb->mem_size) {
 
619
      *ip = 0;
 
620
      DEXIT;
 
621
      return PACK_FORMAT;
 
622
   }
 
623
 
 
624
   /* copy integer */
 
625
   memset(ip, 0, sizeof(u_long32));
 
626
   memcpy(((char *) ip) + INTOFF, pb->cur_ptr, INTSIZE);
 
627
   *ip = ntohl(*ip);
 
628
 
 
629
   /* update cur_ptr & bytes_unpacked */
 
630
   pb->cur_ptr = &(pb->cur_ptr[INTSIZE]);
 
631
   pb->bytes_used += INTSIZE;
 
632
 
 
633
   DEXIT;
 
634
   return PACK_SUCCESS;
 
635
}
 
636
 
 
637
/* ---------------------------------------------------------
 
638
 
 
639
   return values:
 
640
   PACK_SUCCESS
 
641
   (PACK_ENOMEM)
 
642
   PACK_FORMAT
 
643
 
 
644
 */
 
645
int unpackdouble(sge_pack_buffer *pb, double *dp) 
 
646
{
 
647
 
 
648
#if !(defined(WIN32))                                       /* var not needed */
 
649
   XDR xdrs;
 
650
   char buf[32];
 
651
#endif
 
652
 
 
653
   DENTER(PACK_LAYER, "unpackdouble");
 
654
 
 
655
   /* are there enough bytes ? */
 
656
   if (pb->bytes_used + DOUBLESIZE > pb->mem_size) {
 
657
      *dp = 0;
 
658
      DEXIT;
 
659
      return PACK_FORMAT;
 
660
   }
 
661
 
 
662
   /* copy double */
 
663
 
 
664
   /* CygWin does not know RPC u. XDR */
 
665
#if !(defined(WIN32) || defined(INTERIX))                   /* XDR not called */
 
666
   memcpy(buf, pb->cur_ptr, DOUBLESIZE);
 
667
   xdrmem_create(&xdrs, buf, DOUBLESIZE, XDR_DECODE);
 
668
   if (!(xdr_double(&xdrs, dp))) {
 
669
      *dp = 0;
 
670
      DPRINTF(("error unpacking XDRed double\n"));
 
671
      xdr_destroy(&xdrs);
 
672
      DEXIT;
 
673
      return PACK_FORMAT;
 
674
   }
 
675
#endif /* WIN32 || INTERIX */
 
676
#if defined(INTERIX)
 
677
   memcpy(buf, pb->cur_ptr, DOUBLESIZE);
 
678
   wl_xdrmem_create(&xdrs, buf, DOUBLESIZE, XDR_DECODE);
 
679
   if (!(wl_xdr_double(&xdrs, dp))) {
 
680
      *dp = 0;
 
681
      DPRINTF(("error unpacking XDRed double\n"));
 
682
      wl_xdr_destroy(&xdrs);
 
683
      DEXIT;
 
684
      return PACK_FORMAT;
 
685
   }
 
686
#endif
 
687
 
 
688
   /* update cur_ptr & bytes_unpacked */
 
689
   pb->cur_ptr = &(pb->cur_ptr[DOUBLESIZE]);
 
690
   pb->bytes_used += DOUBLESIZE;
 
691
 
 
692
#if !(defined(WIN32) || defined(INTERIX))                   /* XDR not called */
 
693
   xdr_destroy(&xdrs);
 
694
#endif /* WIN32 || INTERIX */
 
695
#if defined(INTIERX)
 
696
   wl_xdr_destroy(&xdrs);
 
697
#endif
 
698
 
 
699
   DEXIT;
 
700
   return PACK_SUCCESS;
 
701
}
 
702
 
 
703
/* ---------------------------------------------------------
 
704
 
 
705
   return values:
 
706
   PACK_SUCCESS
 
707
   PACK_ENOMEM
 
708
   PACK_FORMAT
 
709
 */
 
710
int unpackstr(sge_pack_buffer *pb, char **str) 
 
711
{
 
712
   u_long32 n;
 
713
 
 
714
   DENTER(PACK_LAYER, "unpackstr");
 
715
 
 
716
   /* determine string length */
 
717
   if (!pb->cur_ptr[0]) {
 
718
 
 
719
      *str = NULL;
 
720
 
 
721
      /* update cur_ptr & bytes_unpacked */
 
722
      pb->cur_ptr = &(pb->cur_ptr[1]);
 
723
      pb->bytes_used++;
 
724
 
 
725
      /* are there enough bytes ? */
 
726
      if (pb->bytes_used > pb->mem_size) {
 
727
         DEXIT;
 
728
         return PACK_FORMAT;
 
729
      }
 
730
 
 
731
      DEXIT;
 
732
      return PACK_SUCCESS;
 
733
   } else {
 
734
      n = strlen(pb->cur_ptr) + 1;
 
735
 
 
736
      /* are there enough bytes ? */
 
737
      if (n + pb->bytes_used > pb->mem_size) {
 
738
         DEXIT;
 
739
         return PACK_FORMAT;
 
740
      }
 
741
      *str = strdup(pb->cur_ptr);
 
742
      if (!*str) {
 
743
         DEXIT;
 
744
         return PACK_ENOMEM;
 
745
      }
 
746
      /* update cur_ptr & bytes_unpacked */
 
747
      pb->bytes_used += n;
 
748
      pb->cur_ptr = &(pb->cur_ptr[n]);
 
749
   }
 
750
 
 
751
   DEXIT;
 
752
   return PACK_SUCCESS;
 
753
}
 
754
 
 
755
/* ---------------------------------------------------------
 
756
 
 
757
   return values:
 
758
   PACK_SUCCESS
 
759
   PACK_ENOMEM
 
760
   PACK_FORMAT
 
761
 */
 
762
int unpackbuf(sge_pack_buffer *pb, char **buf_ptr, int buf_size) 
 
763
{
 
764
 
 
765
   DENTER(PACK_LAYER, "unpackbuf");
 
766
 
 
767
   if (buf_size == 0) {
 
768
      DEXIT;
 
769
      return PACK_SUCCESS;
 
770
   }
 
771
 
 
772
   /* are there enough bytes ? */
 
773
   if ((buf_size + pb->bytes_used) > pb->mem_size) {
 
774
      DEXIT;
 
775
      return PACK_FORMAT;
 
776
   }
 
777
 
 
778
   /* copy buffer */
 
779
   *buf_ptr = malloc(buf_size);
 
780
   if (!*buf_ptr) {
 
781
      DEXIT;
 
782
      return PACK_ENOMEM;
 
783
   }
 
784
   memcpy(*buf_ptr, pb->cur_ptr, buf_size);
 
785
   /* update cur_ptr & bytes_unpacked */
 
786
   pb->cur_ptr = &(pb->cur_ptr[buf_size]);
 
787
   pb->bytes_used += buf_size;
 
788
 
 
789
   DEXIT;
 
790
   return PACK_SUCCESS;
 
791
}
 
792
 
 
793
/****** cull/pack/unpackbitfield() ********************************************
 
794
*  NAME
 
795
*     unpackbitfield() -- unpack a bitfield 
 
796
*
 
797
*  SYNOPSIS
 
798
*     int unpackbitfield(sge_pack_buffer *pb, bitfield *bitfield) 
 
799
*
 
800
*  FUNCTION
 
801
*     Unpacks a bitfield from a packbuffer.
 
802
*
 
803
*     If the size of the descriptor doesn't match the size of the unpacked
 
804
*     bitfield, create a new bitfield.
 
805
*
 
806
*  INPUTS
 
807
*     sge_pack_buffer *pb - the source packbuffer
 
808
*     bitfield *bitfield  - used to return the unpacked bitfield
 
809
*     int descr_size      - size of the corresponding descriptor
 
810
*
 
811
*  RESULT
 
812
*     int - PACK_SUCCESS on success,
 
813
*           else PACK_* error codes
 
814
*
 
815
*  SEE ALSO
 
816
*     uti/bitfield/--Bitfield
 
817
*     cull/pack/packbitfield()
 
818
*******************************************************************************/
 
819
int unpackbitfield(sge_pack_buffer *pb, bitfield *bitfield, int descr_size)
 
820
{
 
821
   int ret;
 
822
   u_long32 size, char_size;
 
823
   char *buffer = NULL;
 
824
 
 
825
   DENTER(PACK_LAYER, "unpackbitfield");
 
826
 
 
827
   /* create new bitfield */
 
828
   if (!sge_bitfield_init(bitfield, descr_size)) {
 
829
      DEXIT;
 
830
      return PACK_ENOMEM;
 
831
   }
 
832
 
 
833
   /* unpack the size in bits */
 
834
   if((ret = unpackint(pb, &size)) != PACK_SUCCESS) {
 
835
      DEXIT;
 
836
      return ret;
 
837
   }
 
838
 
 
839
   /* size may not be bigger than bitfield initialized from descr information */
 
840
   if (size > descr_size) {
 
841
      DEXIT;
 
842
      return PACK_ENOMEM;
 
843
   }
 
844
 
 
845
   /* unpack contents of the bitfield */
 
846
   char_size = sge_bitfield_get_size_bytes(size);
 
847
   if((ret = unpackbuf(pb, &buffer, char_size)) != PACK_SUCCESS) {
 
848
      sge_bitfield_free_data(bitfield);
 
849
      DEXIT;
 
850
      return ret;
 
851
   }
 
852
   
 
853
   memcpy(sge_bitfield_get_buffer(bitfield), buffer, char_size);
 
854
 
 
855
   /* free unpacked bitfield buffer */
 
856
   FREE(buffer);
 
857
 
 
858
   DEXIT;
 
859
   return PACK_SUCCESS;
 
860
}
 
861
 
 
862
const char *cull_pack_strerror(int errnum)
 
863
{
 
864
   switch(errnum) {
 
865
      case PACK_SUCCESS:
 
866
         return MSG_CULL_PACK_SUCCESS;
 
867
      case PACK_ENOMEM:
 
868
         return MSG_CULL_PACK_ENOMEM;
 
869
      case PACK_FORMAT:
 
870
         return MSG_CULL_PACK_FORMAT;
 
871
      case PACK_BADARG:
 
872
         return MSG_CULL_PACK_BADARG;
 
873
      case PACK_VERSION:
 
874
         return MSG_CULL_PACK_VERSION;
 
875
      default:
 
876
         /* JG: TODO: we should have some global error message for all strerror functions */
 
877
         return "";
 
878
   }
 
879
}
 
880
 
 
881
/****** cull/pack/pb_are_equivalent() *****************************************
 
882
*  NAME
 
883
*     pb_are_equivalent() -- check if both buffers are equivalent 
 
884
*
 
885
*  SYNOPSIS
 
886
*     bool pb_are_equivalent(sge_pack_buffer *pb1, sge_pack_buffer *pb2) 
 
887
*
 
888
*  FUNCTION
 
889
*     Check if size and content of both packbuffers is equivalent 
 
890
*
 
891
*  INPUTS
 
892
*     sge_pack_buffer *pb1 - packbuffer 
 
893
*     sge_pack_buffer *pb2 - packbuffer 
 
894
*
 
895
*  RESULT
 
896
*     bool - equivalent?
 
897
*        true  - yes
 
898
*        false - no
 
899
*******************************************************************************/
 
900
bool
 
901
pb_are_equivalent(sge_pack_buffer *pb1, sge_pack_buffer *pb2)
 
902
{
 
903
   bool ret = true;
 
904
 
 
905
   if (pb1 != NULL && pb2 != NULL) {
 
906
      ret &= (pb1->bytes_used == pb2->bytes_used);
 
907
      ret &= (memcmp(pb1->head_ptr, pb2->head_ptr, pb1->bytes_used) == 0);
 
908
   }
 
909
   return ret;
 
910
}
 
911
 
 
912
/****** cull/pack/pb_print_to() ***********************************************
 
913
*  NAME
 
914
*     pb_print_to() -- Print content of packbuffer 
 
915
*
 
916
*  SYNOPSIS
 
917
*     void pb_print_to(sge_pack_buffer *pb, FILE* file) 
 
918
*
 
919
*  FUNCTION
 
920
*     Print content of packbuffer into file 
 
921
*
 
922
*  INPUTS
 
923
*     sge_pack_buffer *pb - packbuffer pointer 
 
924
*     bool only_header    - show only summary information 
 
925
*     FILE* file          - file stream (e.g. stderr) 
 
926
*
 
927
*  RESULT
 
928
*     void - NONE
 
929
*******************************************************************************/
 
930
void
 
931
pb_print_to(sge_pack_buffer *pb, bool only_header, FILE* file)
 
932
{
 
933
   int i;
 
934
 
 
935
   fprintf(file, "head_ptr: %p\n", pb->head_ptr);
 
936
   fprintf(file, "cur_ptr: %p\n", pb->cur_ptr);
 
937
   fprintf(file, "mem_size: %d\n", (int)pb->mem_size);
 
938
   fprintf(file, "bytes_used: %d\n", (int)pb->bytes_used);
 
939
   fprintf(file, "buffer:\n");
 
940
   if (!only_header) {
 
941
      for (i = 0; i < pb->bytes_used; i++) {
 
942
         fprintf(file, "%3d ", pb->head_ptr[i]);
 
943
         if ((i + 1) % 15 == 0) {
 
944
            fprintf(file, "\n");
 
945
         }
 
946
      }
 
947
      fprintf(file, "\n");
 
948
   }
 
949
}
 
950