Beispiel #1
0
Datei: json.c Projekt: 0x0all/mpv
/* Parse the string in *src as JSON, and write the result into *dst.
 * max_depth limits the recursion and JSON tree depth.
 * Warning: this overwrites the input string (what *src points to)!
 * Returns:
 *   0: success, *dst is valid, *src points to the end (the caller must check
 *      whether *src really terminates)
 *  -1: failure, *dst is invalid, there may be dead allocs under ta_parent
 *      (ta_free_children(ta_parent) is the only way to free them)
 * The input string can be mutated in both cases. *dst might contain string
 * elements, which point into the (mutated) input string.
 */
int json_parse(void *ta_parent, struct mpv_node *dst, char **src, int max_depth)
{
    max_depth -= 1;
    if (max_depth < 0)
        return -1;

    eat_ws(src);

    char c = **src;
    if (!c)
        return -1; // early EOF
    if (c == 'n' && strncmp(*src, "null", 4) == 0) {
        *src += 4;
        dst->format = MPV_FORMAT_NONE;
        return 0;
    } else if (c == 't' && strncmp(*src, "true", 4) == 0) {
        *src += 4;
        dst->format = MPV_FORMAT_FLAG;
        dst->u.flag = 1;
        return 0;
    } else if (c == 'f' && strncmp(*src, "false", 5) == 0) {
        *src += 5;
        dst->format = MPV_FORMAT_FLAG;
        dst->u.flag = 0;
        return 0;
    } else if (c == '"') {
        return read_str(ta_parent, dst, src);
    } else if (c == '[' || c == '{') {
        return read_sub(ta_parent, dst, src, max_depth);
    } else if (c == '-' || (c >= '0' && c <= '9')) {
        // The number could be either a float or an int. JSON doesn't make a
        // difference, but the client API does.
        char *nsrci = *src, *nsrcf = *src;
        errno = 0;
        long long int numi = strtoll(*src, &nsrci, 0);
        if (errno)
            nsrci = *src;
        errno = 0;
        double numf = strtod(*src, &nsrcf);
        if (errno)
            nsrcf = *src;
        if (nsrci >= nsrcf) {
            *src = nsrci;
            dst->format = MPV_FORMAT_INT64; // long long is usually 64 bits
            dst->u.int64 = numi;
            return 0;
        }
        if (nsrcf > *src && isfinite(numf)) {
            *src = nsrcf;
            dst->format = MPV_FORMAT_DOUBLE;
            dst->u.double_ = numf;
            return 0;
        }
        return -1;
    }
    return -1; // character doesn't start a valid token
}
Beispiel #2
0
Datei: json.c Projekt: Akemi/mpv
static int read_sub(void *ta_parent, struct mpv_node *dst, char **src,
                    int max_depth)
{
    bool is_arr = eat_c(src, '[');
    bool is_obj = !is_arr && eat_c(src, '{');
    if (!is_arr && !is_obj)
        return -1; // not an array or object
    char term = is_obj ? '}' : ']';
    struct mpv_node_list *list = talloc_zero(ta_parent, struct mpv_node_list);
    while (1) {
        eat_ws(src);
        if (eat_c(src, term))
            break;
        if (list->num > 0 && !eat_c(src, ','))
            return -1; // missing ','
        eat_ws(src);
        // non-standard extension: allow a trailing ","
        if (eat_c(src, term))
            break;
        if (is_obj) {
            struct mpv_node keynode;
            // non-standard extension: allow unquoted strings as keys
            if (read_id(list, &keynode, src) < 0 &&
                read_str(list, &keynode, src) < 0)
                return -1; // key is not a string
            eat_ws(src);
            // non-standard extension: allow "=" instead of ":"
            if (!eat_c(src, ':') && !eat_c(src, '='))
                return -1; // ':' missing
            eat_ws(src);
            MP_TARRAY_GROW(list, list->keys, list->num);
            list->keys[list->num] = keynode.u.string;
        }
        MP_TARRAY_GROW(list, list->values, list->num);
        if (json_parse(ta_parent, &list->values[list->num], src, max_depth) < 0)
            return -1;
        list->num++;
    }
    dst->format = is_obj ? MPV_FORMAT_NODE_MAP : MPV_FORMAT_NODE_ARRAY;
    dst->u.list = list;
    return 0;
}
Beispiel #3
0
static int def_load_bio(CONF *conf, BIO *in, long *line)
{
/* The macro BUFSIZE conflicts with a system macro in VxWorks */
#define CONFBUFSIZE     512
    int bufnum = 0, i, ii;
    BUF_MEM *buff = NULL;
    char *s, *p, *end;
    int again;
    long eline = 0;
    char btmp[DECIMAL_SIZE(eline) + 1];
    CONF_VALUE *v = NULL, *tv;
    CONF_VALUE *sv = NULL;
    char *section = NULL, *buf;
    char *start, *psection, *pname;
    void *h = (void *)(conf->data);
    STACK_OF(BIO) *biosk = NULL;
#ifndef OPENSSL_NO_POSIX_IO
    char *dirpath = NULL;
    OPENSSL_DIR_CTX *dirctx = NULL;
#endif

    if ((buff = BUF_MEM_new()) == NULL) {
        CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
        goto err;
    }

    section = OPENSSL_strdup("default");
    if (section == NULL) {
        CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (_CONF_new_data(conf) == 0) {
        CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    sv = _CONF_new_section(conf, section);
    if (sv == NULL) {
        CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
        goto err;
    }

    bufnum = 0;
    again = 0;
    for (;;) {
        if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) {
            CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
            goto err;
        }
        p = &(buff->data[bufnum]);
        *p = '\0';
 read_retry:
        BIO_gets(in, p, CONFBUFSIZE - 1);
        p[CONFBUFSIZE - 1] = '\0';
        ii = i = strlen(p);
        if (i == 0 && !again) {
            /* the currently processed BIO is at EOF */
            BIO *parent;

#ifndef OPENSSL_NO_POSIX_IO
            /* continue processing with the next file from directory */
            if (dirctx != NULL) {
                BIO *next;

                if ((next = get_next_file(dirpath, &dirctx)) != NULL) {
                    BIO_vfree(in);
                    in = next;
                    goto read_retry;
                } else {
                    OPENSSL_free(dirpath);
                    dirpath = NULL;
                }
            }
#endif
            /* no more files in directory, continue with processing parent */
            if ((parent = sk_BIO_pop(biosk)) == NULL) {
                /* everything processed get out of the loop */
                break;
            } else {
                BIO_vfree(in);
                in = parent;
                goto read_retry;
            }
        }
        again = 0;
        while (i > 0) {
            if ((p[i - 1] != '\r') && (p[i - 1] != '\n'))
                break;
            else
                i--;
        }
        /*
         * we removed some trailing stuff so there is a new line on the end.
         */
        if (ii && i == ii)
            again = 1;          /* long line */
        else {
            p[i] = '\0';
            eline++;            /* another input line */
        }

        /* we now have a line with trailing \r\n removed */

        /* i is the number of bytes */
        bufnum += i;

        v = NULL;
        /* check for line continuation */
        if (bufnum >= 1) {
            /*
             * If we have bytes and the last char '\\' and second last char
             * is not '\\'
             */
            p = &(buff->data[bufnum - 1]);
            if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) {
                bufnum--;
                again = 1;
            }
        }
        if (again)
            continue;
        bufnum = 0;
        buf = buff->data;

        clear_comments(conf, buf);
        s = eat_ws(conf, buf);
        if (IS_EOF(conf, *s))
            continue;           /* blank line */
        if (*s == '[') {
            char *ss;

            s++;
            start = eat_ws(conf, s);
            ss = start;
 again:
            end = eat_alpha_numeric(conf, ss);
            p = eat_ws(conf, end);
            if (*p != ']') {
                if (*p != '\0' && ss != p) {
                    ss = p;
                    goto again;
                }
                CONFerr(CONF_F_DEF_LOAD_BIO,
                        CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
                goto err;
            }
            *end = '\0';
            if (!str_copy(conf, NULL, &section, start))
                goto err;
            if ((sv = _CONF_get_section(conf, section)) == NULL)
                sv = _CONF_new_section(conf, section);
            if (sv == NULL) {
                CONFerr(CONF_F_DEF_LOAD_BIO,
                        CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
                goto err;
            }
            continue;
        } else {
            pname = s;
            end = eat_alpha_numeric(conf, s);
            if ((end[0] == ':') && (end[1] == ':')) {
                *end = '\0';
                end += 2;
                psection = pname;
                pname = end;
                end = eat_alpha_numeric(conf, end);
            } else {
                psection = section;
            }
            p = eat_ws(conf, end);
            if (strncmp(pname, ".include", 8) == 0
                && (p != pname + 8 || *p == '=')) {
                char *include = NULL;
                BIO *next;

                if (*p == '=') {
                    p++;
                    p = eat_ws(conf, p);
                }
                trim_ws(conf, p);
                if (!str_copy(conf, psection, &include, p))
                    goto err;
                /* get the BIO of the included file */
#ifndef OPENSSL_NO_POSIX_IO
                next = process_include(include, &dirctx, &dirpath);
                if (include != dirpath) {
                    /* dirpath will contain include in case of a directory */
                    OPENSSL_free(include);
                }
#else
                next = BIO_new_file(include, "r");
                OPENSSL_free(include);
#endif
                if (next != NULL) {
                    /* push the currently processing BIO onto stack */
                    if (biosk == NULL) {
                        if ((biosk = sk_BIO_new_null()) == NULL) {
                            CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
                            goto err;
                        }
                    }
                    if (!sk_BIO_push(biosk, in)) {
                        CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
                        goto err;
                    }
                    /* continue with reading from the included BIO */
                    in = next;
                }
                continue;
            } else if (*p != '=') {
                CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN);
                goto err;
            }
            *end = '\0';
            p++;
            start = eat_ws(conf, p);
            trim_ws(conf, start);

            if ((v = OPENSSL_malloc(sizeof(*v))) == NULL) {
                CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            v->name = OPENSSL_strdup(pname);
            v->value = NULL;
            if (v->name == NULL) {
                CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            if (!str_copy(conf, psection, &(v->value), start))
                goto err;

            if (strcmp(psection, section) != 0) {
                if ((tv = _CONF_get_section(conf, psection))
                    == NULL)
                    tv = _CONF_new_section(conf, psection);
                if (tv == NULL) {
                    CONFerr(CONF_F_DEF_LOAD_BIO,
                            CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
                    goto err;
                }
            } else
                tv = sv;
            if (_CONF_add_string(conf, tv, v) == 0) {
                CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            v = NULL;
        }
    }
    BUF_MEM_free(buff);
    OPENSSL_free(section);
    /*
     * No need to pop, since we only get here if the stack is empty.
     * If this causes a BIO leak, THE ISSUE IS SOMEWHERE ELSE!
     */
    sk_BIO_free(biosk);
    return 1;
 err:
    BUF_MEM_free(buff);
    OPENSSL_free(section);
    /*
     * Since |in| is the first element of the stack and should NOT be freed
     * here, we cannot use sk_BIO_pop_free().  Instead, we pop and free one
     * BIO at a time, making sure that the last one popped isn't.
     */
    while (sk_BIO_num(biosk) > 0) {
        BIO *popped = sk_BIO_pop(biosk);
        BIO_vfree(in);
        in = popped;
    }
    sk_BIO_free(biosk);
#ifndef OPENSSL_NO_POSIX_IO
    OPENSSL_free(dirpath);
    if (dirctx != NULL)
        OPENSSL_DIR_end(&dirctx);
#endif
    if (line != NULL)
        *line = eline;
    BIO_snprintf(btmp, sizeof(btmp), "%ld", eline);
    ERR_add_error_data(2, "line ", btmp);
    if (h != conf->data) {
        CONF_free(conf->data);
        conf->data = NULL;
    }
    if (v != NULL) {
        OPENSSL_free(v->name);
        OPENSSL_free(v->value);
        OPENSSL_free(v);
    }
    return 0;
}
Beispiel #4
0
Datei: json.c Projekt: 0x0all/mpv
void json_skip_whitespace(char **src)
{
    eat_ws(src);
}
Beispiel #5
0
int krip_init(dictionary *conf)
{
	char *svrname;
	char *vip, *ip, *port, *if_name;
	char *p;
	char *c;
	char file[1024], buf[512];
	FILE *fp;
	struct sockaddr_in sin;
	int listen;

	/* Parse the configuration file. ("HOSTNAME_krip" in the current working directory) */
	svrname = iniparser_getstring(conf, "KENS:server_name", "KENS");

	sprintf(file, "%s_krip", svrname);
	fp = fopen(file, "r");
	if (fp == NULL) {
		_enabled = 0;
		return 0;
	}

	/* Initialize system parameters. */
	_update_time = krip_get_mtime();

	c = iniparser_getstring(conf,"KENS:krip_update_interval","3000");
	_update_interval = atoi(c);

	c = iniparser_getstring(conf,"KENS:krip_timeout","7000");
	_timeout = atoi(c);

	_rip_info_list = list_open();
	_neighbor_info_list = list_open();

	/* Create a UDP socket for RIP communication. */
	if ((_sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
		perror("krip");
		return -1;
	}

	_enabled = 1;

	/* configuration example:
	 * listen 127.0.0.1:9501
	 * 10.1.0.1 seth0 127.0.0.1:9502
	 * 10.1.1.1 seth1 127.0.0.1:9503
	 */

	while (fgets(buf, 512, fp)) {
		p = strchr(buf, '#');
		if (p != NULL) *p = '\0';
		if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = '\0';
		
		p = buf;
		p = eat_ws(p);
		if (p == NULL) continue;

		if (strncmp(buf, "listen", 6) == 0) {
			listen = 1;

			p += 6;
			p = eat_ws(p);
		}
		else {
			listen = 0;
			
			vip = p;
			p = eat_ipaddr(vip);
			*p++ = '\0';
			p = eat_ws(p);

			if_name = p;
			p = eat_alphanum(if_name);
			*p++ = '\0';
			p = eat_ws(p);
		}

		ip = p;
		p = eat_ipaddr(ip);
		*p++ = '\0';
		port = p;
		p = eat_digit(port);

		if (listen)
		{
			/* Setup the RIP listening socket. */
			L_ROUTE("krip_init(): bind to %s:%s", ip, port);
			sin.sin_family = AF_INET;
			inet_aton(ip, &sin.sin_addr);
			sin.sin_port = htons((in_port_t)atoi(port));
			if (bind(_sock, (struct sockaddr *)&sin, sizeof(sin))) {
				perror("krip");
				return -1;
			}
		}
		else
		{
			/* Setup the neighbor information for RIP clients. */
			L_ROUTE("krip_init(): register neighbor %s(%s:%s)", vip, ip, port);
			neighbor_info *ni = (neighbor_info *)malloc(sizeof(neighbor_info));
			inet_aton(vip, &ni->virtual_addr);
			ni->krip_addr.sin_family = AF_INET;
			inet_aton(ip, &ni->krip_addr.sin_addr);
			ni->krip_addr.sin_port = htons((in_port_t)atoi(port));
			ni->ifp = ifunit(if_name);
			if (!ni->ifp) {
				L_ROUTE("krip_init(): invalid interface name: %s", if_name);
				free(ni);
				continue;
			}

			list_add_tail(_neighbor_info_list, ni);
		}
	}

	fclose(fp);

	/* Fetch the routing table entries. */
	list rte_list = rt_query();
	list_position pos;
	uint32_t now = krip_get_mtime();
	for (pos = list_get_head_position(rte_list);
			pos; pos = list_get_next_position(pos)) {
		rtentry *rte = list_get_at(pos);
		for (; rte; rte = (rtentry *)((radix_node *)rte)->rn_dupedkey) {
			if (((radix_node *)rte)->rn_mask == NULL)
				continue;
			if (rte->dst.s_addr == 0x00000000) {
				L_ROUTE("krip_init(): default gw %s", inet_ntoa(rte->gw));
			}
			else if (rte->dst.s_addr == inet_addr("127.0.0.1")) {
			}
			else {
				L_ROUTE("krip_init(): dst %s", inet_ntoa(rte->dst));
				L_ROUTE("krip_init(): mask %s", inet_ntoa(rte->mask));
				L_ROUTE("krip_init(): gw %s", inet_ntoa(rte->gw));

				rip_info *ri = (rip_info *)malloc(sizeof(rip_info));
				ri->assoc_rte = rte;
				ri->metric = 1;
				ri->change_flag = 1;
				ri->timeout = 0;		/* The initial entries will not be expired. */
				ri->from = NULL;
				list_add_tail(_rip_info_list, ri);
			}
		}
	}

	/* Send the initial request packets */
	pos = list_get_head_position(_neighbor_info_list);
	for (; pos; pos = list_get_next_position(pos)) {
		neighbor_info *ni = list_get_at(pos);
		krip_send_request(ni);
	}

	return 0;
}
Beispiel #6
0
/**
 * Parses a character map from file.
 * @param filename Name of the character map file
 * @param map 256-byte buffer where parsed map shall be stored
 * @return 0 if fail, 1 if OK
 */
int charmap_parse(const char *filename, unsigned char *map)
{
    int lineno;
    FILE *fp;
    char line[1024];
    /* Attempt to open the file */
    fp = fopen(filename, "rt");
    if (fp == NULL) {
        return 0;
    }
    /* Reset line counter */
    lineno = 0;
    /* Read mappings */
    while (fgets(line, 1023, fp) != NULL) {
        unsigned char key;
        unsigned char hkey;
        unsigned char value;
        int i;
        /* Increase line number */
        lineno++;
        /* Comment? */
        if (line[0] == '#')
            continue;
        /* Reset line index */
        i = 0;
        /* Read key */
        if (get_key(line, &i, &key) == 0) {
            maperr(filename, lineno, "key expected");
            continue;
        }
        /* Check if this is a range definition */
        if (line[i] == '-') {
            /* Eat - */
            i++;
            /* Read high key */
            if (get_key(line, &i, &hkey) == 0) {
                maperr(filename, lineno, "high limit key expected");
                continue;
            }
            /* Make sure hkey larger or equal to key */
            if (hkey < key) {
                maperr(filename, lineno, "invalid range");
                continue;
            }
        }
        else {
            hkey = key;
        }
        /* Eat whitespace */
        eat_ws(line, &i);
        /* Verify = */
        if (line[i] != '=') {
            maperr(filename, lineno, "`=' expected");
            continue;
        }
        /* Eat = */
        i++;
        /* Eat whitespace */
        eat_ws(line, &i);
        /* Make sure we've not hit end of string */
        if ((line[i] == '\0') || (line[i] == '\n')) {
            maperr(filename, lineno, "value expected");
            return 0;
        }
        /* Read value */
        value = get_value(&line[i]);
        /* Store mapping(s) */
        for (; key <= hkey; key++) {
            map[key] = value++;
        }
    }
    /* Close the file */
    fclose(fp);
    /* Success */
    return 1;
}
Beispiel #7
0
static int def_load_bio(CONF *conf, BIO *in, long *line)
	{
/* The macro BUFSIZE conflicts with a system macro in VxWorks */
#define CONFBUFSIZE	512
	int bufnum=0,i,ii;
	BUF_MEM *buff=NULL;
	char *s,*p,*end;
	int again;
	long eline=0;
	char btmp[DECIMAL_SIZE(eline)+1];
	CONF_VALUE *v=NULL,*tv;
	CONF_VALUE *sv=NULL;
	char *section=NULL,*buf;
	STACK_OF(CONF_VALUE) *section_sk=NULL,*ts __UNUSED;
	char *start,*psection,*pname;
	void *h = (void *)(conf->data);

	if ((buff=BUF_MEM_new()) == NULL)
		{
		CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_BUF_LIB);
		goto err;
		}

	section=(char *)OPENSSL_malloc(10);
	if (section == NULL)
		{
		CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	BUF_strlcpy(section,"default",10);

	if (_CONF_new_data(conf) == 0)
		{
		CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	sv=_CONF_new_section(conf,section);
	if (sv == NULL)
		{
		CONFerr(CONF_F_DEF_LOAD_BIO,
					CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
		goto err;
		}
	section_sk=(STACK_OF(CONF_VALUE) *)sv->value;

	bufnum=0;
	again=0;
	for (;;)
		{
		if (!BUF_MEM_grow(buff,bufnum+CONFBUFSIZE))
			{
			CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_BUF_LIB);
			goto err;
			}
		p= &(buff->data[bufnum]);
		*p='\0';
		BIO_gets(in, p, CONFBUFSIZE-1);
		p[CONFBUFSIZE-1]='\0';
		ii=i=strlen(p);
		if (i == 0 && !again) break;
		again=0;
		while (i > 0)
			{
			if ((p[i-1] != '\r') && (p[i-1] != '\n'))
				break;
			else
				i--;
			}
		/* we removed some trailing stuff so there is a new
		 * line on the end. */
		if (ii && i == ii)
			again=1; /* long line */
		else
			{
			p[i]='\0';
			eline++; /* another input line */
			}

		/* we now have a line with trailing \r\n removed */

		/* i is the number of bytes */
		bufnum+=i;

		v=NULL;
		/* check for line continuation */
		if (bufnum >= 1)
			{
			/* If we have bytes and the last char '\\' and
			 * second last char is not '\\' */
			p= &(buff->data[bufnum-1]);
			if (IS_ESC(conf,p[0]) &&
				((bufnum <= 1) || !IS_ESC(conf,p[-1])))
				{
				bufnum--;
				again=1;
				}
			}
		if (again) continue;
		bufnum=0;
		buf=buff->data;

		clear_comments(conf, buf);
		s=eat_ws(conf, buf);
		if (IS_EOF(conf,*s)) continue; /* blank line */
		if (*s == '[')
			{
			char *ss;

			s++;
			start=eat_ws(conf, s);
			ss=start;
again:
			end=eat_alpha_numeric(conf, ss);
			p=eat_ws(conf, end);
			if (*p != ']')
				{
				if (*p != '\0')
					{
					ss=p;
					goto again;
					}
				CONFerr(CONF_F_DEF_LOAD_BIO,
					CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
				goto err;
				}
			*end='\0';
			if (!str_copy(conf,NULL,&section,start)) goto err;
			if ((sv=_CONF_get_section(conf,section)) == NULL)
				sv=_CONF_new_section(conf,section);
			if (sv == NULL)
				{
				CONFerr(CONF_F_DEF_LOAD_BIO,
					CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
				goto err;
				}
			section_sk=(STACK_OF(CONF_VALUE) *)sv->value;
			continue;
			}
		else
			{
Beispiel #8
0
static int def_load_bio(CONF *conf, BIO *in, long *line)
{
/* The macro BUFSIZE conflicts with a system macro in VxWorks */
#define CONFBUFSIZE     512
    int bufnum = 0, i, ii;
    BUF_MEM *buff = NULL;
    char *s, *p, *end;
    int again;
    long eline = 0;
    char btmp[DECIMAL_SIZE(eline) + 1];
    CONF_VALUE *v = NULL, *tv;
    CONF_VALUE *sv = NULL;
    char *section = NULL, *buf;
    char *start, *psection, *pname;
    void *h = (void *)(conf->data);

    if ((buff = BUF_MEM_new()) == NULL) {
        CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
        goto err;
    }

    section = (char *)OPENSSL_malloc(10);
    if (section == NULL) {
        CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    BUF_strlcpy(section, "default", 10);

    if (_CONF_new_data(conf) == 0) {
        CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    sv = _CONF_new_section(conf, section);
    if (sv == NULL) {
        CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
        goto err;
    }

    bufnum = 0;
    again = 0;
    for (;;) {
        if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) {
            CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
            goto err;
        }
        p = &(buff->data[bufnum]);
        *p = '\0';
        BIO_gets(in, p, CONFBUFSIZE - 1);
        p[CONFBUFSIZE - 1] = '\0';
        ii = i = sgx_strlen(p);
        if (i == 0 && !again)
            break;
        again = 0;
        while (i > 0) {
            if ((p[i - 1] != '\r') && (p[i - 1] != '\n'))
                break;
            else
                i--;
        }
        /*
         * we removed some trailing stuff so there is a new line on the end.
         */
        if (ii && i == ii)
            again = 1;          /* long line */
        else {
            p[i] = '\0';
            eline++;            /* another input line */
        }

        /* we now have a line with trailing \r\n removed */

        /* i is the number of bytes */
        bufnum += i;

        v = NULL;
        /* check for line continuation */
        if (bufnum >= 1) {
            /*
             * If we have bytes and the last char '\\' and second last char
             * is not '\\'
             */
            p = &(buff->data[bufnum - 1]);
            if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) {
                bufnum--;
                again = 1;
            }
        }
        if (again)
            continue;
        bufnum = 0;
        buf = buff->data;

        clear_comments(conf, buf);
        s = eat_ws(conf, buf);
        if (IS_EOF(conf, *s))
            continue;           /* blank line */
        if (*s == '[') {
            char *ss;

            s++;
            start = eat_ws(conf, s);
            ss = start;
 again:
            end = eat_alpha_numeric(conf, ss);
            p = eat_ws(conf, end);
            if (*p != ']') {
                if (*p != '\0' && ss != p) {
                    ss = p;
                    goto again;
                }
                CONFerr(CONF_F_DEF_LOAD_BIO,
                        CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
                goto err;
            }
            *end = '\0';
            if (!str_copy(conf, NULL, &section, start))
                goto err;
            if ((sv = _CONF_get_section(conf, section)) == NULL)
                sv = _CONF_new_section(conf, section);
            if (sv == NULL) {
                CONFerr(CONF_F_DEF_LOAD_BIO,
                        CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
                goto err;
            }
            continue;
        } else {
            pname = s;
            psection = NULL;
            end = eat_alpha_numeric(conf, s);
            if ((end[0] == ':') && (end[1] == ':')) {
                *end = '\0';
                end += 2;
                psection = pname;
                pname = end;
                end = eat_alpha_numeric(conf, end);
            }
            p = eat_ws(conf, end);
            if (*p != '=') {
                CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN);
                goto err;
            }
            *end = '\0';
            p++;
            start = eat_ws(conf, p);
            while (!IS_EOF(conf, *p))
                p++;
            p--;
            while ((p != start) && (IS_WS(conf, *p)))
                p--;
            p++;
            *p = '\0';

            if (!(v = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) {
                CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            if (psection == NULL)
                psection = section;
            v->name = (char *)OPENSSL_malloc(strlen(pname) + 1);
            v->value = NULL;
            if (v->name == NULL) {
                CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            BUF_strlcpy(v->name, pname, sgx_strlen(pname) + 1);
            if (!str_copy(conf, psection, &(v->value), start))
                goto err;

            if (sgx_strcmp(psection, section) != 0) {
                if ((tv = _CONF_get_section(conf, psection))
                    == NULL)
                    tv = _CONF_new_section(conf, psection);
                if (tv == NULL) {
                    CONFerr(CONF_F_DEF_LOAD_BIO,
                            CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
                    goto err;
                }
            } else
                tv = sv;
#if 1
            if (_CONF_add_string(conf, tv, v) == 0) {
                CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
                goto err;
            }
#else
            v->section = tv->section;
            if (!sk_CONF_VALUE_push(ts, v)) {
                CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            vv = (CONF_VALUE *)lh_insert(conf->data, v);
            if (vv != NULL) {
                sk_CONF_VALUE_delete_ptr(ts, vv);
                OPENSSL_free(vv->name);
                OPENSSL_free(vv->value);
                OPENSSL_free(vv);
            }
#endif
            v = NULL;
        }
    }
    if (buff != NULL)
        BUF_MEM_free(buff);
    if (section != NULL)
        OPENSSL_free(section);
    return (1);
 err:
    if (buff != NULL)
        BUF_MEM_free(buff);
    if (section != NULL)
        OPENSSL_free(section);
    if (line != NULL)
        *line = eline;
    BIO_snprintf(btmp, sizeof btmp, "%ld", eline);
    ERR_add_error_data(2, "line ", btmp);
    if ((h != conf->data) && (conf->data != NULL)) {
        CONF_free(conf->data);
        conf->data = NULL;
    }
    if (v != NULL) {
        if (v->name != NULL)
            OPENSSL_free(v->name);
        if (v->value != NULL)
            OPENSSL_free(v->value);
        if (v != NULL)
            OPENSSL_free(v);
    }
    return (0);
}
Beispiel #9
0
    len++;
  }

  item->item.i_string.s[len] = '\0';
  item->item.i_string.len = len;

  return str + cgc_read;
}

char* parse_array(kty_item_t *item, char *str)
{
  kty_item_t *new;

  item->type = KTY_ARRAY;
  item->item.i_array = NULL;
  str = eat_ws(str + 1);
  if (str[0] == ']')
    return str + 1;

  new = (kty_item_t *) malloc(sizeof(kty_item_t));
  if (new == NULL)
    goto fail;
  item->item.i_array = array_create(4, free_kty_item);
  if (item->item.i_array == NULL)
    goto fail;
  str = eat_ws(parse_item(new, eat_ws(str)));
  if (str == NULL)
    goto fail;
  array_append(item->item.i_array, new);
  new = NULL;
Beispiel #10
0
/* ========================================================================= */
int ParseBPUInt(BPUInt *val, char *str)
{
   BPInt nval;
   int isneg = 0;

   /* Walk off leading white space */
   eat_ws(&str);

   if ( *str == '-' )
   {
      isneg = 1;
      str++; /* Move off the '-' char */

      /* Walk off leading white space. Note: This could be an if(), but
         my fear is the extreme edge case of two spaces from the neg to the
         actual number. Technically any amount of white space should be fair
         but I am being somewhat limiting here. */
      eat_ws(&str);

      nval = 0;
      while (( *str >= '0' ) && ( *str <= '9' ))
      {
         nval *= 10;
         nval += ( *str - '0' );
         str++;
      }

      /* Apply the negative sign */
      if ( isneg )
         nval *= -1;

      /* Now convert this to an unsigned value. No special casting, just
         copy the bits over, the meaning of the sign mask will change. */
      memcpy(val, &nval, sizeof(BPUInt));

      eat_ws(&str);

      switch ( *str )
      {
         /* This is end of string */
      case 0:
         /* Other terminating conditions (various maths) */
      case ')':
      case '+':
      case '-':
      case '*':
      case '/':
         /* Syntax */
      case ';':
      case ':':
         /* Space terminated */
      case ' ':
      case '\t':
         return(0);
         break;
      default:
         return(1);
         break;
      }
   }

   if ( *str == '0' )
   {
      *val = 0;

      /* Leading zero of a numeric or hex notation */
      str++;
      if (( *str == 'x' ) || ( *str == 'X' ))
      {
         str++;

         while (( *str != ' ' ) && ( *str != '\t' ) && ( *str != 0 ) && ( *str != ')' ))
         {
            if (( *str >= '0' ) && ( *str <= '9' ))
            {
               *val *= 16;
               *val += (*str - '0');
               str++;
            }
            else if (( *str >= 'a' ) && ( *str <= 'f' ))
            {
               *val *= 16;
               *val += ((*str - 'a') + 10);
               str++;
            }
            else if (( *str >= 'A' ) && ( *str <= 'F' ))
            {
               *val *= 16;
               *val += ((*str - 'A') + 10);
               str++;
            }
            else
            {
               *val = 0;
               return(1);
            }
         }
         
         return(0);
      }

      /* See if the leading zero was the *only* numerid (therefore zero) */
      if (( *str == ' ' ) || ( *str == '\t' ) || ( *str == 0 ) || ( *str == ')' ))
      {
         /* This is a leading zero - that IS zero */
         *val = 0;
         return(0);
      }

      /* If it is a numeric with a leading zero, then fall through to next block */
   }

   if (( *str >= '0' ) && ( *str <= '9' ))
   {
      *val = 0;
      while (( *str >= '0' ) && ( *str <= '9' ))
      {
         *val *= 10;
         *val += ( *str - '0' );
         str++;
      }

      /* TCHNICALLY... if we got this far, we are ok. The numeric is complete
         once we hit white space. The one error condition is if the number is
         followed (immediately - without a space) by any invalid char. For example:
         ...3h      <----- Invalid 3h is not a number, nor a tag, etc...
         ...3+      <----- Could be a mathematical expression
         ...3 4     <----- Is invalid (because 4 has no context), but would NOT
         be flagged as wrong here.
      */

      switch ( *str )
      {
         /* This is end of string */
      case 0:
         /* Other terminating conditions (various maths) */
      case ')':
      case '+':
      case '-':
      case '*':
      case '/':
         /* Syntax */
      case ';':
      case ':':
         /* Space terminated */
      case ' ':
      case '\t':
         return(0);
      default:
         return(1);
      }

      /* Unreachable */
   }

   return(1);
}
Beispiel #11
0
/* ========================================================================= */
int ParseBPInt(BPInt *val, char *str)
{
   int isneg = 0;

   /* Walk off leading white space */
   eat_ws(&str);

   if ( *str == '-' )
   {
      /* This code will fail on large negative values. It does not check the
         range of the input. The ASCII input can overflow the integer.

         The recommended option is to parse as an integer (minus the sign)
         and then store the sign in a separate intger.

         This basically creates a 65 bit integer.

         typedef struct Integer
         {
            uint64_t dfz;       / * Distance From Zero * /
            uint8_t sign;
         } Integer;

         The integer itself can be parsed with strtoull().
         http://pubs.opengroup.org/onlinepubs/9699919799/functions/strtoul.html

         Note that strtoull() will covert both hex and dec input to binary.
      */

      isneg = 1;
      str++; /* Move off the '-' char */

      /* Walk off leading white space. Note: This could be an if(), but
         my fear is the extreme edge case of two spaces from the neg to the
         actual number. Technically any amount of white space should be fair
         but I am being somewhat limiting here. */
      eat_ws(&str);

      *val = 0;
      while (( *str >= '0' ) && ( *str <= '9' ))
      {
         *val *= 10;
         *val += ( *str - '0' );
         str++;
      }

      /* Apply the negative sign */
      if ( isneg )
         *val *= -1;

      eat_ws(&str);

      switch ( *str )
      {
         /* This is end of string */
      case 0:
         /* Other terminating conditions (various maths) */
      case ')':
      case '+':
      case '-':
      case '*':
      case '/':
         /* Syntax */
      case ';':
      case ':':
         /* Space terminated */
      case ' ':
      case '\t':
         return(0);
         break;
      default:
         return(1);
         break;
      }
   }

   if ( *str == '0' )
   {
      *val = 0;

      /* Leading zero of a numeric or hex notation */
      str++;
      if (( *str == 'x' ) || ( *str == 'X' ))
      {
         str++;

         while (( *str != ' ' ) && ( *str != '\t' ) && ( *str != 0 ) && ( *str != ')' ))
         {
            if (( *str >= '0' ) && ( *str <= '9' ))
            {
               *val *= 16;
               *val += (*str - '0');
               str++;
            }
            else if (( *str >= 'a' ) && ( *str <= 'f' ))
            {
               *val *= 16;
               *val += ((*str - 'a') + 10);
               str++;
            }
            else if (( *str >= 'A' ) && ( *str <= 'F' ))
            {
               *val *= 16;
               *val += ((*str - 'A') + 10);
               str++;
            }
            else
            {
               *val = 0;
               return(1);
            }
         }
         
         return(0);
      }

      /* See if the leading zero was the *only* numerid (therefore zero) */
      if (( *str == ' ' ) || ( *str == '\t' ) || ( *str == 0 ) || ( *str == ')' ))
      {
         /* This is a leading zero - that IS zero */
         *val = 0;
         return(0);
      }

      /* If it is a numeric with a leading zero, then fall through to next block */
   }

   if (( *str >= '0' ) && ( *str <= '9' ))
   {
      *val = 0;
      while (( *str >= '0' ) && ( *str <= '9' ))
      {
         *val *= 10;
         *val += ( *str - '0' );
         str++;
      }

      /* TCHNICALLY... if we got this far, we are ok. The numeric is complete
         once we hit white space. The one error condition is if the number is
         followed (immediately - without a space) by any invalid char. For example:
         ...3h      <----- Invalid 3h is not a number, nor a tag, etc...
         ...3+      <----- Could be a mathematical expression
         ...3 4     <----- Is invalid (because 4 has no context), but would NOT
         be flagged as wrong here.
      */

      switch ( *str )
      {
         /* This is end of string */
      case 0:
         /* Other terminating conditions (various maths) */
      case ')':
      case '+':
      case '-':
      case '*':
      case '/':
         /* Syntax */
      case ';':
      case ':':
         /* Space terminated */
      case ' ':
      case '\t':
         return(0);
         break;
      default:
         return(1);
         break;
      }

      /* Unreachable */
   }

   return(1);
}