2 * support/nfs/cacheio.c
3 * support IO on the cache channel files in 2.5 and beyond.
4 * These use 'qwords' which are like words, but with a little quoting.
10 * Support routines for text-based upcalls.
11 * Fields are separated by spaces.
12 * Fields are either mangled to quote space tab newline slosh with slosh
13 * or a hexified with a leading \x
14 * Record is terminated with newline.
23 void qword_add(char **bpp, int *lp, char *str)
31 while ((c=*str++) && len)
39 *bp++ = '0' + ((c & 0300)>>6);
40 *bp++ = '0' + ((c & 0070)>>3);
41 *bp++ = '0' + ((c & 0007)>>0);
49 if (c || len <1) len = -1;
58 void qword_addhex(char **bpp, int *lp, char *buf, int blen)
69 while (blen && len >= 2) {
70 unsigned char c = *buf++;
71 *bp++ = '0' + ((c&0xf0)>>4) + (c>=0xa0)*('a'-'9'-1);
72 *bp++ = '0' + (c&0x0f) + ((c&0x0f)>=0x0a)*('a'-'9'-1);
77 if (blen || len<1) len = -1;
86 static char qword_buf[8192];
87 void qword_print(FILE *f, char *str)
90 int len = sizeof(qword_buf);
91 qword_add(&bp, &len, str);
92 fwrite(qword_buf, bp-qword_buf, 1, f);
95 void qword_printhex(FILE *f, char *str, int slen)
98 int len = sizeof(qword_buf);
99 qword_addhex(&bp, &len, str, slen);
100 fwrite(qword_buf, bp-qword_buf, 1, f);
103 void qword_printint(FILE *f, int num)
105 fprintf(f, "%d ", num);
108 void qword_eol(FILE *f)
116 #define isodigit(c) (isdigit(c) && c <= '7')
117 int qword_get(char **bpp, char *dest, int bufsize)
119 /* return bytes copied, or -1 on error */
123 while (*bp == ' ') bp++;
125 if (bp[0] == '\\' && bp[1] == 'x') {
128 while (isxdigit(bp[0]) && isxdigit(bp[1]) && len < bufsize) {
129 int byte = isdigit(*bp) ? *bp-'0' : toupper(*bp)-'A'+10;
132 byte |= isdigit(*bp) ? *bp-'0' : toupper(*bp)-'A'+10;
138 /* text with \nnn octal quoting */
139 while (*bp != ' ' && *bp != '\n' && *bp && len < bufsize-1) {
141 isodigit(bp[1]) && (bp[1] <= '3') &&
144 int byte = (*++bp -'0');
146 byte = (byte << 3) | (*bp++ - '0');
147 byte = (byte << 3) | (*bp++ - '0');
157 if (*bp != ' ' && *bp != '\n' && *bp != '\0')
159 while (*bp == ' ') bp++;
165 int qword_get_int(char **bpp, int *anint)
170 int len = qword_get(bpp, buf, 50);
171 if (len < 0) return -1;
172 if (len ==0) return -1;
173 rv = strtol(buf, &ep, 0);
179 int readline(int fd, char **buf, int *lenp)
181 /* read a line into *buf, which is malloced *len long
182 * realloc if needed until we find a \n
183 * nul out the \n and return
184 * 0 of eof, 1 of success
189 char *b = malloc(128);
195 len = read(fd, *buf, len);
198 while ((*buf)[len-1] != '\n') {
199 /* now the less common case. There was no newline,
200 * so we have to keep reading after re-alloc
205 new = realloc(*buf, *lenp);
208 nl = read(fd, *buf +len, *lenp - len);