Coverage Report

Created: 2022-12-08 06:10

/src/gnupg/common/mischelp.c
Line
Count
Source (jump to first uncovered line)
1
/* mischelp.c - Miscellaneous helper functions
2
 * Copyright (C) 1998, 2000, 2001, 2006, 2007 Free Software Foundation, Inc.
3
 *
4
 * This file is part of GnuPG.
5
 *
6
 * GnuPG is free software; you can redistribute and/or modify this
7
 * part of GnuPG under the terms of either
8
 *
9
 *   - the GNU Lesser General Public License as published by the Free
10
 *     Software Foundation; either version 3 of the License, or (at
11
 *     your option) any later version.
12
 *
13
 * or
14
 *
15
 *   - the GNU General Public License as published by the Free
16
 *     Software Foundation; either version 2 of the License, or (at
17
 *     your option) any later version.
18
 *
19
 * or both in parallel, as here.
20
 *
21
 * GnuPG is distributed in the hope that it will be useful, but
22
 * WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24
 * General Public License for more details.
25
 *
26
 * You should have received a copies of the GNU General Public License
27
 * and the GNU Lesser General Public License along with this program;
28
 * if not, see <https://www.gnu.org/licenses/>.
29
 */
30
31
#include <config.h>
32
#include <stdlib.h>
33
#include <string.h>
34
#include <time.h>
35
#ifdef HAVE_W32_SYSTEM
36
# define WIN32_LEAN_AND_MEAN
37
# include <windows.h>
38
#else /*!HAVE_W32_SYSTEM*/
39
# include <sys/types.h>
40
# include <sys/stat.h>
41
# include <unistd.h>
42
#endif /*!HAVE_W32_SYSTEM*/
43
#include <errno.h>
44
45
#include "util.h"
46
#include "common-defs.h"
47
#include "stringhelp.h"
48
#include "utf8conv.h"
49
#include "mischelp.h"
50
51
52
void
53
wipememory (void *ptr, size_t len)
54
0
{
55
#if defined(HAVE_W32_SYSTEM) && defined(SecureZeroMemory)
56
  SecureZeroMemory (ptr, len);
57
#elif defined(HAVE_EXPLICIT_BZERO)
58
0
  explicit_bzero (ptr, len);
59
#else
60
  /* Prevent compiler from optimizing away the call to memset by accessing
61
     memset through volatile pointer. */
62
  static void *(*volatile memset_ptr)(void *, int, size_t) = (void *)memset;
63
  memset_ptr (ptr, 0, len);
64
#endif
65
0
}
66
67
68
/* Check whether the files NAME1 and NAME2 are identical.  This is for
69
   example achieved by comparing the inode numbers of the files.  */
70
int
71
same_file_p (const char *name1, const char *name2)
72
0
{
73
0
  int yes;
74
75
  /* First try a shortcut.  */
76
0
  if (!compare_filenames (name1, name2))
77
0
    yes = 1;
78
0
  else
79
0
    {
80
#ifdef HAVE_W32_SYSTEM
81
      HANDLE file1, file2;
82
      BY_HANDLE_FILE_INFORMATION info1, info2;
83
      wchar_t *wname;
84
85
      wname = gpgrt_fname_to_wchar (name1);
86
      if (wname)
87
        {
88
          file1 = CreateFileW (wname, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
89
          xfree (wname);
90
        }
91
      else
92
        file1 = INVALID_HANDLE_VALUE;
93
94
      if (file1 == INVALID_HANDLE_VALUE)
95
        yes = 0; /* If we can't open the file, it is not the same.  */
96
      else
97
        {
98
          wname = gpgrt_fname_to_wchar (name2);
99
          if (wname)
100
            {
101
              file2 = CreateFileW (wname, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
102
              xfree (wname);
103
            }
104
          else
105
            file2 = INVALID_HANDLE_VALUE;
106
107
          if (file2 == INVALID_HANDLE_VALUE)
108
            yes = 0; /* If we can't open the file, it is not the same.  */
109
          else
110
            {
111
              yes = (GetFileInformationByHandle (file1, &info1)
112
                     && GetFileInformationByHandle (file2, &info2)
113
                     && info1.dwVolumeSerialNumber==info2.dwVolumeSerialNumber
114
                     && info1.nFileIndexHigh == info2.nFileIndexHigh
115
                     && info1.nFileIndexLow == info2.nFileIndexLow);
116
              CloseHandle (file2);
117
            }
118
          CloseHandle (file1);
119
        }
120
#else /*!HAVE_W32_SYSTEM*/
121
0
      struct stat info1, info2;
122
123
0
      yes = (!stat (name1, &info1) && !stat (name2, &info2)
124
0
             && info1.st_dev == info2.st_dev && info1.st_ino == info2.st_ino);
125
0
#endif /*!HAVE_W32_SYSTEM*/
126
0
    }
127
0
  return yes;
128
0
}
129
130
131
/*
132
  timegm() is a GNU function that might not be available everywhere.
133
  It's basically the inverse of gmtime() - you give it a struct tm,
134
  and get back a time_t.  It differs from mktime() in that it handles
135
  the case where the struct tm is UTC and the local environment isn't.
136
137
  Note, that this replacement implementation might not be thread-safe!
138
139
  Some BSDs don't handle the putenv("foo") case properly, so we use
140
  unsetenv if the platform has it to remove environment variables.
141
*/
142
#ifndef HAVE_TIMEGM
143
time_t
144
timegm (struct tm *tm)
145
{
146
#ifdef HAVE_W32_SYSTEM
147
  /* This one is thread safe.  */
148
  SYSTEMTIME st;
149
  FILETIME ft;
150
  unsigned long long cnsecs;
151
152
  st.wYear   = tm->tm_year + 1900;
153
  st.wMonth  = tm->tm_mon  + 1;
154
  st.wDay    = tm->tm_mday;
155
  st.wHour   = tm->tm_hour;
156
  st.wMinute = tm->tm_min;
157
  st.wSecond = tm->tm_sec;
158
  st.wMilliseconds = 0; /* Not available.  */
159
  st.wDayOfWeek = 0;    /* Ignored.  */
160
161
  /* System time is UTC thus the conversion is pretty easy.  */
162
  if (!SystemTimeToFileTime (&st, &ft))
163
    {
164
      gpg_err_set_errno (EINVAL);
165
      return (time_t)(-1);
166
    }
167
168
  cnsecs = (((unsigned long long)ft.dwHighDateTime << 32)
169
            | ft.dwLowDateTime);
170
  cnsecs -= 116444736000000000ULL; /* The filetime epoch is 1601-01-01.  */
171
  return (time_t)(cnsecs / 10000000ULL);
172
173
#else /* (Non thread safe implementation!) */
174
175
  time_t answer;
176
  char *zone;
177
178
  zone=getenv("TZ");
179
  putenv("TZ=UTC");
180
  tzset();
181
  answer=mktime(tm);
182
  if(zone)
183
    {
184
      static char *old_zone;
185
186
      if (!old_zone)
187
        {
188
          old_zone = malloc(3+strlen(zone)+1);
189
          if (old_zone)
190
            {
191
              strcpy(old_zone,"TZ=");
192
              strcat(old_zone,zone);
193
            }
194
  }
195
      if (old_zone)
196
        putenv (old_zone);
197
    }
198
  else
199
    gnupg_unsetenv("TZ");
200
201
  tzset();
202
  return answer;
203
#endif
204
}
205
#endif /*!HAVE_TIMEGM*/