示例#1
0
文件: alias.c 项目: baohaojun/dico
int
alias_install(const char *kw, int argc, char **argv, grecs_locus_t *ploc)
{
    struct alias *sample = xmalloc(sizeof(*sample)),
                  *ap;

    sample->kw = xstrdup(kw);
    sample->argc = argc;
    sample->argv = argv;
    sample->locus = *ploc;

    if (! ((alias_table
            || (alias_table = hash_initialize(0, 0,
                              alias_hasher,
                              alias_compare,
                              NULL)))
            && (ap = hash_insert(alias_table, sample))))
        xalloc_die();

    if (ap != sample) {
        free(sample->kw);
        free(sample);
        grecs_error(ploc, 0, _("alias `%s' already defined"), kw);
        grecs_error(&ap->locus, 0,
                    _("this is the location of the previous definition"));
        return 1; /* Found */
    }
    return 0;
}
示例#2
0
int
grecs_str_to_sockaddr(struct grecs_sockaddr **sap,
		      const char *arg, struct grecs_sockaddr_hints *gh,
		      grecs_locus_t const *locus)
{
	char *p;
	struct grecs_sockaddr_hints ghints;
	
	if (!gh) {
		memset(&ghints, 0, sizeof(ghints));
		if (grecs_default_port) {
			ghints.flags = GRECS_HINT_PORT;
			ghints.port = ntohs(grecs_default_port);
		}
		gh = &ghints;
	}
	
	p = strchr(arg, ':');
	if (p && p > arg && p[1] == '/' && p[2] == '/') {
		size_t len = p - arg;
		struct schemetab *sp;

		for (sp = schemetab; sp->scheme; sp++)
			if (len == sp->len &&
			    memcmp(arg, sp->scheme, len) == 0)
				return sp->parser(sap, arg, p + 3, gh, locus);
		grecs_error(locus, 0,
			    _("unknown or unsupported scheme: %s"), arg);
		return -1;
	}

	if (arg[0] == '/')
		return parse_unix(sap, arg, arg, gh, locus);
	else if (strlen(arg) > 5 && memcmp(arg, "unix:", 5) == 0) {
		if (arg[5] != '/')
			grecs_error(locus, 0,
				    _("%s: UNIX socket must be an absolute file name"),
				    arg);
		return parse_unix(sap, arg, arg + 5, gh, locus);
	}
	
	return parse_inet(sap, AF_UNSPEC, arg, arg, gh, locus);
}
示例#3
0
文件: acl.c 项目: baohaojun/dico
dico_list_t
dicod_string_list_from_grecs(struct grecs_list *inlist)
{
    struct grecs_list_entry *ep;

    dico_list_t list = xdico_list_create();
    dico_list_set_free_item(list, dicod_free_item, NULL);

    for (ep = inlist->head; ep; ep = ep->next) {
	grecs_value_t *vp = ep->data;
	if (vp->type != GRECS_TYPE_STRING) {
	    grecs_error(&vp->locus, 0, _("expected string"));
	    break;
	}
	xdico_list_append(list, xstrdup(vp->v.string));
    }
    return list;
}
示例#4
0
static int
parse_unix(struct grecs_sockaddr **ret, const char *arg, const char *addrstr,
	   struct grecs_sockaddr_hints *gh, grecs_locus_t const *locus)
{
	struct sockaddr_un *s_un;
	size_t slen = strlen(addrstr);
	struct grecs_sockaddr *sp;
	
	if (slen >= sizeof s_un->sun_path) {
		grecs_error(locus, 0, _("socket path name too long: %s"), arg);
		return -1;
	}
	
	sp = grecs_sockaddr_new(sizeof(s_un[0]));
	s_un = (struct sockaddr_un *) sp->sa;
	s_un->sun_family = AF_UNIX;
	strcpy(s_un->sun_path, addrstr);

	*ret = sp;
	return 0;
}
示例#5
0
struct grecs_node *
grecs_path_parser(const char *name, int traceflags)
{
	struct grecs_node *root, *subtree = NULL, *node;
	FILE *infile;
	struct grecs_txtacc *acc = NULL;
	char *kw, *val;
	grecs_locus_t kwloc, valloc, rootloc;
	int inquote;
	int lookahead;
	int err = 0;
	unsigned prev_col;
	
	infile = fopen(name, "r");
	if (!infile) {
		grecs_error(NULL, errno, _("cannot open `%s'"), name);
		return NULL;
	}
	grecs_current_locus_point.file = grecs_install_text(name);
	grecs_current_locus_point.line = 1;
	grecs_current_locus_point.col = 0;
	rootloc.beg = grecs_current_locus_point;
	rootloc.beg.col++;
	
	acc = grecs_txtacc_create();
	
	while ((lookahead = next_char(infile)) > 0) {
		while (1) {
			while (lookahead == ' ' || lookahead == '\t')
				lookahead = next_char(infile);

			if (lookahead == '#') {
				while ((lookahead = next_char(infile)) &&
				       lookahead != '\n')
					;
				continue;
			}
			break;
		}
		
		if (lookahead <= 0)
			break;

		kwloc.beg = grecs_current_locus_point;

		inquote = 0;
		for (; lookahead > 0 && lookahead != ':';
		     lookahead = next_char(infile)) {
			if (inquote) {
				if (inquote == '"' && lookahead == '\\') {
					lookahead = next_char(infile);
					if (lookahead <= 0)
						break;
				} else if (lookahead == inquote)
					inquote = 0;
			} else if (lookahead == '\'' || lookahead == '"')
				inquote = lookahead;
			grecs_txtacc_grow_char(acc, lookahead);
		}
		
		if (lookahead <= 0) {
			grecs_error(&kwloc, 0, _("unexpected end of file"));
			err = 1;
			break;
		}

		grecs_txtacc_grow_char(acc, 0);
		kw = grecs_txtacc_finish(acc, 0);

		kwloc.end = grecs_current_locus_point;
		kwloc.end.col--;
		
		while ((lookahead = next_char(infile)) > 0 &&
		       (lookahead == ' ' || lookahead == '\t'));

		if (lookahead <= 0) {
			grecs_error(&kwloc, 0, _("unexpected end of file"));
			err = 1;
			break;
		}

		valloc.beg = grecs_current_locus_point;
		do {
			grecs_txtacc_grow_char(acc, lookahead);
			prev_col = grecs_current_locus_point.col;
		} while ((lookahead = next_char(infile)) > 0 &&
			 lookahead != '\n');
		valloc.end = grecs_current_locus_point;
		valloc.end.line--;
		valloc.end.col = prev_col;
		
		grecs_txtacc_grow_char(acc, 0);
		val = grecs_txtacc_finish(acc, 0);

		node = grecs_node_from_path_locus(kw, val, &kwloc, &valloc);
		if (!node) {
			grecs_error(&kwloc, 0, _("parse error"));
			err = 1;
			break;
		}
		node->locus.end = valloc.end;
		node->idloc = kwloc;
		
		if (!subtree)
			subtree = node;
		else
			grecs_node_bind(subtree, node, 0);
		grecs_txtacc_free_string(acc, kw);
		grecs_txtacc_free_string(acc, val);
	}

	fclose(infile);
	grecs_txtacc_free(acc);

	if (err) {
		grecs_tree_free(subtree);
		root = NULL;
	} else {
		rootloc.end = grecs_current_locus_point;
		root = grecs_node_create(grecs_node_root, &rootloc);
		root->v.texttab = grecs_text_table();
		grecs_node_bind(root, subtree, 1);
		grecs_tree_reduce(root, NULL, 0);
	}
	
	return root;
}
示例#6
0
static int
parse_inet(struct grecs_sockaddr **ret,
	   int family, const char *arg, const char *addrstr,
	   struct grecs_sockaddr_hints *gh, grecs_locus_t const *locus)
{
	int rc;
	struct addrinfo hints;
	struct addrinfo *res, *ap;
	const char *node = NULL;
	char *nodebuf = NULL;
	const char *service = NULL;
	struct grecs_sockaddr *head = NULL, *tail = NULL;
	char portbuf[64];

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = family;
	hints.ai_socktype = SOCK_STREAM;

	if ((family == AF_INET6 || family == AF_UNSPEC)
	    && addrstr[0] == '[') {
		char *p = strchr(addrstr + 1, ']');
		if (p && p > addrstr + 1) {
			size_t len;
			
			addrstr++;
			len = p - addrstr;
			nodebuf = grecs_malloc(len + 1);
			memcpy(nodebuf, addrstr, len);
			nodebuf[len] = 0;
			node = nodebuf;
			service = p + 1;
			family = AF_INET6;
		} else
			service = strchr(addrstr, ':');
	} else
		service = strrchr(addrstr, ':');

	if (service && *service) {
		if (*service != ':') {
			grecs_error(locus, 0,
				    _("%s: garbage near %s"), arg, service);
			return -1;
		}
		service++;
	}
	
	if (!node) {
		if (service) {
			size_t len = service - addrstr - 1;
			
			if (len == 0)
				node = NULL;
			else {
				nodebuf = grecs_malloc(len + 1);
				memcpy(nodebuf, addrstr, len);
				nodebuf[len] = 0;
				node = nodebuf;
			}
		} else {
			if (grecs_str_is_ipaddr(addrstr))
				node = addrstr;
			else if (grecs_str_is_num(addrstr)) {
				service = addrstr;
				hints.ai_flags |= AI_NUMERICSERV;
			}
		}
	}
	
	if (!service || !*service) {
		if (!node && addrstr[0])
			node = addrstr;
		if (gh->flags & GRECS_HINT_SERVICE) {
			service = gh->service;
		} else if (gh->flags & GRECS_HINT_PORT) {
			snprintf(portbuf, sizeof portbuf, "%hu", gh->port);
			service = portbuf;
			hints.ai_flags |= AI_NUMERICSERV;
		} else if (!(gh->flags & GRECS_AH_PASSIVE)) {
			grecs_error(locus, 0,
				    _("service not specified: %s"), arg);
			return -1;
		}
	}
	
	if (!node) {
		if (gh->flags & GRECS_AH_PASSIVE)
			hints.ai_flags |= AI_PASSIVE;
	}
	
	rc = getaddrinfo(node, service, &hints, &res);
	free(nodebuf);
	switch (rc) {
	case 0:
		break;
	case EAI_SYSTEM:
		grecs_error(locus, 0,
			    _("%s: cannot parse address: %s"),
			    arg, strerror(errno));
		break;
	case EAI_BADFLAGS:
	case EAI_SOCKTYPE:
		grecs_error(locus, 0,
			    "%s:%d: internal error converting %s",
			    __FILE__,__LINE__,arg);
		break;
	case EAI_MEMORY:
		grecs_alloc_die();
	default:
		grecs_error(locus, 0,
			    "%s: %s", arg, gai_strerror(rc));
		return -1;
	}

	for (ap = res; ap; ap = ap->ai_next) {
		if (family == AF_UNSPEC || ap->ai_addr->sa_family == family) {
			struct grecs_sockaddr *sp =
				grecs_sockaddr_new(ap->ai_addrlen);
			memcpy(sp->sa, ap->ai_addr, ap->ai_addrlen);
			sp->len = ap->ai_addrlen;
			if (!head)
				head = sp;
			else
				tail->next = sp;
			tail = sp;
		}
	}
	freeaddrinfo(res);
	*ret = head;
	return 0;
}
示例#7
0
文件: acl.c 项目: baohaojun/dico
static int
_parse_sockaddr(struct acl_entry *entry, grecs_value_t *value)
{
    struct dicod_sockaddr *sptr;
    const char *string;

    if (value->type != GRECS_TYPE_STRING) {
	grecs_error(&entry->locus, 0, _("expected string but found list"));
	return 1;
    }

    string = value->v.string;
    
    if (string[0] == '/') {
	size_t len;
	struct sockaddr_un *s_un;
	
	len = strlen (string);
	if (len >= sizeof(s_un->sun_path)) {
	    grecs_error(&entry->locus, 0,
			 _("socket name too long: `%s'"),
			 string);
	    return 1;
	}
	sptr = create_acl_sockaddr(AF_UNIX, sizeof(s_un));
	s_un = (struct sockaddr_un *) &sptr->sa;
	memcpy(s_un->sun_path, string, len);
	s_un->sun_path[len] = 0;
    } else {
	struct in_addr addr;
	struct sockaddr_in *s_in;
	char *p = strchr(string, '/');

	if (p)
	    *p = 0;

	if (inet_aton(string, &addr) == 0) {
	    struct hostent *hp = gethostbyname(string);
	    if (!hp) {
		grecs_error(&entry->locus, 0,
			     _("cannot resolve host name: `%s'"),
			     string);
		if (p)
		    *p = '/';
		return 1;
	    }
	    memcpy(&addr.s_addr, hp->h_addr, sizeof(addr.s_addr));
	}
	addr.s_addr = ntohl(addr.s_addr);

	sptr = create_acl_sockaddr(AF_INET, sizeof(s_in));
	s_in = (struct sockaddr_in *) &sptr->sa;
	s_in->sin_addr = addr;

	if (p) {
	    *p++ = '/';
	    char *q;
	    unsigned netlen;
	  
	    netlen = strtoul(p, &q, 10);
	    if (*q == 0) {
		if (netlen == 0)
		    sptr->netmask = 0;
		else {
		    sptr->netmask = 0xfffffffful >> (32 - netlen);
		    sptr->netmask <<= (32 - netlen);
		}
	    } else if (*q == '.') {
		struct in_addr addr;
	      
		if (inet_aton(p, &addr) == 0) {
		    grecs_error(&entry->locus, 0,
				 _("invalid netmask: `%s'"),
				 p);
		    return 1;
		}
		sptr->netmask = addr.s_addr;
	    } else {
		grecs_error(&entry->locus, 0,
			     _("invalid netmask: `%s'"),
			     p);
		return 1;
	    }
	} else