diff options
| author | Neil Brown <neilb@cse.unsw.edu.au> | 2002-10-11 05:40:19 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-10-11 05:40:19 -0700 |
| commit | 5ce8b167dae710a36cf8ca0aacc456e7f4cb1818 (patch) | |
| tree | f4bddf26f591f80c443886db22aa75951137d69b | |
| parent | 11644e2effeabe4333397d9822a4009624c068ca (diff) | |
[PATCH] kNFSd: Implement get_word to help in parsing cache updates
get_word understands both \x and \012 quoting styles.
| -rw-r--r-- | include/linux/sunrpc/cache.h | 1 | ||||
| -rw-r--r-- | net/sunrpc/cache.c | 61 |
2 files changed, 62 insertions, 0 deletions
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h index 7d9f0bc0f906..8b06312e499a 100644 --- a/include/linux/sunrpc/cache.h +++ b/include/linux/sunrpc/cache.h @@ -273,5 +273,6 @@ extern void cache_drop(struct cache_detail *detail); extern void add_word(char **bpp, int *lp, char *str); extern void add_hex(char **bpp, int *lp, char *buf, int blen); +extern int get_word(char **bpp, char *dest, int bufsize); #endif /* _LINUX_SUNRPC_CACHE_H_ */ diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index ec6b28cbc4de..d401cf6bea94 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -19,6 +19,7 @@ #include <linux/kmod.h> #include <linux/list.h> #include <linux/module.h> +#include <linux/ctype.h> #include <asm/uaccess.h> #include <linux/poll.h> #include <linux/proc_fs.h> @@ -864,3 +865,63 @@ static int cache_make_upcall(struct cache_detail *detail, struct cache_head *h) wake_up(&queue_wait); return 0; } + +/* + * parse a message from user-space and pass it + * to an appropriate cache + * Messages are, like requests, separated into fields by + * spaces and dequotes as \xHEXSTRING or embedded \nnn octal + * + * Message is + * reply cachename expiry key ... content.... + * + * key and content are both parsed by cache + */ + +#define isodigit(c) (isdigit(c) && c <= '7') +int get_word(char **bpp, char *dest, int bufsize) +{ + /* return bytes copied, or -1 on error */ + char *bp = *bpp; + int len = 0; + + while (*bp == ' ') bp++; + + if (bp[0] == '\\' && bp[1] == 'x') { + /* HEX STRING */ + bp += 2; + while (isxdigit(bp[0]) && isxdigit(bp[1]) && len < bufsize) { + int byte = isdigit(*bp) ? *bp-'0' : toupper(*bp)-'A'+10; + bp++; + byte <<= 4; + byte |= isdigit(*bp) ? *bp-'0' : toupper(*bp)-'A'+10; + *dest++ = byte; + bp++; + len++; + } + } else { + /* text with \nnn octal quoting */ + while (*bp != ' ' && *bp && len < bufsize-1) { + if (*bp == '\\' && + isodigit(bp[1]) && (bp[1] <= '3') && + isodigit(bp[2]) && + isodigit(bp[3])) { + int byte = (*++bp -'0'); + bp++; + byte = (byte << 3) | (*bp++ - '0'); + byte = (byte << 3) | (*bp++ - '0'); + *dest++ = byte; + len++; + } else { + *dest++ = *bp++; + len++; + } + } + *dest = '\0'; + } + + *bpp = bp; + if (*bp == ' ' || *bp == '\n' || *bp == '\0') + return len; + return -1; +} |
