diff options
author | Russ Allbery <rra@stanford.edu> | 2008-01-19 00:37:31 +0000 |
---|---|---|
committer | Russ Allbery <rra@stanford.edu> | 2008-01-19 00:37:31 +0000 |
commit | aa57ab48cc9df24ab756b5651959b36a2d81cad3 (patch) | |
tree | ff27773218cb6d2677032d18f6872dd45493b82a /client/file.c | |
parent | 275cc7eac5d693bffec19884bf37322df59a871c (diff) |
When downloading a keytab to a file that already exists, merge the new
keytab keys into that file rather than moving aside the old keytab and
creating a new keytab with only the new keys.
Also fix get handling in the client for all types other than keytabs.
This isn't visible yet since the server doesn't yet support other types
of objects.
Diffstat (limited to 'client/file.c')
-rw-r--r-- | client/file.c | 74 |
1 files changed, 62 insertions, 12 deletions
diff --git a/client/file.c b/client/file.c index 8e16103..ce25ab5 100644 --- a/client/file.c +++ b/client/file.c @@ -3,7 +3,7 @@ ** File handling for the wallet client. ** ** Written by Russ Allbery <rra@stanford.edu> -** Copyright 2007 Board of Trustees, Leland Stanford Jr. University +** Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University ** ** See LICENSE for licensing terms. */ @@ -18,28 +18,40 @@ /* ** Given a filename, some data, and a length, write that data to the given -** file safely and atomically by creating file.new, writing the data, linking -** file to file.bak, and then renaming file.new to file. +** file safely, but overwrite any existing file by that name. */ void -write_file(const char *name, const void *data, size_t length) +overwrite_file(const char *name, const void *data, size_t length) { int fd; ssize_t status; - char *temp, *backup; - temp = concat(name, ".new", (char *) 0); - backup = concat(name, ".bak", (char *) 0); - fd = open(temp, O_WRONLY | O_CREAT | O_TRUNC, 0600); + fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (fd < 0) - sysdie("open of %s failed", temp); + sysdie("open of %s failed", name); status = write(fd, data, length); if (status < 0) - sysdie("write to %s failed", temp); + sysdie("write to %s failed", name); else if (status != (ssize_t) length) - die("write to %s truncated", temp); + die("write to %s truncated", name); if (close(fd) < 0) - sysdie("close of %s failed (file probably truncated)", temp); + sysdie("close of %s failed (file probably truncated)", name); +} + + +/* +** Given a filename, some data, and a length, write that data to the given +** file safely and atomically by creating file.new, writing the data, linking +** file to file.bak, and then renaming file.new to file. +*/ +void +write_file(const char *name, const void *data, size_t length) +{ + char *temp, *backup; + + temp = concat(name, ".new", (char *) 0); + backup = concat(name, ".bak", (char *) 0); + overwrite_file(temp, data, length); if (access(name, F_OK) == 0) { if (access(backup, F_OK) == 0) if (unlink(backup) < 0) @@ -52,3 +64,41 @@ write_file(const char *name, const void *data, size_t length) free(temp); free(backup); } + + +/* +** Given a remctl object, the command prefix, object type, and object name, +** and a file (which may be NULL), send a wallet get command and write the +** results to the provided file. If the file is NULL, write the results to +** standard output instead. Returns 0 on success and an exit status on +** failure. +*/ +int +get_file(struct remctl *r, const char *prefix, const char *type, + const char *name, const char *file) +{ + const char *command[5]; + char *data = NULL; + size_t length = 0; + int status; + + command[0] = prefix; + command[1] = "get"; + command[2] = type; + command[3] = name; + command[4] = NULL; + status = run_command(r, command, &data, &length); + if (status != 0) + return status; + if (data == NULL) { + warn("no data returned by wallet server"); + return 255; + } + if (file != NULL) + write_file(file, data, length); + else { + if (fwrite(data, length, 1, stdout) != 1) + sysdie("cannot write to standard output"); + } + return 0; +} |