Logo Search packages:      
Sourcecode: ksh version File versions  Download package

csattr.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*          Copyright (c) 1990-2007 AT&T Intellectual Property          *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                    by AT&T Intellectual Property                     *
*                                                                      *
*                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 local attr attributes for host name
 */

#include "cslib.h"

#include <ctype.h>
#include <hash.h>

typedef struct
{
      HASH_HEADER;
      char        data[1];
} Info_t;

/*
 * load the info from the local info file
 */

static Hash_table_t*
load(register Cs_t* state)
{
      register char*          s;
      char*             h;
      register Info_t*  ip;
      register Sfio_t*  sp;
      register Hash_table_t*  tp;
      int               c;

      if (!(sp = csinfo(state, NiL, NiL))) return 0;
      if (tp = hashalloc(NiL, HASH_set, HASH_ALLOCATE, HASH_name, "state->info", 0))
            while (s = sfgetr(sp, '\n', 1))
            {
                  while (isspace(*s)) s++;
                  h = s;
                  while (!isspace(*s) && *s) s++;
                  if (*s)
                  {
                        c = *s;
                        *s++ = 0;
                        if (!(ip = (Info_t*)hashlook(tp, h, HASH_CREATE|HASH_SIZE(sizeof(Info_t)+strlen(s)+1), NiL)))
                        {
                              hashfree(tp);
                              tp = 0;
                              break;
                        }
                        *--s = c;
                        strcpy(ip->data, s);
                  }
            }
      sfclose(sp);
      return tp;
}

/*
 * info cached on first call and return value placed in static buffer ...
 * if name==0 || name=="-" then all valid records returned by successive
 *    csattr() calls until 0 return
 * if attr==0 || attr=="-" then all attributes returned
 */

char*
csattr(register Cs_t* state, const char* name, const char* attr)
{
      register char*          s;
      register char*          b;
      register char*          x;
      register char*          v;
      register Info_t*  ip;
      int               n;
      unsigned long           addr;

      static Hash_table_t*    tp;
      static Hash_position_t* pt;
      static char       buf[256];

      messagef((state->id, NiL, -8, "attr(%s,%s) call", name, attr));
      if (!tp && !(tp = load(state)))
            return 0;
      if (attr && (!*attr || *attr == '-' && !*(attr + 1)))
            attr = 0;
      b = buf;
      x = &buf[sizeof(buf) - 1];
      if (!name || *name == '-' && !*(name + 1))
      {
            name = 0;
      scan:
            if (!pt && !(pt = hashscan(tp, 0)))
                  return 0;
            n = attr && streq(attr, "name");
            do if (!(ip = (Info_t*)hashnext(pt)))
            {
                  hashdone(pt);
                  pt = 0;
                  return 0;
            } while (n && streq(ip->name, CS_HOST_LOCAL));
            if (n)
                  return ip->name;
            if (attr && streq(attr, "*"))
                  return buf;
            b += sfsprintf(b, x - b, "%s", ip->name);
      }
      else
      {
            if (streq(name, CS_HOST_LOCAL))
                  name = (const char*)csname(state, 0);
            if (!(ip = (Info_t*)hashlook(tp, name, HASH_LOOKUP, NiL)))
                  return 0;
            if (attr)
            {
                  if (streq(attr, "*"))
                        return buf;
                  if (streq(attr, "name"))
                        return csaddr(state, ip->name) ? state->host : ip->name;
                  if (streq(attr, "addr") || streq(attr, "host"))
                  {
                        if (addr = csaddr(state, ip->name))
                              return *attr == 'a' ? csntoa(state, addr) : state->host;
                        return CS_HOST_UNKNOWN;
                  }
            }
      }
      if (!attr)
      {
            v = ip->data;
            if (b == buf) while (isspace(*v)) v++;
            b += sfsprintf(b, x - b, "%s", v);
            if (addr = csaddr(state, ip->name))
            {
                  if (!streq(ip->name, state->host))
                        b += sfsprintf(b, x - b, " host=%s", state->host);
                  b += sfsprintf(b, x - b, " addr=%s", csntoa(state, addr));
            }
      }
      else if (streq(attr, "addr") || streq(attr, "host"))
            b += sfsprintf(b, x - b, " %s", (addr = csaddr(state, ip->name)) ? (*attr == 'a' ? csntoa(state, addr) : state->host) : CS_HOST_UNKNOWN);
      else for (v = ip->data;;)
      {
            while (isspace(*v)) v++;
            if (!*v)
            {
                  if (!name)
                  {
                        b = buf;
                        goto scan;
                  }
                  return 0;
            }
            for (s = (char*)attr; *s && *v == *s++; v++);
            if (!*s && (*v == '=' || !*v || isspace(*v)))
            {
                  if (*v == '=') v++;
                  else v = "1";
                  if (b > buf && b < x) *b++ = ' ';
                  while (b < x && !isspace(*v) && (*b++ = *v++));
                  break;
            }
            while (*v && !isspace(*v)) v++;
      }
      *b = 0;
      return buf;
}

char*
_cs_attr(const char* name, const char* attr)
{
      return csattr(&cs, name, attr);
}

Generated by  Doxygen 1.6.0   Back to index