Example #1
0
File: tags.c Project: flrl/goat
GoatError goat_message_get_tag_value(
    const GoatMessage *message, const char *key, char *value, size_t *size
) {
    if (NULL == message) return EINVAL;
    if (NULL == key) return EINVAL;
    if (NULL == value) return EINVAL;
    if (NULL == size) return EINVAL;

    const MessageTags *tags = message->m_tags;

    if (NULL == tags || 0 == strlen(tags->m_bytes)) return GOAT_E_NOTAG;

    const char *p, *v, *end;

    p = _find_tag(tags->m_bytes, key);
    if (NULL == p) return GOAT_E_NOTAG;

    v = _find_value(p);
    if (NULL == v) return GOAT_E_NOTAGVAL;

    end = _next_tag(v);
    if ('\0' != *end) end--; // account for separator

    char unescaped[GOAT_MESSAGE_MAX_TAGS];
    size_t unescaped_len = sizeof(unescaped);
    _unescape_value(v, unescaped, &unescaped_len);

    if (*size <= unescaped_len) return EOVERFLOW;

    memset(value, 0, *size);
    strncpy(value, unescaped, unescaped_len);
    *size = unescaped_len;

    return 0;
}
    /*
     * Find the last tag in the tag list.
     */
    static inline NkTagHeader*
_find_last_tag (NkTagHeader* t)
{
    while (t->size != 0) {
	t = _next_tag(t);
    }
    return t;
}
    /*
     * Remove a tag from the tag list
     */
    void
remove_tag (NkTagHeader* t)
{
    NkTagHeader* next;
    nku32_f	 size;

    next = _next_tag(t);
    size = tags_len(next);
    memcpy(t, next, size);
}
    /*
     * Find a tag in the tag list
     */
    NkTagHeader*
find_tag (NkTagHeader* t, nku32_f tag)
{
    while (t->size != 0) {
	if (t->tag == tag) {
	    return t;
	}
	t = _next_tag(t);
    }
    return 0;
}
    /*
     * Add a command line tag to the tag list.
     * Check if the resulting tag list exceeds its size limit.
     * Return added tag.
     */
    NkTagHeader*
add_cmd_line_tag (NkTagHeader* t, char* cmd_line, nku32_f limit)
{
    NkTagHeader* last;
    NkTagHeader* cmdl;
    NkTagHeader	 ltag;
    nku32_f	 size;

    last = _find_last_tag(t);
    ltag = *last;

	/*
	 * Calculate new tag size (at first in bytes, then in words)
	 */
    size = strlen(cmd_line) + 1 + sizeof(NkTagHeader);
    size = (size + sizeof(nku32_f) - 1)/sizeof(nku32_f);

	/*
	 * Check for overflow
	 */
    if (_tags_len(t, last) + size * sizeof(nku32_f) > limit) {
	return 0;
    }

	/*
	 * Add a new command line tag
	 */
    last->tag  = ATAG_CMDLINE;
    last->size = size;
    strcpy((char*)(last+1), cmd_line);
    cmdl = last;

	/*
	 * Add a termination tag
	 */
    last = _next_tag(last);
    *last = ltag;

    return cmdl;
}
Example #6
0
File: tags.c Project: flrl/goat
const char *_find_tag(const char *str, const char *key) {
    assert(str != NULL);
    assert(key != NULL);

    const char *p = str;
    const size_t key_len = strlen(key);

    while (*p) {
        if (0 == strncmp(p, key, key_len)) {
            switch (*(p + key_len)) {
                case '\0':
                case '=':
                case ';':
                    return p;
            }
        }

        p = _next_tag(p);
    }

    return NULL;
}
    /*
     * Add an init ram disk tag to the tag list.
     * Check if the resulting tag list exceeds its size limit.
     * Return added tag.
     */
    NkTagHeader*
add_ram_disk_tag (NkTagHeader* t, NkPhAddr start, NkPhSize size, nku32_f limit)
{
    NkTagHeader* last;
    NkTagHeader* rdsk;
    NkTagHeader	 ltag;
    nku32_f*	 tag;

    last = _find_last_tag(t);
    ltag = *last;

	/*
	 * Check for overflow
	 */
    if (_tags_len(t, last) + sizeof(NkTagHeader) + 2*sizeof(nku32_f) > limit) {
	return 0;
    }

	/*
	 * Add a new initrd tag
	 */
    last->tag  = ATAG_INITRD2;
    last->size = sizeof(NkTagHeader)/sizeof(nku32_f) + 2;

    tag    = (nku32_f*)(last+1);
    tag[0] = start;
    tag[1] = size;

    rdsk = last;

	/*
	 * Add a termination tag
	 */
    last = _next_tag(last);
    *last = ltag;

    return rdsk;
}
Example #8
0
File: tags.c Project: flrl/goat
GoatError goat_message_unset_tag(GoatMessage *message, const char *key) {
    if (NULL == message) return EINVAL;
    if (NULL == key) return EINVAL;

    MessageTags *tags = message->m_tags;

    if (NULL == tags || 0 == strlen(tags->m_bytes)) return 0;

    char *p1, *p2, *end;

    end = &tags->m_bytes[tags->m_len];

    p1 = (char *) _find_tag(tags->m_bytes, key);
    if (p1[0] == '\0') return 0;
    // => p1 is the start of the tag to be replaced

    p2 = (char *) _next_tag(p1);
    // => p2 is the start of the rest of the string (if any)

    if (p2[0] != '\0') {
        memmove(p1, p2, end - p2);
        tags->m_len -= (p2 - p1);
        memset(&tags->m_bytes[tags->m_len], 0, sizeof(tags->m_bytes) - tags->m_len);
    }
    else {
        tags->m_len = p1 - tags->m_bytes;
        memset(p1, 0, sizeof(tags->m_bytes) - tags->m_len);
    }

    // may be a trailing semicolon if tag removed from end, chomp it
    if (tags->m_bytes[tags->m_len - 1] == ';') {
        tags->m_bytes[-- tags->m_len] = '\0';
    }

    return 0;
}
    /*
     * Dump a tag list
     */
    void
dump_taglist(NkTagHeader* t)
{
    if (t->tag != ATAG_CORE) {
	printk("No tag list found at 0x%08x\n", (unsigned int)t);
	return;
    }

    printk(" === dump tag list at 0x%08x ===\n", (unsigned int)t);
    for (;;) {
	printk(" tag = 0x%08x  size = 0x%08x\n", t->tag, t->size);

	if (t->size == 0) break;

	switch (t->tag) {
	  case ATAG_CORE: {
	    nku32_f* tag = (nku32_f*)(t+1);
	    printk("   core tag:      0x%08x 0x%08x 0x%08x\n",
		      tag[0], tag[1], tag[2]);
	    break;
	  }
	  case ATAG_CMDLINE: {
	    printk("   cmd line tag:  <%s>\n", (char*)(t+1));
	    break;
	  }
	  case ATAG_MEM: {
	    nku32_f* tag = (nku32_f*)(t+1);
	    printk("   mem chunk tag: start = 0x%08x size = 0x%08x\n",
		      tag[1], tag[0]);
	    break;
	  }
	  case ATAG_RAMDISK: {
	    nku32_f* tag = (nku32_f*)(t+1);
	    printk("   ram disk tag:  start = 0x%08x size = 0x%08x"
		      " flags =%d\n", tag[2], tag[1], tag[0]);
	    break;
	  }
	  case ATAG_INITRD: {
	    nku32_f* tag = (nku32_f*)(t+1);
	    printk("   initrd tag:    start = 0x%08x size = 0x%08x\n",
		      tag[0], tag[1]);
	    break;
	  }
	  case ATAG_INITRD2: {
	    nku32_f* tag = (nku32_f*)(t+1);
	    printk("   initrd2 tag:   start = 0x%08x size = 0x%08x\n",
		      tag[0], tag[1]);
	    break;
	  }
	  case ATAG_SERIAL: {
	    nku32_f* tag = (nku32_f*)(t+1);
	    printk("   serial number:  0x%08x%08x\n", tag[1], tag[0]);
	    break;
	  }
	  case ATAG_REVISION: {
	    nku32_f* tag = (nku32_f*)(t+1);
	    printk("   board revision: 0x%08x\n", tag[0]);
	    break;
	  }
	  case ATAG_ARCH_ID: {
	    nku32_f* tag = (nku32_f*)(t+1);
	    printk("   arch id tag:    %d\n", tag[0]);
	    break;
	  }
	  case ATAG_MAP_DESC: {
	    nku32_f* tag = (nku32_f*)(t+1);
	    printk("   map desc tag:   pstart = 0x%08x plimit = 0x%08x\n",
		      tag[0], tag[1]);
	    printk("                   vstart = 0x%08x pte_attr = 0x%03x\n",
		      tag[2], tag[3]);
	    printk("                   mem_type = %d mem_owner = %d\n",
		      tag[4], tag[5]);
	    break;
	  }
	  case ATAG_TAG_REF: {
	    nku32_f* tag = (nku32_f*)(t+1);
	    printk("   tag ref:        addr = 0x%08x\n", tag[0]);
	    break;
	  }
	}

	t = _next_tag(t);
    }
    printk("\n");
}
    /*
     * Next tag in the tag list
     */
    NkTagHeader*
next_tag(NkTagHeader* t)
{
    return _next_tag(t);
}