X-Git-Url: http://git.vrable.net/?p=cumulus.git;a=blobdiff_plain;f=util.cc;h=f89569b31483ec06fff1fa998e1f8ec693d0f2f8;hp=b595eea602f1f11f9e76958afd5efe4a04501c85;hb=HEAD;hpb=915e73b3fa1f245541611f26268cdd574798e1e2 diff --git a/util.cc b/util.cc index b595eea..f89569b 100644 --- a/util.cc +++ b/util.cc @@ -1,7 +1,6 @@ -/* Cumulus: Smart Filesystem Backup to Dumb Servers - * - * Copyright (C) 2007 The Regents of the University of California - * Written by Michael Vrable +/* Cumulus: Efficient Filesystem Backup to the Cloud + * Copyright (C) 2007-2008 The Cumulus Developers + * See the AUTHORS file for a list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,8 +20,11 @@ /* Utility functions for converting various datatypes to text format (and * later, for parsing them back, perhaps). */ +#include #include #include +#include +#include #include #include @@ -30,10 +32,31 @@ #include #include +#include "util.h" + using std::map; using std::ostream; using std::string; +/* Like sprintf, but returns the output as an allocated string. */ +string string_printf(const char *fmt, ...) +{ + va_list args; + char *output = NULL; + string result; + + va_start(args, fmt); + if (vasprintf(&output, fmt, args) < 0) { + /* TODO: Error signalling? */ + return result; + } + result = output; + va_end(args); + + free(output); + return result; +} + /* Perform URI-style escaping of a string. Bytes which cannot be represented * directly are encoded in the form %xx (where "xx" is a string of two * hexadecimal digits). */ @@ -93,20 +116,12 @@ string uri_decode(const string &in) * advisory. For negative numbers, will always use decimal. */ string encode_int(long long n, int base) { - char buf[64]; - - if (n >= 0 && base == 16) { - sprintf(buf, "0x%llx", n); - return buf; - } - - if (n > 0 && base == 8) { - sprintf(buf, "0%llo", n); - return buf; - } - - sprintf(buf, "%lld", n); - return buf; + if (n >= 0 && base == 16) + return string_printf("0x%llx", n); + else if (n > 0 && base == 8) + return string_printf("0%llo", n); + else + return string_printf("%lld", n); } /* Parse the string representation of an integer. Accepts decimal, octal, and @@ -115,3 +130,42 @@ long long parse_int(const string &s) { return strtoll(s.c_str(), NULL, 0); } + +/* Mark a file descriptor as close-on-exec. */ +void cloexec(int fd) +{ + long flags = fcntl(fd, F_GETFD); + + if (flags < 0) + return; + + fcntl(fd, F_SETFD, flags | FD_CLOEXEC); +} + +/* Report a fatal error and exit. */ +void fatal(string msg) +{ + fprintf(stderr, "FATAL: %s\n", msg.c_str()); + exit(1); +} + +/* Available time formats. */ +const char TimeFormat::FORMAT_FILENAME[] = "%Y%m%dT%H%M%S"; +const char TimeFormat::FORMAT_ISO8601[] = "%Y-%m-%d %H:%M:%S"; +const char TimeFormat::FORMAT_LOCALTIME[] = "%Y-%m-%d %H:%M:%S %z"; + +static size_t MAX_TIMESTAMP_LENGTH = 1024; + +std::string TimeFormat::format(time_t timestamp, const char *format, bool utc) +{ + struct tm time_buf; + + if (utc) + gmtime_r(×tamp, &time_buf); + else + localtime_r(×tamp, &time_buf); + + char buffer[MAX_TIMESTAMP_LENGTH]; + strftime(buffer, MAX_TIMESTAMP_LENGTH, format, &time_buf); + return string(buffer); +}