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

« back to all changes in this revision

Viewing changes to source/libs/uti/sge_hostname.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
#include <stdio.h>
 
33
#include <stdlib.h>
 
34
#include <unistd.h>
 
35
#include <string.h>
 
36
#include <errno.h>
 
37
#include <pthread.h>
 
38
#include <fnmatch.h>
 
39
#include <sys/types.h>
 
40
#include <sys/socket.h>
 
41
#include <netinet/in.h>
 
42
#include <arpa/inet.h>
 
43
#include <netdb.h>
 
44
 
 
45
 
 
46
#if defined(SGE_MT)
 
47
#include <pthread.h>
 
48
#endif
 
49
 
 
50
#include "sge_bootstrap.h"
 
51
#include "sge_hostname.h"
 
52
#include "sgermon.h"
 
53
#include "sge_log.h"
 
54
#include "sge_language.h"
 
55
#include "sge_time.h" 
 
56
#include "sge_unistd.h"
 
57
#include "sge_string.h"
 
58
#include "sge_prog.h"
 
59
#include "sge_uidgid.h"
 
60
 
 
61
 
 
62
#include "msg_utilib.h"
 
63
#include "sge_mtutil.h"
 
64
 
 
65
#define ALIAS_DELIMITER "\n\t ,;"
 
66
#define SGE_MAXNISRETRY 5
 
67
 
 
68
#ifndef h_errno
 
69
extern int h_errno;
 
70
#endif
 
71
 
 
72
extern void trace(char *);
 
73
 
 
74
 
 
75
/* MT-NOTE: hostlist used only in qmaster, commd and some utilities */
 
76
static host *hostlist = NULL;
 
77
 
 
78
/* MT-NOTE: localhost used only in commd */
 
79
static host *localhost = NULL;
 
80
 
 
81
static pthread_mutex_t get_qmaster_port_mutex = PTHREAD_MUTEX_INITIALIZER;
 
82
static pthread_mutex_t get_execd_port_mutex = PTHREAD_MUTEX_INITIALIZER;
 
83
 
 
84
static struct servent *sge_getservbyname_r(struct servent *se_result, const char *service, char *buffer, size_t size)
 
85
{
 
86
   struct servent *se;
 
87
 
 
88
   int nisretry = SGE_MAXNISRETRY;
 
89
   while (nisretry--) {
 
90
/*******************************************************************************
 
91
 * TODO:
 
92
 * Whoever extends this function to account for other architectures,
 
93
 * DO NOT base the ifdef's on architecture names.  Instead, use the format:
 
94
 * GETSERVBYNAM_R<num_args>.  For example, instead of "LINUX" below, you
 
95
 * should use "GETSERVBYNAM_R6".  For architectures without a reentrant
 
96
 * version of the function, use "GETSERVBYNAM_M" and use locks to make it MT
 
97
 * safe.  This will require that you update aimk to include the correct defines
 
98
 * for each architecture.
 
99
 ******************************************************************************/
 
100
#if defined(LINUX)
 
101
      if (getservbyname_r(service, "tcp", se_result, buffer, size, &se) != 0)
 
102
         se = NULL;
 
103
#elif defined(SOLARIS)
 
104
      se = getservbyname_r(service, "tcp", se_result, buffer, size);
 
105
#else
 
106
      se = getservbyname(service, "tcp");
 
107
#endif
 
108
      if (se != NULL) {
 
109
         return se;
 
110
      } else {
 
111
         sleep(1);
 
112
      }
 
113
   }
 
114
 
 
115
   return NULL;
 
116
}
 
117
 
 
118
#define SGE_PORT_CACHE_TIMEOUT 60*10   /* 10 Min. */
 
119
int sge_get_qmaster_port(bool *from_services) {
 
120
   char* port = NULL;
 
121
   int int_port = -1;
 
122
 
 
123
   struct timeval now;
 
124
   static long next_timeout = 0;
 
125
   static int cached_port = -1;
 
126
   DENTER(GDI_LAYER, "sge_get_qmaster_port");
 
127
 
 
128
   sge_mutex_lock("get_qmaster_port_mutex", SGE_FUNC, __LINE__, &get_qmaster_port_mutex);
 
129
 
 
130
   /* check for reresolve timeout */
 
131
   gettimeofday(&now,NULL);
 
132
 
 
133
   if (next_timeout > 0 ) {
 
134
      DPRINTF(("reresolve port timeout in "sge_U32CFormat"\n", sge_u32c( next_timeout - now.tv_sec)));
 
135
   }
 
136
   if (cached_port >= 0 && next_timeout > now.tv_sec) {
 
137
      int_port = cached_port;
 
138
      DPRINTF(("returning cached port value: "sge_U32CFormat"\n", sge_u32c(int_port)));
 
139
      sge_mutex_unlock("get_qmaster_port_mutex", SGE_FUNC, __LINE__, &get_qmaster_port_mutex);
 
140
      DEXIT;
 
141
      return int_port;
 
142
   }
 
143
 
 
144
   port = getenv("SGE_QMASTER_PORT");   
 
145
   if (port != NULL) {
 
146
      int_port = atoi(port);
 
147
   }
 
148
 
 
149
   /* get port from services file */
 
150
   if (int_port <= 0) {
 
151
      char buffer[2048];
 
152
      struct servent se_result;
 
153
      struct servent* se_help = NULL;
 
154
 
 
155
      se_help = sge_getservbyname_r(&se_result, "sge_qmaster", buffer, sizeof(buffer));
 
156
      if (se_help != NULL) {
 
157
         int_port = ntohs(se_help->s_port);
 
158
         if (int_port > 0 && from_services) {
 
159
            *from_services = true;
 
160
         }
 
161
      }
 
162
   }
 
163
 
 
164
   if (int_port <= 0 ) {
 
165
      ERROR((SGE_EVENT, MSG_UTI_CANT_GET_ENV_OR_PORT_SS, "SGE_QMASTER_PORT", "sge_qmaster"));
 
166
      if ( cached_port > 0 ) {
 
167
         WARNING((SGE_EVENT, MSG_UTI_USING_CACHED_PORT_SU, "sge_qmaster", sge_u32c(cached_port) ));
 
168
         int_port = cached_port; 
 
169
      } else {
 
170
         sge_mutex_unlock("get_qmaster_port_mutex", SGE_FUNC, __LINE__, &get_qmaster_port_mutex);
 
171
         SGE_EXIT(NULL, 1);
 
172
      }
 
173
   } else {
 
174
      DPRINTF(("returning port value: "sge_U32CFormat"\n", sge_u32c(int_port)));
 
175
      /* set new timeout time */
 
176
      gettimeofday(&now,NULL);
 
177
      next_timeout = now.tv_sec + SGE_PORT_CACHE_TIMEOUT;
 
178
 
 
179
      /* set new port value */
 
180
      cached_port = int_port;
 
181
   }
 
182
 
 
183
   sge_mutex_unlock("get_qmaster_port_mutex", SGE_FUNC, __LINE__, &get_qmaster_port_mutex);
 
184
   
 
185
   DEXIT;
 
186
   return int_port;
 
187
}
 
188
 
 
189
int sge_get_execd_port(void) {
 
190
   char* port = NULL;
 
191
   int int_port = -1;
 
192
 
 
193
   struct timeval now;
 
194
   static long next_timeout = 0;
 
195
   static int cached_port = -1;
 
196
 
 
197
   DENTER(TOP_LAYER, "sge_get_execd_port");
 
198
 
 
199
   sge_mutex_lock("get_execd_port_mutex", SGE_FUNC, __LINE__, &get_execd_port_mutex);
 
200
   
 
201
   /* check for reresolve timeout */
 
202
   gettimeofday(&now,NULL);
 
203
 
 
204
   if ( next_timeout > 0 ) {
 
205
      DPRINTF(("reresolve port timeout in "sge_U32CFormat"\n", sge_u32c( next_timeout - now.tv_sec)));
 
206
   }
 
207
   if ( cached_port >= 0 && next_timeout > now.tv_sec ) {
 
208
      int_port = cached_port;
 
209
      DPRINTF(("returning cached port value: "sge_U32CFormat"\n", sge_u32c(int_port)));
 
210
      sge_mutex_unlock("get_execd_port_mutex", SGE_FUNC, __LINE__, &get_execd_port_mutex);
 
211
      return int_port;
 
212
   }
 
213
 
 
214
   port = getenv("SGE_EXECD_PORT");   
 
215
   if (port != NULL) {
 
216
      int_port = atoi(port);
 
217
   }
 
218
 
 
219
   /* get port from services file */
 
220
   if (int_port <= 0) {
 
221
      char buffer[2048];
 
222
      struct servent se_result;
 
223
      struct servent* se_help = NULL;
 
224
 
 
225
      se_help = sge_getservbyname_r(&se_result, "sge_execd", buffer, sizeof(buffer));
 
226
      if (se_help != NULL) {
 
227
         int_port = ntohs(se_help->s_port);
 
228
      }
 
229
   }
 
230
 
 
231
   if (int_port <= 0 ) {
 
232
      ERROR((SGE_EVENT, MSG_UTI_CANT_GET_ENV_OR_PORT_SS, "SGE_EXECD_PORT" , "sge_execd"));
 
233
      if ( cached_port > 0 ) {
 
234
         WARNING((SGE_EVENT, MSG_UTI_USING_CACHED_PORT_SU, "sge_execd", sge_u32c(cached_port) ));
 
235
         int_port = cached_port; 
 
236
      } else {
 
237
         sge_mutex_unlock("get_execd_port_mutex", SGE_FUNC, __LINE__, &get_execd_port_mutex);
 
238
         SGE_EXIT(NULL, 1);
 
239
      }
 
240
   } else {
 
241
      DPRINTF(("returning port value: "sge_U32CFormat"\n", sge_u32c(int_port)));
 
242
      /* set new timeout time */
 
243
      gettimeofday(&now,NULL);
 
244
      next_timeout = now.tv_sec + SGE_PORT_CACHE_TIMEOUT;
 
245
 
 
246
      /* set new port value */
 
247
      cached_port = int_port;
 
248
   } 
 
249
 
 
250
   sge_mutex_unlock("get_execd_port_mutex", SGE_FUNC, __LINE__, &get_execd_port_mutex);
 
251
 
 
252
   DEXIT;
 
253
   return int_port;
 
254
 
 
255
}
 
256
 
 
257
static int matches_addr(struct hostent *he, char *addr);
 
258
static host *sge_host_search_pred_alias(host *h);
 
259
 
 
260
static int matches_name(struct hostent *he, const char *name);    
 
261
static void sge_host_delete(host *h);
 
262
 
 
263
/* this globals are used for profiling */
 
264
unsigned long gethostbyname_calls = 0;
 
265
unsigned long gethostbyname_sec = 0;
 
266
unsigned long gethostbyaddr_calls = 0;
 
267
unsigned long gethostbyaddr_sec = 0;
 
268
 
 
269
 
 
270
#if 0 /*defined(SOLARIS)*/
 
271
int gethostname(char *name, int namelen);
 
272
#endif
 
273
 
 
274
#ifdef GETHOSTBYNAME_M
 
275
/* guards access to the non-MT-safe gethostbyname system call */
 
276
static pthread_mutex_t hostbyname_mutex = PTHREAD_MUTEX_INITIALIZER;
 
277
#endif
 
278
 
 
279
#ifdef GETHOSTBYADDR_M
 
280
/* guards access to the non-MT-safe gethostbyaddr system call */
 
281
static pthread_mutex_t hostbyaddr_mutex = PTHREAD_MUTEX_INITIALIZER;
 
282
#endif
 
283
 
 
284
 
 
285
/****** libs/uti/uti_state_get_localhost() *************************************
 
286
*  NAME
 
287
*     uti_state_get_localhost() - read access to uti lib global variables
 
288
*
 
289
*  FUNCTION
 
290
*     Provides access to either global variable or per thread global variable.
 
291
*
 
292
*******************************************************************************/
 
293
host *uti_state_get_localhost(void)
 
294
{
 
295
   /* so far called only by commd */ 
 
296
   return localhost;
 
297
}
 
298
 
 
299
#define MAX_RESOLVER_BLOCKING 15
 
300
 
 
301
/****** uti/host/sge_gethostbyname_retry() *************************************
 
302
*  NAME
 
303
*     sge_gethostbyname_retry() -- gethostbyname() wrapper
 
304
*
 
305
*  SYNOPSIS
 
306
*     struct hostent *sge_gethostbyname_retry(const char *name)
 
307
*
 
308
*  FUNCTION
 
309
*     Wraps sge_gethostbyname() function calls, and retries if the host is not
 
310
*     found.
 
311
*
 
312
*     return value must be released by function caller (don't forget the 
 
313
*     char** array lists inside of struct hostent)
 
314
*
 
315
*     If possible (libcomm linked) use getuniquehostname() or 
 
316
*     cl_com_cached_gethostbyname() or cl_com_gethostname() from commlib.
 
317
*
 
318
*     This will return an sge aliased hostname.
 
319
*
 
320
*
 
321
*
 
322
*  NOTES
 
323
*     MT-NOTE: see sge_gethostbyname()
 
324
*******************************************************************************/
 
325
struct hostent *sge_gethostbyname_retry(
 
326
const char *name 
 
327
) {
 
328
   int i;
 
329
   struct hostent *he;
 
330
 
 
331
   DENTER(TOP_LAYER, "sge_gethostbyname_retry");
 
332
 
 
333
   if (!name || name[0] == '\0') {
 
334
      DPRINTF(("hostname to resolve is NULL or has zero length\n"));
 
335
      DEXIT;
 
336
      return NULL;
 
337
   }
 
338
 
 
339
   he = sge_gethostbyname(name,NULL);
 
340
   if (he == NULL) {
 
341
      for (i = 0; i < MAX_NIS_RETRIES && he == NULL; i++) {
 
342
         DPRINTF(("Couldn't resolve hostname %s\n", name));
 
343
         sleep(1);
 
344
         he = sge_gethostbyname(name,NULL);
 
345
      }
 
346
   }
 
347
 
 
348
   DEXIT;
 
349
   return he;
 
350
}
 
351
 
 
352
/****** uti/host/sge_gethostbyname() ****************************************
 
353
*  NAME
 
354
*     sge_gethostbyname() -- gethostbyname() wrapper
 
355
*
 
356
*  SYNOPSIS
 
357
*     struct hostent *sge_gethostbyname(const char *name)
 
358
*
 
359
*  FUNCTION
 
360
*     Wrapps gethostbyname() function calls, measures time spent 
 
361
*     in gethostbyname() and logs when very much time has passed.
 
362
*
 
363
*     return value must be released by function caller (don't forget the 
 
364
*     char* array lists inside of struct hostent)
 
365
*
 
366
*     If possible (libcomm linked) use getuniquehostname() or 
 
367
*     cl_com_cached_gethostbyname() or cl_com_gethostname() from libcomm.
 
368
*
 
369
*     This will return an sge aliased hostname.
 
370
*
 
371
*
 
372
*  NOTES
 
373
*     MT-NOTE: sge_gethostbyname() is MT safe
 
374
*     MT-NOTE: sge_gethostbyname() uses a mutex to guard access to the
 
375
*     MT-NOTE: gethostbyname() system call on all platforms other than Solaris,
 
376
*     MT-NOTE: Linux, AIX, Tru64, HP-UX, and MacOS 10.2 and greater.  Therefore,
 
377
*     MT-NOTE: except on the aforementioned platforms, MT calls to
 
378
*     MT-NOTE: gethostbyname() must go through sge_gethostbyname() to be MT safe.
 
379
*******************************************************************************/
 
380
struct hostent *sge_gethostbyname(const char *name, int* system_error_retval)
 
381
{
 
382
   struct hostent *he = NULL;
 
383
   time_t now;
 
384
   time_t time;
 
385
   int l_errno = 0;
 
386
   
 
387
   DENTER(GDI_LAYER, "sge_gethostbyname");
 
388
 
 
389
   /* This method goes to great lengths to slip a reentrant gethostbyname into
 
390
    * the code without making changes to the rest of the source base.  That
 
391
    * basically means that we have to make some redundant copies to
 
392
    * return to the caller.  This method doesn't appear to be highly utilized,
 
393
    * so that's probably ok.  If it's not ok, the interface can be changed
 
394
    * later. */
 
395
   
 
396
   now = (time_t)sge_get_gmt();
 
397
   gethostbyname_calls++;       /* profiling */
 
398
   
 
399
#ifdef GETHOSTBYNAME_R6
 
400
#define SGE_GETHOSTBYNAME_FOUND
 
401
   /* This is for Linux */
 
402
   DPRINTF (("Getting host by name - Linux\n"));
 
403
   {
 
404
      struct hostent re;
 
405
      char buffer[4096];
 
406
 
 
407
      /* No need to malloc he because it will end up pointing to re. */
 
408
      gethostbyname_r(name, &re, buffer, 4096, &he, &l_errno);
 
409
      
 
410
      /* Since re contains pointers into buffer, and both re and the buffer go
 
411
       * away when we exit this code block, we make a deep copy to return. */
 
412
      /* Yes, I do mean to check if he is NULL and then copy re!  No, he
 
413
       * doesn't need to be freed first. */
 
414
      if (he != NULL) {
 
415
         he = sge_copy_hostent (&re);
 
416
      }
 
417
   }
 
418
#endif
 
419
#ifdef GETHOSTBYNAME_R5
 
420
#define SGE_GETHOSTBYNAME_FOUND
 
421
 
 
422
   /* This is for Solaris */
 
423
   DPRINTF (("Getting host by name - Solaris\n"));
 
424
   {
 
425
      char buffer[4096];
 
426
      struct hostent *help_he = NULL;
 
427
 
 
428
      he = (struct hostent *)malloc (sizeof (struct hostent));
 
429
      if (he != NULL) {
 
430
         memset(he, 0, sizeof(struct hostent));
 
431
         /* On Solaris, this function returns the pointer to my struct on success
 
432
          * and NULL on failure. */
 
433
         help_he = gethostbyname_r(name, he, buffer, 4096, &l_errno);
 
434
         
 
435
         /* Since he contains pointers into buffer, and buffer goes away when we
 
436
          * exit this code block, we make a deep copy to return. */
 
437
         if (help_he != NULL) {
 
438
            struct hostent *new_he = sge_copy_hostent(he);
 
439
            FREE(he);
 
440
            he = new_he;
 
441
         } else {
 
442
            FREE(he);
 
443
         }
 
444
      }
 
445
   }
 
446
#endif
 
447
#ifdef GETHOSTBYNAME_R3
 
448
#define SGE_GETHOSTBYNAME_FOUND
 
449
 
 
450
   /* This is for AIX < 4.3, HPUX < 11, and Tru64 */
 
451
   DPRINTF (("Getting host by name - 3 arg\n"));
 
452
   
 
453
   {
 
454
      struct hostent_data he_data;
 
455
     
 
456
      memset(&he_data, 0, sizeof(he_data));
 
457
      he = (struct hostent *)malloc (sizeof (struct hostent));
 
458
      if (he != NULL) {
 
459
         memset(he, 0, sizeof(struct hostent));
 
460
         if (gethostbyname_r(name, he, &he_data) < 0) {
 
461
            /* If this function fails, free he so that we can test if it's NULL
 
462
             * later in the code. */
 
463
            FREE(he);
 
464
         }
 
465
         /* The location of the error code is actually undefined.  I'm just
 
466
          * assuming that it's in h_errno since that's where it is in the unsafe
 
467
          * version.
 
468
          * h_errno is, of course, not thread safe, but if there's an error we're
 
469
          * already screwed, so we won't worry to much about it.
 
470
          * An alternative would be to set errno to HOST_NOT_FOUND. */
 
471
         l_errno = h_errno;
 
472
      
 
473
         /* Since he contains pointers into he_data, and he_data goes away when we
 
474
          * exit this code block, we make a deep copy to return. */
 
475
         if (he != NULL) {
 
476
            struct hostent *new_he = sge_copy_hostent(he);
 
477
            FREE(he);
 
478
            he = new_he;
 
479
         }
 
480
      }
 
481
   }
 
482
#endif
 
483
#ifdef GETHOSTBYNAME
 
484
#define SGE_GETHOSTBYNAME_FOUND
 
485
 
 
486
   /* This is for AIX >= 4.3, HPUX >= 11, and Mac OS X >= 10.2 */
 
487
   DPRINTF (("Getting host by name - Thread safe\n"));
 
488
   he = gethostbyname(name);
 
489
   /* The location of the error code is actually undefined.  I'm just
 
490
    * assuming that it's in h_errno since that's where it is in the unsafe
 
491
    * version.
 
492
    * h_errno is, of course, not thread safe, but if there's an error we're
 
493
    * already screwed, so we won't worry too much about it.
 
494
    * An alternative would be to set errno to HOST_NOT_FOUND. */
 
495
   l_errno = h_errno;
 
496
   if (he != NULL) {
 
497
      struct hostent *new_he = sge_copy_hostent (he);
 
498
      /* do NOT free he, there was no malloc() */
 
499
      he = new_he;
 
500
   }
 
501
#endif
 
502
#ifdef GETHOSTBYNAME_M
 
503
#define SGE_GETHOSTBYNAME_FOUND
 
504
 
 
505
   /* This is for Mac OS < 10.2, IRIX, and everyone else
 
506
    *  - Actually, IRIX 6.5.17 supports a reentrant getaddrinfo(), but it's not
 
507
    *    worth the effort. */
 
508
   DPRINTF (("Getting host by name - Mutex guarded\n"));
 
509
 
 
510
   sge_mutex_lock("hostbyname", SGE_FUNC, __LINE__, &hostbyname_mutex);
 
511
 
 
512
   he = gethostbyname(name);
 
513
   l_errno = h_errno;
 
514
 
 
515
   if (he != NULL) {
 
516
      struct hostent *new_he = sge_copy_hostent (he);
 
517
      /* do NOT free he, there was no malloc() */
 
518
      he = new_he;
 
519
   }
 
520
   sge_mutex_unlock("hostbyname", SGE_FUNC, __LINE__, &hostbyname_mutex);
 
521
 
 
522
#endif
 
523
 
 
524
#ifndef SGE_GETHOSTBYNAME_FOUND
 
525
#error "no sge_gethostbyname() definition for this architecture."
 
526
#endif
 
527
 
 
528
   time = (time_t)sge_get_gmt() - now;
 
529
   gethostbyname_sec += time;   /* profiling */
 
530
 
 
531
   /* warn about blocking gethostbyname() calls */
 
532
   if (time > MAX_RESOLVER_BLOCKING) {
 
533
      WARNING((SGE_EVENT, "gethostbyname(%s) took %d seconds and returns %s\n", 
 
534
            name, (int)time, he?"success":
 
535
          (l_errno == HOST_NOT_FOUND)?"HOST_NOT_FOUND":
 
536
          (l_errno == TRY_AGAIN)?"TRY_AGAIN":
 
537
          (l_errno == NO_RECOVERY)?"NO_RECOVERY":
 
538
          (l_errno == NO_DATA)?"NO_DATA":
 
539
          (l_errno == NO_ADDRESS)?"NO_ADDRESS":"<unknown error>"));
 
540
   }
 
541
   if (system_error_retval != NULL) {
 
542
      *system_error_retval = l_errno;
 
543
   }
 
544
 
 
545
   DEXIT;
 
546
   return he;
 
547
}
 
548
 
 
549
/****** uti/host/sge_copy_hostent() ****************************************
 
550
*  NAME
 
551
*     sge_copy_hostent() -- make a deep copy of a struct hostent
 
552
*
 
553
*  SYNOPSIS
 
554
*     struct hostent *sge_copy_hostent (struct hostent *orig)
 
555
*
 
556
*  FUNCTION
 
557
*     Makes a deep copy of a struct hostent so that sge_gethostbyname() can
 
558
*     free it's buffer for the gethostbyname_r() calls on Linux and Solaris.
 
559
*
 
560
*  NOTES
 
561
*     MT-NOTE: sge_copy_hostent() is MT safe
 
562
*******************************************************************************/
 
563
struct hostent *sge_copy_hostent(struct hostent *orig)
 
564
{
 
565
   struct hostent *copy = (struct hostent *)malloc(sizeof(struct hostent));
 
566
   char **p = NULL;
 
567
   int count = 0;
 
568
 
 
569
   DENTER (GDI_LAYER, "sge_copy_hostent");
 
570
 
 
571
   if (copy != NULL) {  
 
572
      /* reset the malloced memory */
 
573
      memset(copy, 0, sizeof(struct hostent));
 
574
 
 
575
      /* Easy stuff first */
 
576
      copy->h_name = strdup(orig->h_name);
 
577
      copy->h_addrtype = orig->h_addrtype;
 
578
      copy->h_length = orig->h_length;
 
579
      
 
580
      /* Count the number of entries */
 
581
      count = 0;
 
582
      for (p = orig->h_addr_list; *p != NULL; p++) {
 
583
         count++;
 
584
      }
 
585
      
 
586
      DPRINTF (("%d names in h_addr_list\n", count));
 
587
      
 
588
      copy->h_addr_list = (char **) malloc (sizeof (char *) * (count + 1));
 
589
      
 
590
      /* Copy the entries */
 
591
      count = 0;
 
592
      for (p = orig->h_addr_list; *p != NULL; p++) {
 
593
 
 
594
#ifndef in_addr_t
 
595
         int tmp_size = sizeof (uint32_t); /* POSIX definition for AF_INET */
 
596
#else 
 
597
         int tmp_size = sizeof (in_addr_t);
 
598
#endif
 
599
         /* struct in_addr */
 
600
         copy->h_addr_list[count] = (char *)malloc (tmp_size);
 
601
         memcpy (copy->h_addr_list[count++], *p, tmp_size);
 
602
      }
 
603
      
 
604
      copy->h_addr_list[count] = NULL;
 
605
      
 
606
      /* Count the number of entries */
 
607
      count = 0;
 
608
      for (p = orig->h_aliases; *p != 0; p++) {
 
609
         count++;
 
610
      }
 
611
      
 
612
      DPRINTF (("%d names in h_aliases\n", count));
 
613
      
 
614
      copy->h_aliases = (char **) malloc (sizeof (char *) * (count + 1));
 
615
      
 
616
      /* Copy the entries */
 
617
      count = 0;
 
618
      for (p = orig->h_aliases; *p != 0; p++) {
 
619
         int tmp_size = (strlen(*p) + 1) * sizeof(char);
 
620
 
 
621
         copy->h_aliases[count] = (char *)malloc(tmp_size);
 
622
         memcpy(copy->h_aliases[count++], *p, tmp_size);
 
623
      }
 
624
      
 
625
      copy->h_aliases[count] = NULL;
 
626
   }
 
627
   DEXIT;
 
628
   return copy;
 
629
}
 
630
 
 
631
/****** uti/host/sge_gethostbyaddr() ****************************************
 
632
*  NAME
 
633
*     sge_gethostbyaddr() -- gethostbyaddr() wrapper
 
634
*
 
635
*  SYNOPSIS
 
636
*     struct hostent *sge_gethostbyaddr(const struct in_addr *addr)
 
637
*
 
638
*  FUNCTION
 
639
*     Wrapps gethostbyaddr() function calls, measures time spent 
 
640
*     in gethostbyaddr() and logs when very much time has passed.
 
641
*
 
642
*     return value must be released by function caller (don't forget the 
 
643
*     char** array lists inside of struct hostent)
 
644
*
 
645
*     If possible (libcomm linked) use  cl_com_cached_gethostbyaddr() 
 
646
*     from libcomm. This will return an sge aliased hostname.
 
647
*
 
648
*
 
649
*  NOTES
 
650
*     MT-NOTE: sge_gethostbyaddr() is MT safe
 
651
*     MT-NOTE: sge_gethostbyaddr() uses a mutex to guard access to the
 
652
*     MT-NOTE: gethostbyaddr() system call on all platforms other than Solaris,
 
653
*     MT-NOTE: Linux, and HP-UX.  Therefore, except on the aforementioned
 
654
*     MT-NOTE: platforms, MT calls to gethostbyaddr() must go through
 
655
*     MT-NOTE: sge_gethostbyaddr() to be MT safe.
 
656
*******************************************************************************/
 
657
struct hostent *sge_gethostbyaddr(const struct in_addr *addr, int* system_error_retval)
 
658
{
 
659
   struct hostent *he = NULL;
 
660
   time_t now;
 
661
   time_t time;
 
662
   int l_errno;
 
663
 
 
664
   DENTER(TOP_LAYER, "sge_gethostbyaddr");
 
665
 
 
666
   /* This method goes to great lengths to slip a reentrant gethostbyaddr into
 
667
    * the code without making changes to the rest of the source base.  That
 
668
    * basically means that we have to make some redundant copies to
 
669
    * return to the caller.  This method doesn't appear to be highly utilized,
 
670
    * so that's probably ok.  If it's not ok, the interface can be changed
 
671
    * later. */
 
672
 
 
673
   gethostbyaddr_calls++;      /* profiling */
 
674
   now = (time_t)sge_get_gmt();
 
675
 
 
676
#ifdef GETHOSTBYADDR_R8
 
677
#define SGE_GETHOSTBYADDR_FOUND
 
678
   /* This is for Linux */
 
679
   DPRINTF (("Getting host by addr - Linux\n"));
 
680
   {
 
681
      struct hostent re;
 
682
      char buffer[4096];
 
683
 
 
684
      /* No need to malloc he because it will end up pointing to re. */
 
685
      gethostbyaddr_r ((const char *)addr, 4, AF_INET, &re, buffer, 4096, &he, &l_errno);
 
686
      
 
687
      /* Since re contains pointers into buffer, and both re and the buffer go
 
688
       * away when we exit this code block, we make a deep copy to return. */
 
689
      /* Yes, I do mean to check if he is NULL and then copy re!  No, he
 
690
       * doesn't need to be freed first. */
 
691
      if (he != NULL) {
 
692
         he = sge_copy_hostent (&re);
 
693
      }
 
694
   }
 
695
#endif
 
696
#ifdef GETHOSTBYADDR_R7
 
697
#define SGE_GETHOSTBYADDR_FOUND
 
698
   /* This is for Solaris */
 
699
   DPRINTF(("Getting host by addr - Solaris\n"));
 
700
   {
 
701
      char buffer[4096];
 
702
      struct hostent *help_he = NULL;
 
703
      he = (struct hostent *)malloc(sizeof(struct hostent));
 
704
      if (he != NULL) {
 
705
         memset(he, 0, sizeof(struct hostent));
 
706
 
 
707
         /* On Solaris, this function returns the pointer to my struct on success
 
708
          * and NULL on failure. */
 
709
         help_he = gethostbyaddr_r((const char *)addr, 4, AF_INET, he, buffer, 4096, &l_errno);
 
710
      
 
711
         /* Since he contains pointers into buffer, and buffer goes away when we
 
712
          * exit this code block, we make a deep copy to return. */
 
713
         if (help_he != NULL) {
 
714
            struct hostent *new_he = sge_copy_hostent(help_he);
 
715
            FREE(he);
 
716
            he = new_he;
 
717
         } else {
 
718
            FREE(he);
 
719
            he = NULL;
 
720
         }
 
721
      }
 
722
   }
 
723
#endif
 
724
 
 
725
#ifdef GETHOSTBYADDR_R5
 
726
#define SGE_GETHOSTBYADDR_FOUND
 
727
   /* This is for HPUX < 11 */
 
728
   DPRINTF(("Getting host by addr - 3 arg\n"));
 
729
   
 
730
   {
 
731
      struct hostent_data he_data;
 
732
     
 
733
      memset(&he_data, 0, sizeof(he_data));
 
734
      he = (struct hostent *)malloc (sizeof (struct hostent));
 
735
      if (he != NULL) {
 
736
         memset(he, 0, sizeof(struct hostent));
 
737
         if (gethostbyaddr_r ((const char *)addr, 4, AF_INET, he, &he_data) < 0) {
 
738
            /* If this function fails, free he so that we can test if it's NULL
 
739
             * later in the code. */
 
740
            FREE (he);
 
741
            he = NULL;
 
742
         }
 
743
         /* The location of the error code is actually undefined.  I'm just
 
744
          * assuming that it's in h_errno since that's where it is in the unsafe
 
745
          * version.
 
746
          * h_errno is, of course, not thread safe, but if there's an error we're
 
747
          * already screwed, so we won't worry to much about it.
 
748
          * An alternative would be to set errno to HOST_NOT_FOUND. */
 
749
         l_errno = h_errno;
 
750
         
 
751
         /* Since he contains pointers into he_data, and he_data goes away when we
 
752
          * exit this code block, we make a deep copy to return. */
 
753
         if (he != NULL) {
 
754
            struct hostent *new_he = sge_copy_hostent (he);
 
755
            FREE (he);
 
756
            he = new_he;
 
757
         }
 
758
      }
 
759
   }
 
760
#endif
 
761
#ifdef GETHOSTBYADDR
 
762
#define SGE_GETHOSTBYADDR_FOUND
 
763
   /* This is for HPUX >= 11 */
 
764
   DPRINTF(("Getting host by addr - Thread safe\n"));
 
765
   he = gethostbyaddr((const char *)addr, 4, AF_INET);
 
766
   /*
 
767
    * JG: TODO: shouldn't it be 
 
768
    * he = gethostbyaddr((const char *)addr, sizeof(struct in_addr), AF_INET);
 
769
    */
 
770
 
 
771
   /* The location of the error code is actually undefined.  I'm just
 
772
    * assuming that it's in h_errno since that's where it is in the unsafe
 
773
    * version.
 
774
    * h_errno is, of course, not thread safe, but if there's an error we're
 
775
    * already screwed, so we won't worry too much about it.
 
776
    * An alternative would be to set errno to HOST_NOT_FOUND. */
 
777
   l_errno = h_errno;
 
778
   if (he != NULL) {
 
779
      struct hostent *new_he = sge_copy_hostent(he);
 
780
      /* do not free he, there was no malloc() */
 
781
      he = new_he;
 
782
   }
 
783
#endif
 
784
 
 
785
 
 
786
#ifdef GETHOSTBYADDR_M
 
787
#define SGE_GETHOSTBYADDR_FOUND
 
788
   /* This is for everone else. */
 
789
   DPRINTF (("Getting host by addr - Mutex guarded\n"));
 
790
   
 
791
   sge_mutex_lock("hostbyaddr", SGE_FUNC, __LINE__, &hostbyaddr_mutex);
 
792
 
 
793
#if defined(CRAY)
 
794
   he = gethostbyaddr((const char *)addr, sizeof(struct in_addr), AF_INET);
 
795
#else
 
796
   /* JG: TODO: shouldn't it always be sizeof(struct in_addr)? */
 
797
   he = gethostbyaddr((const char *)addr, 4, AF_INET);
 
798
#endif
 
799
 
 
800
   l_errno = h_errno;
 
801
   if (he != NULL) {
 
802
      struct hostent *new_he = sge_copy_hostent(he);
 
803
      /* do not free he, there was no malloc() */
 
804
      he = new_he;
 
805
   }
 
806
   sge_mutex_unlock("hostbyaddr", SGE_FUNC, __LINE__, &hostbyaddr_mutex);
 
807
#endif
 
808
 
 
809
#ifndef SGE_GETHOSTBYADDR_FOUND
 
810
#error "no sge_gethostbyaddr() definition for this architecture."
 
811
#endif
 
812
   time = (time_t)sge_get_gmt() - now;
 
813
   gethostbyaddr_sec += time;   /* profiling */
 
814
 
 
815
   /* warn about blocking gethostbyaddr() calls */
 
816
   if (time > MAX_RESOLVER_BLOCKING) {
 
817
      WARNING((SGE_EVENT, "gethostbyaddr() took %d seconds and returns %s\n", (int)time, he?"success":
 
818
          (l_errno == HOST_NOT_FOUND)?"HOST_NOT_FOUND":
 
819
          (l_errno == TRY_AGAIN)?"TRY_AGAIN":
 
820
          (l_errno == NO_RECOVERY)?"NO_RECOVERY":
 
821
          (l_errno == NO_DATA)?"NO_DATA":
 
822
          (l_errno == NO_ADDRESS)?"NO_ADDRESS":"<unknown error>"));
 
823
   }
 
824
   if (system_error_retval != NULL) {
 
825
      *system_error_retval = l_errno;
 
826
   }
 
827
 
 
828
   DEXIT;
 
829
   return he;
 
830
}
 
831
 
 
832
 
 
833
/****** sge_hostname/sge_host_delete() *****************************************
 
834
*  NAME
 
835
*     sge_host_delete() -- delete host in host list with all aliases 
 
836
*
 
837
*  SYNOPSIS
 
838
*     static void sge_host_delete(host *h) 
 
839
*
 
840
*  INPUTS
 
841
*     host *h - host to be deleted
 
842
*
 
843
*  NOTES
 
844
*     MT-NOTE: sge_host_delete() is not MT safe due to access to global variable
 
845
*
 
846
*******************************************************************************/
 
847
static void sge_host_delete(host *h) 
 
848
{
 
849
   host *last = NULL, *hl = hostlist;
 
850
   host *predalias, *nextalias;
 
851
 
 
852
   if (!h)
 
853
      return;
 
854
 
 
855
   predalias = sge_host_search_pred_alias(h);
 
856
   nextalias = h->alias;
 
857
 
 
858
   while (hl && hl != h) {
 
859
      last = hl;
 
860
      hl = hl->next;
 
861
   }
 
862
   if (hl) {
 
863
      if (last)
 
864
         last->next = hl->next;
 
865
      else
 
866
         hostlist = hostlist->next;
 
867
   }
 
868
   sge_strafree(&(h->he.h_aliases));
 
869
   sge_strafree(&(h->he.h_addr_list));
 
870
   free(h);
 
871
 
 
872
   sge_host_delete(predalias);
 
873
   sge_host_delete(nextalias);
 
874
}
 
875
 
 
876
 
 
877
 
 
878
/****** sge_hostname/sge_host_search_pred_alias() ******************************
 
879
*  NAME
 
880
*     sge_host_search_pred_alias() -- search host who's aliasptr points to host 
 
881
*
 
882
*  SYNOPSIS
 
883
*     static host* sge_host_search_pred_alias(host *h) 
 
884
*
 
885
*  INPUTS
 
886
*     host *h - host we search for
 
887
*
 
888
*  RESULT
 
889
*     static host* - found host if contained in host list
 
890
*
 
891
*  NOTES
 
892
*     MT-NOTE: sge_host_search_pred_alias() is not MT safe due to access to 
 
893
*     MT-NOTE: global variable
 
894
*
 
895
*  BUGS
 
896
*     ??? 
 
897
*
 
898
*  SEE ALSO
 
899
*     ???/???
 
900
*******************************************************************************/
 
901
static host *sge_host_search_pred_alias(host *h) 
 
902
{
 
903
   host *hl = hostlist;
 
904
 
 
905
   while (hl && hl->alias != h)
 
906
      hl = hl->next;
 
907
 
 
908
   return hl;
 
909
}
 
910
 
 
911
 
 
912
/****** sge_hostname/matches_name() ********************************************
 
913
*  NAME
 
914
*     matches_name() -- ??? 
 
915
*
 
916
*  SYNOPSIS
 
917
*     static int matches_name(struct hostent *he, const char *name) 
 
918
*
 
919
*  INPUTS
 
920
*     struct hostent *he - ???
 
921
*     const char *name   - ??? 
 
922
*
 
923
*  RESULT
 
924
*     static int - ???
 
925
*
 
926
*  NOTES
 
927
*     MT-NOTE: matches_name() is MT safe
 
928
*******************************************************************************/
 
929
static int matches_name(struct hostent *he, const char *name)    
 
930
{
 
931
   if (!name)
 
932
      return 1;
 
933
   if (!strcasecmp(name, he->h_name))
 
934
      return 1;
 
935
   if (sge_stracasecmp(name, he->h_aliases))
 
936
      return 1;
 
937
   return 0;
 
938
}
 
939
 
 
940
/****** sge_hostname/matches_addr() ********************************************
 
941
*  NAME
 
942
*     matches_addr() -- ??? 
 
943
*
 
944
*  SYNOPSIS
 
945
*     static int matches_addr(hostent *he, char *addr) 
 
946
*
 
947
*  INPUTS
 
948
*     struct hostent *he - ??? 
 
949
*     char *addr  - ??? 
 
950
*
 
951
*  NOTES
 
952
*     MT-NOTE: matches_addr() is MT safe
 
953
*******************************************************************************/
 
954
static int matches_addr(struct hostent *he, char *addr) 
 
955
{
 
956
   if (!addr) {
 
957
      return 1;
 
958
   }
 
959
   if (sge_stramemncpy(addr, he->h_addr_list, he->h_length)) {
 
960
      return 1;
 
961
   }
 
962
   return 0;
 
963
}
 
964
 
 
965
/****** uti/hostname/sge_host_search() ****************************************
 
966
*  NAME
 
967
*     sge_host_search() -- Search for host 
 
968
*
 
969
*  SYNOPSIS
 
970
*     host* sge_host_search(const char *name, char *addr) 
 
971
*
 
972
*  FUNCTION
 
973
*     Search for host. If 'name' is not NULL the returned host has 
 
974
*     the given or the alias that matches this name. 'name' is
 
975
*     not case sensitive. 'addr' is in hostorder.
 
976
*     If 'addr' is not NULL the returned host has 'addr' in his
 
977
*     addrlist. If 'addr' is aliased this function returns the
 
978
*     hostname of the first alias (mainname) 
 
979
*
 
980
*  INPUTS
 
981
*     const char *name - hostname 
 
982
*     char *addr       - address 
 
983
*
 
984
*  NOTES
 
985
*     MT-NOTE: sge_host_search() is not MT safe due to access to hostlist 
 
986
*     MT-NOTE: global variable
 
987
*
 
988
*  RESULT
 
989
*     host* - host entry
 
990
******************************************************************************/
 
991
host *sge_host_search(const char *name, char *addr) 
 
992
{
 
993
   host *hl = hostlist, *h1;
 
994
   struct hostent *he;
 
995
 
 
996
   while (hl) {
 
997
      he = &hl->he;
 
998
 
 
999
      if (((name && !strcasecmp(hl->mainname, name)) || 
 
1000
            matches_name(he, name)) && matches_addr(he, addr)) {
 
1001
         while ((h1 = sge_host_search_pred_alias(hl)))   /* start of alias chain */
 
1002
            hl = h1;
 
1003
         return hl;
 
1004
      }
 
1005
      hl = hl->next;
 
1006
   }
 
1007
 
 
1008
   return NULL;
 
1009
}
 
1010
 
 
1011
/****** uti/hostname/sge_host_print() *****************************************
 
1012
*  NAME
 
1013
*     sge_host_print() -- Print host entry info file 
 
1014
*
 
1015
*  SYNOPSIS
 
1016
*     void sge_host_print(host *h, FILE *fp) 
 
1017
*
 
1018
*  FUNCTION
 
1019
*     Print host entry info file  
 
1020
*
 
1021
*  INPUTS
 
1022
*     host *h  - host entry 
 
1023
*     FILE *fp - file 
 
1024
*
 
1025
*  NOTES
 
1026
*     MT-NOTE: sge_host_print() is NOT MT safe ( because of inet_ntoa() call)
 
1027
******************************************************************************/
 
1028
void sge_host_print(host *h, FILE *fp) 
 
1029
{
 
1030
   struct hostent *he;
 
1031
   char **cpp;
 
1032
 
 
1033
   he = &h->he;
 
1034
   fprintf(fp, "h_name: %s\n", he->h_name);
 
1035
   fprintf(fp, "mainname: %s\n", h->mainname);
 
1036
   fprintf(fp, "h_aliases:\n");
 
1037
   for (cpp = he->h_aliases; *cpp; cpp++) {
 
1038
      fprintf(fp, "  %s\n", *cpp);
 
1039
   }
 
1040
   fprintf(fp, "h_addrtype: %d\n", he->h_addrtype);
 
1041
   fprintf(fp, "h_length: %d\n", he->h_length);
 
1042
   fprintf(fp, "h_addr_list:\n");
 
1043
   for (cpp = he->h_addr_list; *cpp; cpp++) {
 
1044
      fprintf(fp, "  %s\n", inet_ntoa(*(struct in_addr *) *cpp)); /* inet_ntoa() is not MT save */
 
1045
   }
 
1046
   if (h->alias) {
 
1047
      fprintf(fp, "aliased to %s\n", h->alias->he.h_name);
 
1048
   }
 
1049
}
 
1050
 
 
1051
/****** uti/hostname/sge_host_list_print() ************************************
 
1052
*  NAME
 
1053
*     sge_host_list_print() -- Print hostlist into file 
 
1054
*
 
1055
*  SYNOPSIS
 
1056
*     void sge_host_list_print(FILE *fp) 
 
1057
*
 
1058
*  FUNCTION
 
1059
*     Print hostlist into file 
 
1060
*
 
1061
*  INPUTS
 
1062
*     FILE *fp - filename 
 
1063
*  
 
1064
*  NOTES
 
1065
*     MT-NOTE: sge_host_list_print() is not MT safe due to access to hostlist 
 
1066
*     MT-NOTE: global variable
 
1067
******************************************************************************/
 
1068
void sge_host_list_print(FILE *fp) 
 
1069
{
 
1070
   host *hl = hostlist;
 
1071
 
 
1072
   while (hl) {
 
1073
      sge_host_print(hl, fp);
 
1074
      hl = hl->next;
 
1075
      if (hl)
 
1076
         fprintf(fp, "\n");
 
1077
   }
 
1078
}
 
1079
 
 
1080
 
 
1081
 
 
1082
void sge_free_hostent( struct hostent** he_to_del ) {
 
1083
   struct hostent *he = NULL; 
 
1084
   char** help = NULL;
 
1085
 
 
1086
   /* nothing to free */
 
1087
   if (he_to_del == NULL) {
 
1088
      return;
 
1089
   }
 
1090
 
 
1091
   /* pointer points to NULL, nothing to free */
 
1092
   if (*he_to_del == NULL) {
 
1093
      return;
 
1094
   }
 
1095
 
 
1096
   he = *he_to_del;
 
1097
 
 
1098
   /* free unique host name */
 
1099
   free(he->h_name);
 
1100
   he->h_name = NULL;
 
1101
 
 
1102
   /* free host aliases */  
 
1103
   if (he->h_aliases != NULL) {
 
1104
      help = he->h_aliases;
 
1105
      while(*help) {
 
1106
         free(*help++);
 
1107
      }
 
1108
      free(he->h_aliases);
 
1109
   }
 
1110
   he->h_aliases = NULL;
 
1111
 
 
1112
   /* free addr list */
 
1113
   if (he->h_addr_list != NULL) {
 
1114
      help = he->h_addr_list;
 
1115
      while(*help) {
 
1116
         free(*help++);
 
1117
      }
 
1118
      free(he->h_addr_list);
 
1119
   }
 
1120
   he->h_addr_list = NULL;
 
1121
 
 
1122
   /* free hostent struct */
 
1123
   free(*he_to_del);
 
1124
   *he_to_del = NULL;
 
1125
}
 
1126
 
 
1127
 
 
1128
 
 
1129
/****** uti/hostname/sge_host_get_mainname() **********************************
 
1130
*  NAME
 
1131
*     sge_host_get_mainname() -- Return mainname considering aliases 
 
1132
*
 
1133
*  SYNOPSIS
 
1134
*     char* sge_host_get_mainname(host *h) 
 
1135
*
 
1136
*  FUNCTION
 
1137
*     Return the mainname of a host considering aliases. 
 
1138
*
 
1139
*  INPUTS
 
1140
*     host *h - host
 
1141
*
 
1142
*  RESULT
 
1143
*     char* - mainname 
 
1144
*
 
1145
*  NOTES:
 
1146
*     MT-NOTE: sge_host_get_mainname() is not MT safe
 
1147
******************************************************************************/
 
1148
char *sge_host_get_mainname(host *h) 
 
1149
{
 
1150
   host *h1;
 
1151
 
 
1152
   h1 = h;
 
1153
   while ((h = sge_host_search_pred_alias(h)))   /* search start of alias chain */
 
1154
      h1 = h;
 
1155
 
 
1156
   if (h1->mainname[0])
 
1157
      return h1->mainname;
 
1158
 
 
1159
   return (char *) h1->he.h_name;
 
1160
}
 
1161
 
 
1162
 
 
1163
 
 
1164
/****** uti/hostname/sge_hostcpy() ********************************************
 
1165
*  NAME
 
1166
*     sge_hostcpy() -- strcpy() for hostnames.
 
1167
*
 
1168
*  SYNOPSIS
 
1169
*     void sge_hostcpy(char *dst, const char *raw)
 
1170
*
 
1171
*  FUNCTION
 
1172
*     strcpy() for hostnames. Honours some configuration values:
 
1173
*        - Domain name may be ignored
 
1174
*        - Domain name may be replaced by a 'default domain'
 
1175
*        - Hostnames may be used as they are.
 
1176
*        - straight strcpy() for hostgroup names
 
1177
*
 
1178
*  INPUTS
 
1179
*     char *dst       - possibly modified hostname
 
1180
*     const char *raw - hostname
 
1181
*
 
1182
*  SEE ALSO
 
1183
*     uti/hostname/sge_hostcmp()
 
1184
*     uti/hostname/sge_hostmatch()
 
1185
*
 
1186
*  NOTES:
 
1187
*     MT-NOTE: sge_hostcpy() is MT safe
 
1188
******************************************************************************/
 
1189
void sge_hostcpy(char *dst, const char *raw)
 
1190
{
 
1191
   bool ignore_fqdn = bootstrap_get_ignore_fqdn();
 
1192
   bool is_hgrp = is_hgroup_name(raw);
 
1193
   const char *default_domain;
 
1194
 
 
1195
   if (dst == NULL || raw == NULL) {
 
1196
      return;
 
1197
   }
 
1198
   if (is_hgrp) {
 
1199
      /* hostgroup name: not in FQDN format, copy the entire string*/
 
1200
      sge_strlcpy(dst, raw, CL_MAXHOSTLEN);
 
1201
      return;
 
1202
   } 
 
1203
   if (ignore_fqdn) {
 
1204
      char *s = NULL;
 
1205
      /* standard: simply ignore FQDN */
 
1206
 
 
1207
      sge_strlcpy(dst, raw, CL_MAXHOSTLEN);
 
1208
      if ((s = strchr(dst, '.'))) {
 
1209
         *s = '\0';
 
1210
      }
 
1211
      return;
 
1212
   } 
 
1213
   if ((default_domain = bootstrap_get_default_domain()) != NULL && 
 
1214
              SGE_STRCASECMP(default_domain, "none") != 0) {
 
1215
 
 
1216
      /* exotic: honor FQDN but use default_domain */
 
1217
      if (!strchr(raw, '.')) {
 
1218
         snprintf(dst, CL_MAXHOSTLEN, "%s.%s", raw, default_domain);
 
1219
      } else {
 
1220
         sge_strlcpy(dst, raw, CL_MAXHOSTLEN);
 
1221
      }
 
1222
   } else {
 
1223
      /* hardcore: honor FQDN, don't use default_domain */
 
1224
 
 
1225
      sge_strlcpy(dst, raw, CL_MAXHOSTLEN);
 
1226
   }
 
1227
 
 
1228
   return;
 
1229
}  
 
1230
 
 
1231
/****** uti/hostname/sge_hostcmp() ********************************************
 
1232
*  NAME
 
1233
*     sge_hostcmp() -- strcmp() for hostnames
 
1234
*
 
1235
*  SYNOPSIS
 
1236
*     int sge_hostcmp(const char *h1, const char*h2)
 
1237
*
 
1238
*  FUNCTION
 
1239
*     strcmp() for hostnames. Honours some configuration values:
 
1240
*        - Domain name may be ignored
 
1241
*        - Domain name may be replaced by a 'default domain'
 
1242
*        - Hostnames may be used as they are.
 
1243
*
 
1244
*  INPUTS
 
1245
*     const char *h1 - 1st hostname
 
1246
*     const char *h2 - 2nd hostname
 
1247
*
 
1248
*  RESULT
 
1249
*     int - 0, 1 or -1
 
1250
*
 
1251
*  SEE ALSO
 
1252
*     uti/hostname/sge_hostmatch()
 
1253
*     uti/hostname/sge_hostcpy()
 
1254
*
 
1255
*  NOTES:
 
1256
*     MT-NOTE: sge_hostcmp() is MT safe
 
1257
******************************************************************************/
 
1258
int sge_hostcmp(const char *h1, const char*h2)
 
1259
{
 
1260
   int cmp = -1;
 
1261
   char h1_cpy[CL_MAXHOSTLEN+1], h2_cpy[CL_MAXHOSTLEN+1];
 
1262
 
 
1263
 
 
1264
   DENTER(BASIS_LAYER, "sge_hostcmp");
 
1265
 
 
1266
   if (h1 != NULL && h2 != NULL) {
 
1267
      sge_hostcpy(h1_cpy,h1);
 
1268
      sge_hostcpy(h2_cpy,h2);
 
1269
 
 
1270
      cmp = SGE_STRCASECMP(h1_cpy, h2_cpy); 
 
1271
 
 
1272
      DPRINTF(("sge_hostcmp(%s, %s) = %d\n", h1_cpy, h2_cpy));
 
1273
   }
 
1274
 
 
1275
   DEXIT;
 
1276
   return cmp;
 
1277
}
 
1278
 
 
1279
/****** uti/hostname/sge_hostmatch() ********************************************
 
1280
*  NAME
 
1281
*     sge_hostmatch() -- fnmatch() for hostnames
 
1282
*
 
1283
*  SYNOPSIS
 
1284
*     int sge_hostmatch(const char *h1, const char*h2)
 
1285
*
 
1286
*  FUNCTION
 
1287
*     fnmatch() for hostnames. Honours some configuration values:
 
1288
*        - Domain name may be ignored
 
1289
*        - Domain name may be replaced by a 'default domain'
 
1290
*        - Hostnames may be used as they are.
 
1291
*
 
1292
*  INPUTS
 
1293
*     const char *h1 - 1st hostname
 
1294
*     const char *h2 - 2nd hostname
 
1295
*
 
1296
*  RESULT
 
1297
*     int - 0, 1 or -1
 
1298
*
 
1299
*  SEE ALSO
 
1300
*     uti/hostname/sge_hostcmp()
 
1301
*     uti/hostname/sge_hostcpy()
 
1302
*
 
1303
*  NOTES:
 
1304
*     MT-NOTE: sge_hostmatch() is MT safe
 
1305
******************************************************************************/
 
1306
int sge_hostmatch(const char *h1, const char*h2)
 
1307
{
 
1308
   int cmp = -1;
 
1309
   char h1_cpy[CL_MAXHOSTLEN+1], h2_cpy[CL_MAXHOSTLEN+1];
 
1310
 
 
1311
 
 
1312
   DENTER(BASIS_LAYER, "sge_hostmatch");
 
1313
 
 
1314
   if (h1 != NULL && h2 != NULL) {
 
1315
      sge_hostcpy(h1_cpy,h1);
 
1316
      sge_hostcpy(h2_cpy,h2);
 
1317
 
 
1318
      cmp=fnmatch(h1_cpy, h2_cpy, 0);
 
1319
 
 
1320
      DPRINTF(("sge_hostmatch(%s, %s) = %d\n", h1_cpy, h2_cpy));
 
1321
   }
 
1322
 
 
1323
   DEXIT;
 
1324
   return cmp;
 
1325
}
 
1326
 
 
1327
 
 
1328
/****** uti/hostname/is_hgroup_name() ****************************************
 
1329
*  NAME
 
1330
*     is_hgroup_name() -- Is the given name a hostgroup name 
 
1331
*
 
1332
*  SYNOPSIS
 
1333
*     bool is_hgroup_name(const char *name) 
 
1334
*
 
1335
*  FUNCTION
 
1336
*     Is the given name a hostgroup name 
 
1337
*
 
1338
*  NOTE
 
1339
*     This function is also used for usergroup in resource quota sets
 
1340
*
 
1341
*  INPUTS
 
1342
*     const char *name - hostname or hostgroup name 
 
1343
*
 
1344
*  RESULT
 
1345
*     bool - true for hostgroupnames otherwise false
 
1346
******************************************************************************/
 
1347
bool 
 
1348
is_hgroup_name(const char *name)
 
1349
{
 
1350
   bool ret = false;
 
1351
 
 
1352
   if (name != NULL) {
 
1353
      ret = (name[0] == HOSTGROUP_INITIAL_CHAR) ? true : false;
 
1354
   }
 
1355
   return ret;
 
1356
}