Sync with HEAD.
[dragonfly.git] / lib / libcaps / caps_msgbuf.c
blob20b3c40dc14a4da3a7462b6e99bbcc8f479f5596
1 /*
2 * Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
26 * $DragonFly: src/lib/libcaps/caps_msgbuf.c,v 1.1 2004/03/07 23:36:44 dillon Exp $
29 #include "defs.h"
31 void
32 caps_init_msgbuf(caps_msgbuf_t msg, void *data, int size)
34 msg->base = data;
35 msg->index = 0;
36 msg->bufsize = size;
37 msg->error = 0;
40 void
41 caps_msgbuf_error(caps_msgbuf_t msg, int eno, int undo)
43 if (eno)
44 msg->error = eno;
45 if (msg->index < undo)
46 msg->index = 0;
47 else
48 msg->index -= undo;
52 * Extract the next class specification. A class specification is an upper
53 * case letter followed by quoted data or non-quoted data. Non-quoted data
54 * may only contain the characters 0-9 and LOWER CASE a-z, '.', or '_'.
55 * The returned (ptr,len) tuple includes the quotes in quoted data.
57 u_int8_t
58 caps_msgbuf_getclass(caps_msgbuf_t msg, u_int8_t **pptr, int *plen)
60 u_int8_t c;
61 u_int8_t cc;
62 int i;
64 while (msg->index < msg->bufsize) {
65 c = msg->base[msg->index++];
66 if (c >= 'A' && c <= 'Z') {
67 i = msg->index;
68 *pptr = msg->base + i;
69 if (i < msg->bufsize && msg->base[i] == '\"') {
70 for (++i; i < msg->bufsize; ++i) {
71 cc = msg->base[i];
72 if ((cc >= 'a' && cc <= 'z') ||
73 (cc >= 'A' && cc <= 'Z') ||
74 (cc >= '0' && cc <= '9') ||
75 cc == '_' || cc == '.' || cc == '/' || cc == '+' ||
76 cc == '-' || cc == '%'
77 ) {
78 continue;
80 if (cc == '"') /* quote end string, else error */
81 ++i;
82 else
83 msg->error = EINVAL;
84 break;
86 } else {
87 for (; i < msg->bufsize; ++i) {
88 cc = msg->base[i];
89 if (cc >= 'a' && cc <= 'z')
90 continue;
91 if (cc >= '0' && cc <= '9')
92 continue;
93 if (cc == '.' || cc == '_')
94 continue;
95 break;
98 *plen = i - msg->index;
99 msg->index = i;
100 return(c);
102 if (c == ',' || c == '{' || c == '}')
103 return(c);
104 if (c != '\t' && c != ' ' && c != '\r' && c != '\n') {
105 msg->error = EINVAL;
106 break;
108 /* loop on whitespce */
110 return(0);
114 * Support routines for encoding/decoding
116 void
117 caps_msgbuf_printf(caps_msgbuf_t msg, const char *ctl, ...)
119 va_list va;
120 int i;
122 va_start(va, ctl);
123 i = msg->index;
124 if (i <= msg->bufsize)
125 i += vsnprintf(msg->base + i, msg->bufsize - i, ctl, va);
126 else
127 i += vsnprintf(NULL, 0, ctl, va);
128 msg->index = i;
129 va_end(va);