Пример #1
0
/*  7.1  */
const SWmlNode * lookupElement(SDocData *data)
{
/* 1. Pick up the name of the current element from event list.
 * 2. Look into table of tags/elements of SWmlDescriptor for it.
 * 3. Return the corresponding node, or the node of the unknown element.
 * 
 * Note: The value of the current XML event must exits.
 * Assume the calling takes place from the proper context.
 *---------------------------------------------------------------------------
 */
/* Data Structures */
  PString           _str;   /* name of the element                  */
  unsigned          _idx;   /* the index of element in the table    */
  const SWmlNode  * _node;  /* traverses the list                   */
  
/*  Code  */
  _str  = data->m_eventList.m_head->m_tokenValue;
  _idx  = (!STR_LEN(_str)) ? 0 : (*STR_DATA(_str))&0x7f;
  _node = FIRST_NODE(data->m_desc->m_elements[_idx]);
  

  while(_node && !STR_SAME(_node->m_name, _str))
      _node = _node->m_next;

  return _node ? _node : g_unknownElement;
}
Пример #2
0
void    master_config(void)
{
    MASTER_SERV *entry;
    MASTER_SERV *serv;

#define STR_DIFF	strcmp
#define STR_SAME	!strcmp
#define SWAP(type,a,b)	{ type temp = a; a = b; b = temp; }

    /*
     * A service is identified by its endpoint name AND by its transport
     * type, not just by its name alone. The name is unique within its
     * transport type. XXX Service privacy is encoded in the service name.
     */
    set_master_ent();
    while ((entry = get_master_ent()) != 0) {
	if (msg_verbose)
	    print_master_ent(entry);
	for (serv = master_head; serv != 0; serv = serv->next)
	    if (STR_SAME(serv->name, entry->name) && serv->type == entry->type)
		break;

	/*
	 * Add a new service entry. We do not really care in what order the
	 * service entries are kept in memory.
	 */
	if (serv == 0) {
	    entry->next = master_head;
	    master_head = entry;
	    master_start_service(entry);
	}

	/*
	 * Update an existing service entry. Make the current generation of
	 * child processes commit suicide whenever it is convenient. The next
	 * generation of child processes will run with the new configuration
	 * settings.
	 */
	else {
	    serv->flags &= ~MASTER_FLAG_MARK;
	    if (entry->flags & MASTER_FLAG_CONDWAKE)
		serv->flags |= MASTER_FLAG_CONDWAKE;
	    else
		serv->flags &= ~MASTER_FLAG_CONDWAKE;
	    serv->wakeup_time = entry->wakeup_time;
	    serv->max_proc = entry->max_proc;
	    serv->throttle_delay = entry->throttle_delay;
	    SWAP(char *, serv->ext_name, entry->ext_name);
	    SWAP(char *, serv->path, entry->path);
	    SWAP(ARGV *, serv->args, entry->args);
	    SWAP(char *, serv->stress_param_val, entry->stress_param_val);
	    master_restart_service(serv, DO_CONF_RELOAD);
	    free_master_ent(entry);
	}
    }
    end_master_ent();
}
Пример #3
0
/*  7.2  */
const SWmlNode * lookupAttr(SDocData *data,
                            const SWmlNode *element)
{
/* 1. Pick up the name of the current current attribute from event list.
 * 2. If the 'element' had that attribute: return it.
 * 3. If the attribute was found in the table of attributes of the
 *    SWmlDescriptor: return it.
 * 4. Otherwise return the 'unknown' attribute.
 *
 * Note: The value of the current XML event must exits.
 * Assume the calling takes place from the proper context.
 *---------------------------------------------------------------------------
 */
/* Data Structures */
  PString           _str  = data->m_eventList.m_head->m_tokenValue;
  const SWmlNode  * _node = FIRST_NODE(element->m_children);
  unsigned          _idx;
  
/*  Code  */
  DBG_LOG2( (DBG_WML, _str, "lookupAttr:") );
  while(_node && !STR_SAME(_node->m_name, _str)) {
      DBG_LOG2( (DBG_WML, _node->m_name, "   ?:") );
      _node = _node->m_next;
  }

  if(!_node) { 
      /* global attributes */
      _idx  = (!STR_LEN(_str)) ? 0 : (*STR_DATA(_str))&0x7f;
      _node = FIRST_NODE(data->m_desc->m_attributes[_idx]);

      while(_node && !STR_SAME(_node->m_name, _str))
          _node = _node->m_next;
  }
  DBG_LOG( (DBG_WML, "lookupAttr: found: %p",_node ) );

  return _node ? _node : g_unknownAttribute;
}
Пример #4
0
/*  7.3  */
SWmlString  * lookupString(SDocData *data,
                           PString str)
{
/*  Search for 'str' in 'stringTable' of DocData.
 *  Return the node or NULL.
 *---------------------------------------------------------------------------
 */
/* Data Structures */
  unsigned     _idx  = (!STR_LEN(str)) ? 0 : (*STR_DATA(str))&0x7f;
  SWmlString * _node = FIRST_NODE(data->m_stringTable[_idx]);
  
/*  Code  */
  while(_node && !STR_SAME(_node->m_string, str))
      _node = _node->m_next;

  return _node;
}
Пример #5
0
MASTER_SERV *get_master_ent()
{
    VSTRING *buf = vstring_alloc(100);
    VSTRING *junk = vstring_alloc(100);
    MASTER_SERV *serv;
    char   *cp;
    char   *name;
    char   *host = 0;
    char   *port = 0;
    char   *transport;
    int     private;
    int     unprivileged;		/* passed on to child */
    int     chroot;			/* passed on to child */
    char   *command;
    int     n;
    char   *bufp;
    char   *atmp;
    const char *parse_err;
    static char *saved_interfaces = 0;
    char   *err;

    if (master_fp == 0)
	msg_panic("get_master_ent: config file not open");
    if (master_disable == 0)
	msg_panic("get_master_ent: no service disable list");

    /*
     * XXX We cannot change the inet_interfaces setting for a running master
     * process. Listening sockets are inherited by child processes so that
     * closing and reopening those sockets in the master does not work.
     * 
     * Another problem is that library routines still cache results that are
     * based on the old inet_interfaces setting. It is too much trouble to
     * recompute everything.
     * 
     * In order to keep our data structures consistent we ignore changes in
     * inet_interfaces settings, and issue a warning instead.
     */
    if (saved_interfaces == 0)
	saved_interfaces = mystrdup(var_inet_interfaces);

    /*
     * Skip blank lines and comment lines.
     */
    for (;;) {
	if (readllines(buf, master_fp, &master_line_last, &master_line) == 0) {
	    vstring_free(buf);
	    vstring_free(junk);
	    return (0);
	}
	bufp = vstring_str(buf);
	if ((cp = mystrtok(&bufp, master_blanks)) == 0)
	    continue;
	name = cp;
	transport = get_str_ent(&bufp, "transport type", (char *) 0);
	vstring_sprintf(junk, "%s/%s", name, transport);
	if (match_service_match(master_disable, vstring_str(junk)) == 0)
	    break;
    }

    /*
     * Parse one logical line from the configuration file. Initialize service
     * structure members in order.
     */
    serv = (MASTER_SERV *) mymalloc(sizeof(MASTER_SERV));
    serv->next = 0;

    /*
     * Flags member.
     */
    serv->flags = 0;

    /*
     * All servers busy warning timer.
     */
    serv->busy_warn_time = 0;

    /*
     * Service name. Syntax is transport-specific.
     */
    serv->ext_name = mystrdup(name);

    /*
     * Transport type: inet (wild-card listen or virtual) or unix.
     */
#define STR_SAME	!strcmp

    if (STR_SAME(transport, MASTER_XPORT_NAME_INET)) {
	if (!STR_SAME(saved_interfaces, var_inet_interfaces)) {
	    msg_warn("service %s: ignoring %s change",
		     serv->ext_name, VAR_INET_INTERFACES);
	    msg_warn("to change %s, stop and start Postfix",
		     VAR_INET_INTERFACES);
	}
	serv->type = MASTER_SERV_TYPE_INET;
	atmp = mystrdup(name);
	if ((parse_err = host_port(atmp, &host, "", &port, (char *) 0)) != 0)
	    fatal_with_context("%s in \"%s\"", parse_err, name);
	if (*host) {
	    serv->flags |= MASTER_FLAG_INETHOST;/* host:port */
	    MASTER_INET_ADDRLIST(serv) = (INET_ADDR_LIST *)
		mymalloc(sizeof(*MASTER_INET_ADDRLIST(serv)));
	    inet_addr_list_init(MASTER_INET_ADDRLIST(serv));
	    if (inet_addr_host(MASTER_INET_ADDRLIST(serv), host) == 0)
		fatal_with_context("bad hostname or network address: %s", name);
	    inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv));
	    serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
	} else {
	    MASTER_INET_ADDRLIST(serv) =
		strcasecmp(saved_interfaces, INET_INTERFACES_ALL) ?
		own_inet_addr_list() :		/* virtual */
		wildcard_inet_addr_list();	/* wild-card */
	    inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv));
	    serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
	}
	MASTER_INET_PORT(serv) = mystrdup(port);
	for (n = 0; /* see below */ ; n++) {
	    if (n >= MASTER_INET_ADDRLIST(serv)->used) {
		serv->flags |= MASTER_FLAG_LOCAL_ONLY;
		break;
	    }
	    if (!sock_addr_in_loopback(SOCK_ADDR_PTR(MASTER_INET_ADDRLIST(serv)->addrs + n)))
		break;
	}
    } else if (STR_SAME(transport, MASTER_XPORT_NAME_UNIX)) {
	serv->type = MASTER_SERV_TYPE_UNIX;
	serv->listen_fd_count = 1;
	serv->flags |= MASTER_FLAG_LOCAL_ONLY;
    } else if (STR_SAME(transport, MASTER_XPORT_NAME_UXDG)) {
	serv->type = MASTER_SERV_TYPE_UXDG;
	serv->listen_fd_count = 1;
	serv->flags |= MASTER_FLAG_LOCAL_ONLY;
    } else if (STR_SAME(transport, MASTER_XPORT_NAME_FIFO)) {
	serv->type = MASTER_SERV_TYPE_FIFO;
	serv->listen_fd_count = 1;
	serv->flags |= MASTER_FLAG_LOCAL_ONLY;
#ifdef MASTER_SERV_TYPE_PASS
    } else if (STR_SAME(transport, MASTER_XPORT_NAME_PASS)) {
	serv->type = MASTER_SERV_TYPE_PASS;
	serv->listen_fd_count = 1;
	/* If this is a connection screener, remote clients are likely. */
#endif
    } else {
	fatal_with_context("bad transport type: %s", transport);
    }

    /*
     * Service class: public or private.
     */
    private = get_bool_ent(&bufp, "private", "y");