diff options
Diffstat (limited to 'client')
| -rw-r--r-- | client/file.c | 20 | ||||
| -rw-r--r-- | client/internal.h | 25 | ||||
| -rw-r--r-- | client/remctl.c | 53 | ||||
| -rw-r--r-- | client/wallet.c | 34 | 
4 files changed, 84 insertions, 48 deletions
| diff --git a/client/file.c b/client/file.c index c9edf3a..66d5f63 100644 --- a/client/file.c +++ b/client/file.c @@ -115,14 +115,13 @@ get_file(struct remctl *r, const char *prefix, const char *type,  /* - * Read all of a file into memory and return the contents as a newly allocated - * string.  Handles a file name of "-" to mean standard input.  Dies on any - * failure. - * - * This will need modification later when we want to handle nul characters. + * Read all of a file into memory and return the contents in newly allocated + * memory.  Returns the size of the file contents in the second argument if + * it's not NULL.  Handles a file name of "-" to mean standard input.  Dies on + * any failure.   */ -char * -read_file(const char *name) +void * +read_file(const char *name, size_t *length)  {      char *contents;      size_t size, offset; @@ -140,7 +139,7 @@ read_file(const char *name)              sysdie("cannot open file %s", name);          if (fstat(fd, &st) < 0)              sysdie("cannot stat file %s", name); -        size = st.st_size + 1; +        size = st.st_size;          contents = xmalloc(size);      }      offset = 0; @@ -157,8 +156,7 @@ read_file(const char *name)          offset += status;      } while (status > 0);      close(fd); -    contents[offset] = '\0'; -    if (memchr(contents, '\0', offset) != NULL) -        die("cannot yet handle file data containing nul characters"); +    if (length != NULL) +        *length = offset;      return contents;  } diff --git a/client/internal.h b/client/internal.h index 7fe962b..d82196c 100644 --- a/client/internal.h +++ b/client/internal.h @@ -17,6 +17,7 @@  /* Forward declarations to avoid unnecessary includes. */  struct remctl; +struct iovec;  BEGIN_DECLS @@ -29,14 +30,18 @@ void kinit(krb5_context, const char *principal);  void kdestroy(void);  /* - * Given a remctl object, run a remctl command.  If data is non-NULL, saves - * the standard output from the command into data with the length in length. - * Otherwise, prints it to standard output.  Either way, prints standard error - * output and errors to standard error and returns the exit status or 255 for - * a remctl internal error. + * Given a remctl object, either a NULL-terminated array of strings or an + * array of iovecs and the number of elements in the array, and optional data + * and size output variables, run a remctl command.  If data is non-NULL, + * saves the standard output from the command into data with the length in + * length.  Otherwise, prints it to standard output.  Either way, prints + * standard error output and errors to standard error and returns the exit + * status or 255 for a remctl internal error.   */  int run_command(struct remctl *, const char **command, char **data,                  size_t *length); +int run_commandv(struct remctl *, const struct iovec *command, size_t count, +                 char **data, size_t *length);  /*   * Check whether an object exists using the exists wallet interface.  Returns @@ -91,12 +96,12 @@ void write_srvtab(krb5_context, const char *srvtab, const char *principal,                    const char *keytab);  /* - * Read all of a file into memory and return the contents as a newly allocated - * string.  Handles a file name of "-" to mean standard input.  Dies on any - * failure.  This will need modification later when we want to handle nul - * characters. + * Read all of a file into memory and return the contents in newly allocated + * memory.  Handles a file name of "-" to mean standard input.  Stores the + * length of the data in the second argument if it isn't NULL.  Dies on any + * failure.   */ -char *read_file(const char *); +void *read_file(const char *, size_t *);  END_DECLS diff --git a/client/remctl.c b/client/remctl.c index a4ff097..5a541d5 100644 --- a/client/remctl.c +++ b/client/remctl.c @@ -18,15 +18,14 @@  /* - * Given a remctl connection and a command, run the command. - * - * If data is non-NULL, save the output in it and return the length in length. - * Otherwise, send any output to stdout.  Either way, send error output to - * stderr, and return the exit status (or 255 if there is an error). + * Retrieve the results of a remctl command, which should be issued prior to + * calling this function.  If data is non-NULL, save the output in it and + * return the length in length.  Otherwise, send any output to stdout.  Either + * way, send error output to stderr, and return the exit status (or 255 if + * there is an error).   */ -int -run_command(struct remctl *r, const char **command, char **data, -            size_t *length) +static int +command_results(struct remctl *r, char **data, size_t *length)  {      struct remctl_output *output;      int status = 255; @@ -35,10 +34,6 @@ run_command(struct remctl *r, const char **command, char **data,          *data = NULL;      if (length != NULL)          *length = 0; -    if (!remctl_command(r, command)) { -        warn("%s", remctl_error(r)); -        return 255; -    }      do {          output = remctl_output(r);          switch (output->type) { @@ -74,6 +69,40 @@ run_command(struct remctl *r, const char **command, char **data,  /* + * Given a remctl connection and a NULL-terminated array of strings, run the + * command and return the results using command_results, optionally putting + * output into the data variable. + */ +int +run_command(struct remctl *r, const char **command, char **data, +            size_t *length) +{ +    if (!remctl_command(r, command)) { +        warn("%s", remctl_error(r)); +        return 255; +    } +    return command_results(r, data, length); +} + + +/* + * Given a remctl connection, an array of iovecs, and the length of the array, + * run the command and return the results using command_results, optionally + * putting output into the data variable. + */ +int +run_commandv(struct remctl *r, const struct iovec *command, size_t count, +             char **data, size_t *length) +{ +    if (!remctl_commandv(r, command, count)) { +        warn("%s", remctl_error(r)); +        return 255; +    } +    return command_results(r, data, length); +} + + +/*   * Check whether an object exists using the exists wallet interface.  Returns   * true if it does, false if it doesn't, and dies on remctl errors.   */ diff --git a/client/wallet.c b/client/wallet.c index ce0f4e7..dc4fe18 100644 --- a/client/wallet.c +++ b/client/wallet.c @@ -135,7 +135,8 @@ main(int argc, char *argv[])      krb5_error_code retval;      struct options options;      int option, i, status; -    const char **command; +    struct iovec *command; +    size_t count, length;      const char *file = NULL;      const char *srvtab = NULL;      struct remctl *r; @@ -241,24 +242,27 @@ main(int argc, char *argv[])              status = get_file(r, options.type, argv[1], argv[2], file);          }      } else { +        count = argc + 1;          if (strcmp(argv[0], "store") == 0) {              if (argc > 4)                  die("too many arguments"); -            else if (argc == 4) -                command = xmalloc(sizeof(char *) * (argc + 2)); -            else -                command = xmalloc(sizeof(char *) * (argc + 3)); -        } else -            command = xmalloc(sizeof(char *) * (argc + 2)); -        command[0] = options.type; -        for (i = 0; i < argc; i++) -            command[i + 1] = argv[i]; +            else if (argc < 4) +                count++; +        } +        command = xmalloc(sizeof(struct iovec) * count); +        command[0].iov_base = (char *) options.type; +        command[0].iov_len = strlen(options.type); +        for (i = 0; i < argc; i++) { +            command[i + 1].iov_base = argv[i]; +            command[i + 1].iov_len = strlen(argv[i]); +        }          if (strcmp(argv[0], "store") == 0 && argc < 4) { -            command[argc + 1] = read_file(file == NULL ? "-" : file); -            command[argc + 2] = NULL; -        } else -            command[argc + 1] = NULL; -        status = run_command(r, command, NULL, NULL); +            if (file == NULL) +                file = "-"; +            command[argc + 1].iov_base = read_file(file, &length); +            command[argc + 1].iov_len = length; +        } +        status = run_commandv(r, command, count, NULL, NULL);      }      remctl_close(r);      krb5_free_context(ctx); | 
