diff options
author | Roland McGrath <roland@gnu.org> | 1999-05-23 17:38:45 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 1999-05-23 17:38:45 +0000 |
commit | 27aac74449762f5fa2e48983afa222750ee0c8a8 (patch) | |
tree | aec17f09ebfd16ac7723ba025dd5681b1e4ff72a | |
parent | 61181c508711aa4b1b0d1f815843d14ad16ca629 (diff) |
1999-05-16 Roland McGrath <roland@baalperazim.frob.com>
* remap.c (remap_decode): Add attribute((unused)) to suppress warning.
1999-05-14 Roland McGrath <roland@baalperazim.frob.com>
* remap.c (remap_open, remap_validate_name): New functions, to support
parsing block lists a la GRUB.
(store_remap_class): Initialize those slots.
-rw-r--r-- | libstore/remap.c | 109 |
1 files changed, 104 insertions, 5 deletions
diff --git a/libstore/remap.c b/libstore/remap.c index aa7c4580..01e84f3a 100644 --- a/libstore/remap.c +++ b/libstore/remap.c @@ -1,6 +1,6 @@ /* Block address translation - Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc. Written by Miles Bader <miles@gnu.ai.mit.edu> This file is part of the GNU Hurd. @@ -18,7 +18,9 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ -#include <malloc.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> #include <hurd/fs.h> #include "store.h" @@ -70,7 +72,7 @@ remap_decode (struct store_enc *enc, const struct store_class *const *classes, return EINVAL; else { - int type = enc->ints[enc->cur_int++]; + int type __attribute__((unused)) = enc->ints[enc->cur_int++]; int flags = enc->ints[enc->cur_int++]; int num_runs = enc->ints[enc->cur_int++]; error_t create_remap (const struct store_run *runs, size_t num_runs) @@ -85,12 +87,109 @@ remap_decode (struct store_enc *enc, const struct store_class *const *classes, } } +error_t +remap_open (const char *name, int flags, + const struct store_class *const *classes, + struct store **store) +{ + error_t err; + struct store *from; + const char *end, *p; + struct store_run *runs; + size_t nruns; + + end = strchr (name, ':'); + if (!end) + return EINVAL; + + runs = alloca ((end - name) * sizeof runs[0]); + + nruns = 0; + p = name; + do + { + char *endp; + runs[nruns].start = strtoul (p, &endp, 0) * 512; /* ? */ + if (*endp == '+') + { + if (endp == p) /* Syntax "+5,+7" means "0+5,0+7". */ + runs[nruns].start = 0; + p = endp + 1; + runs[nruns].length = strtoul (p, &endp, 0) * 512; + if (endp == p) + return EINVAL; + } + else if (endp == p) /* Must have a number unless starts with +. */ + return EINVAL; + else + runs[nruns].length = 512; + ++nruns; + p = endp; + if (*p == ',') + ++p; + } while (p < end); + + + err = store_typed_open (end + 1, flags, classes, &from); + if (!err) + { + err = store_remap (from, runs, nruns, store); + if (err) + store_free (from); + } + return err; +} + +error_t +remap_validate_name (const char *name, + const struct store_class *const *classes) +{ + const char *end = strchr (name, ':'); + const char *p; + + if (!end) + return EINVAL; + + p = name; + do + { + if (*p != '+') + { + if (!isdigit (*p)) + return EINVAL; + do + ++p; + while (isdigit (*p)); + } + + if (*p == '+') + { + ++p; + if (!isdigit (*p)) + return EINVAL; + do + ++p; + while (isdigit (*p)); + } + + if (*p == ',') + ++p; + else if (*p == ':') + return 0; + } while (*p != '\0'); + + return EINVAL; +} + + struct store_class store_remap_class = { STORAGE_REMAP, "remap", remap_read, remap_write, remap_allocate_encoding, remap_encode, remap_decode, - store_set_child_flags, store_clear_child_flags + store_set_child_flags, store_clear_child_flags, + NULL, NULL, NULL, /* cleanup, clone, remap */ + remap_open, remap_validate_name }; /* Return a new store in STORE that reflects the blocks in RUNS & RUNS_LEN @@ -153,7 +252,7 @@ store_remap_runs (const struct store_run *runs, size_t num_runs, for (i = 0; i < num_runs; i++) { off_t addr = runs[i].start, left = runs[i].length; - + if (addr >= 0) for (j = 0; j < num_base_runs && left > 0; j++) { |