GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/uuid.cc Lines: 41 45 91.1 %
Date: 2019-02-03 02:48:13 Branches: 12 14 85.7 %

Line Branch Exec Source
1
/**
2
 * This file is part of the CernVM File System.
3
 *
4
 * UUID generation and caching.
5
 */
6
7
#define __STDC_FORMAT_MACROS
8
9
#include "uuid.h"
10
11
#include <cassert>
12
#include <cstdio>
13
#include <cstring>
14
15
#include "util/pointer.h"
16
#include "util/posix.h"
17
#include "util/string.h"
18
19
using namespace std;  // NOLINT
20
21
namespace cvmfs {
22
23
100363
Uuid *Uuid::Create(const string &store_path) {
24
100363
  UniquePtr<Uuid> uuid(new Uuid());
25
100363
  if (store_path == "") {
26
100166
    uuid->MkUuid();
27
100166
    return uuid.Release();
28
  }
29
30
197
  FILE *f = fopen(store_path.c_str(), "r");
31
197
  if (f == NULL) {
32
    // Create and store
33
123
    uuid->MkUuid();
34
123
    string uuid_str = uuid->uuid();
35
123
    string path_tmp;
36
    FILE *f_tmp = CreateTempFile(store_path + "_tmp",
37
123
      S_IWUSR | S_IWGRP | S_IRUSR | S_IRGRP | S_IROTH, "w", &path_tmp);
38
123
    if (!f_tmp)
39
15
      return NULL;
40
108
    int written = fprintf(f_tmp, "%s\n", uuid_str.c_str());
41
108
    fclose(f_tmp);
42
108
    if (written != static_cast<int>(uuid_str.length() + 1)) {
43
      unlink(path_tmp.c_str());
44
      return NULL;
45
    }
46
108
    if (rename(path_tmp.c_str(), store_path.c_str()) != 0) {
47
      unlink(path_tmp.c_str());
48
      return NULL;
49
    }
50
108
    return uuid.Release();
51
  }
52
53
  // Read from cached file
54
74
  bool retval = GetLineFile(f, &uuid->uuid_);
55
74
  fclose(f);
56
74
  if (!retval)
57
30
    return NULL;
58
  int nitems = sscanf(uuid->uuid_.c_str(),
59
    "%08" SCNx32 "-%04" SCNx16 "-%04" SCNx16 "-%04" SCNx16 "-%08" SCNx32 "%04"
60
      SCNx16,
61
    &uuid->uuid_presentation_.split.a, &uuid->uuid_presentation_.split.b,
62
    &uuid->uuid_presentation_.split.c, &uuid->uuid_presentation_.split.d,
63
44
    &uuid->uuid_presentation_.split.e1, &uuid->uuid_presentation_.split.e2);
64
44
  if (nitems != 6)
65
15
    return NULL;
66
67
29
  return uuid.Release();
68
}
69
70
71
30
string Uuid::CreateOneTime() {
72
30
  Uuid uuid;
73
30
  uuid.MkUuid();
74
30
  return uuid.uuid_;
75
}
76
77
78
/**
79
 * Creates a new UUID in canonical string representation and overwrites uuid_
80
 * with the result.
81
 */
82
100319
void Uuid::MkUuid() {
83
  uuid_t new_uuid;
84
100319
  uuid_generate(new_uuid);
85
  assert(sizeof(new_uuid) == 16);
86
100319
  memcpy(uuid_presentation_.uuid, new_uuid, sizeof(uuid_presentation_.uuid));
87
  // Canonical UUID format, including trailing \0
88
100319
  unsigned uuid_len = 8+1+4+1+4+1+4+1+12+1;
89
100319
  char uuid_cstr[uuid_len];
90
  snprintf(uuid_cstr, uuid_len, "%08x-%04x-%04x-%04x-%08x%04x",
91
           uuid_presentation_.split.a, uuid_presentation_.split.b,
92
           uuid_presentation_.split.c, uuid_presentation_.split.d,
93
100319
           uuid_presentation_.split.e1, uuid_presentation_.split.e2);
94
100319
  uuid_ = string(uuid_cstr);
95
100319
}
96
97
98
100393
Uuid::Uuid() {
99
100393
  memset(&uuid_presentation_, 0, sizeof(uuid_presentation_));
100
100393
}
101
102
}  // namespace cvmfs