2 Copyright (c) 2004 The Regents of the University of Michigan.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 2. Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 3. Neither the name of the University nor the names of its
15 contributors may be used to endorse or promote products derived
16 from this software without specific prior written permission.
18 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * support/nfs/cacheio.c
33 * support IO on the cache channel files in 2.5 and beyond.
34 * These use 'qwords' which are like words, but with a little quoting.
40 * Support routines for text-based upcalls.
41 * Fields are separated by spaces.
42 * Fields are either mangled to quote space tab newline slosh with slosh
43 * or a hexified with a leading \x
44 * Record is terminated with newline.
52 #include <sys/types.h>
61 void qword_add(char **bpp, int *lp, char *str)
69 while ((c=*str++) && len)
77 *bp++ = '0' + ((c & 0300)>>6);
78 *bp++ = '0' + ((c & 0070)>>3);
79 *bp++ = '0' + ((c & 0007)>>0);
87 if (c || len <1) len = -1;
96 void qword_addhex(char **bpp, int *lp, char *buf, int blen)
107 while (blen && len >= 2) {
108 unsigned char c = *buf++;
109 *bp++ = '0' + ((c&0xf0)>>4) + (c>=0xa0)*('a'-'9'-1);
110 *bp++ = '0' + (c&0x0f) + ((c&0x0f)>=0x0a)*('a'-'9'-1);
115 if (blen || len<1) len = -1;
124 void qword_addint(char **bpp, int *lp, int n)
128 len = snprintf(*bpp, *lp, "%d ", n);
135 void qword_addeol(char **bpp, int *lp)
144 static char qword_buf[8192];
145 static char tmp_buf[8192];
146 void qword_print(FILE *f, char *str)
148 char *bp = qword_buf;
149 int len = sizeof(qword_buf);
150 qword_add(&bp, &len, str);
151 fwrite(qword_buf, bp-qword_buf, 1, f);
153 memcpy(tmp_buf, qword_buf, bp-qword_buf);
154 tmp_buf[bp-qword_buf] = '\0';
155 printerr(2, "%s", tmp_buf);
158 void qword_printhex(FILE *f, char *str, int slen)
160 char *bp = qword_buf;
161 int len = sizeof(qword_buf);
162 qword_addhex(&bp, &len, str, slen);
163 fwrite(qword_buf, bp-qword_buf, 1, f);
165 memcpy(tmp_buf, qword_buf, bp-qword_buf);
166 tmp_buf[bp-qword_buf] = '\0';
167 printerr(2, "%s", tmp_buf);
170 void qword_printint(FILE *f, int num)
172 fprintf(f, "%d ", num);
173 printerr(2, "%d ", num);
176 void qword_eol(FILE *f)
185 #define isodigit(c) (isdigit(c) && c <= '7')
186 int qword_get(char **bpp, char *dest, int bufsize)
188 /* return bytes copied, or -1 on error */
192 while (*bp == ' ') bp++;
194 if (bp[0] == '\\' && bp[1] == 'x') {
197 while (isxdigit(bp[0]) && isxdigit(bp[1]) && len < bufsize) {
198 int byte = isdigit(*bp) ? *bp-'0' : toupper(*bp)-'A'+10;
201 byte |= isdigit(*bp) ? *bp-'0' : toupper(*bp)-'A'+10;
207 /* text with \nnn octal quoting */
208 while (*bp != ' ' && *bp != '\n' && *bp && len < bufsize-1) {
210 isodigit(bp[1]) && (bp[1] <= '3') &&
213 int byte = (*++bp -'0');
215 byte = (byte << 3) | (*bp++ - '0');
216 byte = (byte << 3) | (*bp++ - '0');
226 if (*bp != ' ' && *bp != '\n' && *bp != '\0')
228 while (*bp == ' ') bp++;
230 // why should we clear *dest???
235 int qword_get_int(char **bpp, int *anint)
240 int len = qword_get(bpp, buf, 50);
241 if (len < 0) return -1;
242 if (len ==0) return -1;
243 rv = strtol(buf, &ep, 0);
249 #define READLINE_BUFFER_INCREMENT 2048
251 int readline(int fd, char **buf, int *lenp)
253 /* read a line into *buf, which is malloced *len long
254 * realloc if needed until we find a \n
255 * nul out the \n and return
256 * 0 of eof, 1 of success
261 char *b = malloc(READLINE_BUFFER_INCREMENT);
265 *lenp = READLINE_BUFFER_INCREMENT;
267 len = read(fd, *buf, *lenp);
269 printerr(0, "readline: read error: len %d errno %d (%s)\n",
270 len, errno, strerror(errno));
273 while ((*buf)[len-1] != '\n') {
274 /* now the less common case. There was no newline,
275 * so we have to keep reading after re-alloc
279 *lenp += READLINE_BUFFER_INCREMENT;
280 new = realloc(*buf, *lenp);
284 nl = read(fd, *buf +len, *lenp - len);
286 printerr(0, "readline: read error: len %d "
287 "errno %d (%s)\n", nl, errno, strerror(errno));
293 printerr(3, "readline: read %d chars into buffer of size %d:\n%s\n",