Logo Search packages:      
Sourcecode: ksh version File versions

csaddr.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*           Copyright (c) 1990-2007 AT&T Knowledge Ventures            *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                      by AT&T Knowledge Ventures                      *
*                                                                      *
*                A copy of the License is available at                 *
*            http://www.opensource.org/licenses/cpl1.0.txt             *
*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
*                                                                      *
*              Information and Software Systems Research               *
*                            AT&T Research                             *
*                           Florham Park NJ                            *
*                                                                      *
*                 Glenn Fowler <gsf@research.att.com>                  *
*                                                                      *
***********************************************************************/
#pragma prototyped
/*
 * Glenn Fowler
 * AT&T Research
 *
 * return the address of a host given its name
 */

#include "cslib.h"

union nl
{
      unsigned char     c[4];
      uint32_t    l;
};

static unsigned long    local;

/*
 * real name to address conversion
 */

static unsigned long
realaddr(register Cs_t* state, const char* name)
{
      register int            n;
      register const char*    s;
      int               r;
      const char*       t;
      union nl          addr;

#if CS_LIB_SOCKET

      register struct hostent*      hp;

#endif
      messagef((state->id, NiL, -8, "realaddr(%s) call", name));
      state->flags &= ~CS_ADDR_NUMERIC;
      s = name;
      if (streq(s, CS_HOST_LOCAL))
      {
            messagef((state->id, NiL, -8, "realaddr(%s) = %s, flags = |%s%s%s", name, csntoa(state, local), (state->flags & CS_ADDR_LOCAL) ? "LOCAL|" : "", (state->flags & CS_ADDR_REMOTE) ? "REMOTE|" : "", (state->flags & CS_ADDR_SHARE) ? "SHARE|" : ""));
            return local;
      }

      /*
       * check for 0xX.X.X.X or n.n.n.n
       */

      if (*s == '0' && *(s + 1) == 'x')
      {
            s += 2;
            r = 16;
      }
      else r = 0;
      addr.l = 0;
      n = 0;
      do
      {
            addr.c[n] = strtol(s, (char**)&t, r) & 0xff;
            if (t == s) break;
            s = t;
      } while (++n < 4 && *s && *s++ == '.');
      if (!*s && n == 4)
      {
            if (!addr.l || addr.c[0] == 127 && addr.c[1] == 0 && addr.c[2] == 0 && addr.c[3] <= 1)
            {
                  addr.l = csaddr(state, NiL);
                  if (local == CS_LOCAL)
                  {
                        addr.c[0] = 127;
                        addr.c[1] = 0;
                        addr.c[2] = 0;
                        addr.c[3] = 1;
                        local = addr.l;
                  }
                  else
                        addr.l = local;
            }
            state->flags |= CS_ADDR_NUMERIC;
            messagef((state->id, NiL, -8, "realaddr(%s) = %s, flags = |%s%s%s", name, csntoa(state, addr.l), (state->flags & CS_ADDR_LOCAL) ? "LOCAL|" : "", (state->flags & CS_ADDR_REMOTE) ? "REMOTE|" : "", (state->flags & CS_ADDR_SHARE) ? "SHARE|" : ""));
            return addr.l;
      }

      /*
       * local conversion
       */

      csdb(state);

#if CS_LIB_V10 || CS_LIB_SOCKET

#if CS_LIB_V10
      if ((addr.l = (unsigned long)in_address(name)) == INADDR_ANY)
            addr.l = 0;
#else
      addr.l = ((hp = gethostbyname(name)) && hp->h_addrtype == AF_INET && hp->h_length <= sizeof(struct in_addr)) ? (unsigned long)((struct in_addr*)hp->h_addr)->s_addr : 0;
#endif
      if (addr.c[0] == 127 && addr.c[1] == 0 && addr.c[2] == 0 && addr.c[3] <= 1)
      {
            if (local == CS_LOCAL)
                  local = addr.l;
            else
                  addr.l = local;
      }
      messagef((state->id, NiL, -8, "realaddr(%s) = %s, flags = |%s%s%s", name, csntoa(state, addr.l), (state->flags & CS_ADDR_LOCAL) ? "LOCAL|" : "", (state->flags & CS_ADDR_REMOTE) ? "REMOTE|" : "", (state->flags & CS_ADDR_SHARE) ? "SHARE|" : ""));
#else
      messagef((state->id, NiL, -8, "realaddr(%s) not found", name));
      addr.l = 0;
#endif
      return addr.l;
}

/*
 * address conversion with CS_HOST_* aliases
 * 0 returned on failure
 * on success:
 *
 *    state->flags      CS_ADDR_* changed to match real host name
 *    state->host real host name after aliases and local truncation
 */

unsigned long
csaddr(register Cs_t* state, const char* aname)
{
      register char*          name = (char*)aname;
      register char*          s;
      register unsigned long  addr;
      register Sfio_t*  sp = 0;
      int               userlen = 0;
      int               dot = 0;
      long              flags = 0;
      char*             user;

      messagef((state->id, NiL, -8, "addr(%s) call", name));
      if (!local)
      {
#if CS_LIB_SOCKET
            if (!state->db)
                  state->db = -1;
#endif
            local = CS_LOCAL;
            if (addr = realaddr(state, csname(state, 0)))
                  local = addr;
      }
      if (!name)
      {
            addr = local;
            goto ok;
      }
      if (s = strchr(name, '@'))
      {
            userlen = s - name;
            user = name;
            name = s + 1;
      }
      if (strneq(name, CS_HOST_SHARE, sizeof(CS_HOST_SHARE) - 1))
            switch (name[sizeof(CS_HOST_SHARE) - 1])
            {
            case 0:
                  flags |= CS_ADDR_SHARE;
                  if (sp = csinfo(state, name, NiL))
                  {
                        while (name = sfgetr(sp, '\n', 1))
                              if (addr = realaddr(state, name))
                                    goto ok;
                        sfclose(sp);
                        sp = 0;
                  }
                  if (!(addr = realaddr(state, name = CS_HOST_GATEWAY)))
                        addr = local;
                  goto ok;
            case '.':
                  flags |= CS_ADDR_SHARE;
                  name += sizeof(CS_HOST_SHARE);
                  break;
            }
      if (addr = realaddr(state, name))
            goto ok;
      if ((flags & CS_ADDR_SHARE) && !(state->flags & CS_ADDR_NUMERIC) && (s = strchr(name, '.')))
      {
            char*             sb;
            char*             se;
            char*             sx;
            char*             t;
            char*             te;

            dot = s - name;
            s = state->temp;
            sx = &state->temp[sizeof(state->temp) - 1];
            s += sfsprintf(s, sx - s, "%s/", CS_SVC_REMOTE);
            sb = s;
            se = 0;
            t = name;
            while (*t && s < sx)
            {
                  if (s - sb >= CS_MNT_MAX)
                  {
                        if (se)
                        {
                              s = se - 1;
                              t = te;
                        }
                        else
                        {
                              if (s >= sx) break;
                              if (*t == '.') t++;
                        }
                        *s++ = '/';
                        sb = s;
                        se = 0;
                  }
                  if ((*s++ = *t++) == '.')
                  {
                        se = s;
                        te = t;
                  }
            }
            *s = 0;
            if (sp = csinfo(state, state->temp, NiL))
            {
                  while (t = sfgetr(sp, '\n', 1))
                  {
                        if (s = strchr(t, '@')) s++;
                        else s = t;
                        if (addr = realaddr(state, s))
                        {
                              name = s;
                              if (!userlen && s != t)
                              {
                                    userlen = s - t - 1;
                                    user = t;
                              }
                              goto ok;
                        }
                  }
                  sfclose(sp);
                  sp = 0;
            }
            sfsprintf(state->temp, sizeof(state->temp), "%s.%s", CS_HOST_GATEWAY, name);
            if (addr = realaddr(state, state->temp))
            {
                  name = state->temp;
                  goto ok;
            }
            sfsprintf(state->temp, sizeof(state->temp), "%-.*s.%s", dot, name, name);
            if (addr = realaddr(state, state->temp))
            {
                  name = state->temp;
                  goto ok;
            }
      }
      messagef((state->id, NiL, -1, "addr: %s: not found", aname));
      return 0;
 ok:
      if (state->flags & CS_ADDR_NUMERIC)
            flags &= ~CS_ADDR_SHARE;
      if (addr == local)
      {
            flags |= CS_ADDR_LOCAL;
            name = csname(state, 0);
      }
      else if (!(state->flags & CS_ADDR_NUMERIC))
      {
            if (s = strchr(name, '.'))
            {
                  sfsprintf(state->temp, sizeof(state->temp), "%-.*s", s - name, name);
                  if (realaddr(state, state->temp) == addr)
                        name = state->temp;
                  else flags |= CS_ADDR_REMOTE;
            }
            if (!(flags & CS_ADDR_REMOTE) && !streq(name, CS_HOST_PROXY) && !csattr(state, name, "*"))
                  flags |= CS_ADDR_REMOTE;
      }

      /*
       * cache host name and user for possible CS_REMOTE_SHELL
       */

      strncpy(state->host, name, sizeof(state->host) - 1);
      if (userlen)
      {
            if (userlen >= sizeof(state->user)) userlen = sizeof(state->user) - 1;
            strncpy(state->user, user, userlen);
      }
      state->user[userlen] = 0;
      if (sp) sfclose(sp);
      state->flags &= ~(CS_ADDR_LOCAL|CS_ADDR_NOW|CS_ADDR_REMOTE|CS_ADDR_SHARE|CS_DAEMON_SLAVE|CS_ADDR_TEST|CS_ADDR_TRUST);
      state->flags |= flags;
      messagef((state->id, NiL, -8, "addr(%s) = %s, flags = |%s%s%s", aname, csntoa(state, addr), (state->flags & CS_ADDR_LOCAL) ? "LOCAL|" : "", (state->flags & CS_ADDR_REMOTE) ? "REMOTE|" : "", (state->flags & CS_ADDR_SHARE) ? "SHARE|" : ""));
      return addr;
}

unsigned long
_cs_addr(const char* aname)
{
      return csaddr(&cs, aname);
}

Generated by  Doxygen 1.6.0   Back to index