Coverage Report

Created: 2026-01-10 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdbm/tools/util.c
Line
Count
Source
1
/* This file is part of GDBM, the GNU data base manager.
2
   Copyright (C) 1990-2025 Free Software Foundation, Inc.
3
4
   GDBM is free software; you can redistribute it and/or modify
5
   it under the terms of the GNU General Public License as published by
6
   the Free Software Foundation; either version 3, or (at your option)
7
   any later version.
8
9
   GDBM is distributed in the hope that it will be useful,
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
   GNU General Public License for more details.
13
14
   You should have received a copy of the GNU General Public License
15
   along with GDBM. If not, see <http://www.gnu.org/licenses/>.    */
16
17
#include "gdbmtool.h"
18
#include <pwd.h>
19
20
char *
21
mkfilename (const char *dir, const char *file, const char *suf)
22
0
{
23
0
  char *tmp;
24
0
  size_t dirlen = strlen (dir);
25
0
  size_t suflen = suf ? strlen (suf) : 0;
26
0
  size_t fillen = strlen (file);
27
0
  size_t len;
28
  
29
0
  while (dirlen > 0 && dir[dirlen-1] == '/')
30
0
    dirlen--;
31
32
0
  len = dirlen + (dir[0] ? 1 : 0) + fillen + suflen;
33
0
  tmp = emalloc (len + 1);
34
0
  memcpy (tmp, dir, dirlen);
35
0
  if (dir[0])
36
0
    tmp[dirlen++] = '/';
37
0
  memcpy (tmp + dirlen, file, fillen);
38
0
  if (suf)
39
0
    memcpy (tmp + dirlen + fillen, suf, suflen);
40
0
  tmp[len] = 0;
41
0
  return tmp;
42
0
}
43
44
char *
45
tildexpand (char *s)
46
0
{
47
0
  if (s[0] == '~')
48
0
    {
49
0
      char *p = s + 1;
50
0
      size_t len = strcspn (p, "/");
51
0
      struct passwd *pw;
52
53
0
      if (len == 0)
54
0
  pw = getpwuid (getuid ());
55
0
      else
56
0
  {
57
0
    char *user = emalloc (len + 1);
58
    
59
0
    memcpy (user, p, len);
60
0
    user[len] = 0;
61
0
    pw = getpwnam (user);
62
0
    free (user);
63
0
  }
64
0
      if (pw)
65
0
  return mkfilename (pw->pw_dir, p + len + 1, NULL);
66
0
    }
67
0
  return estrdup (s);
68
0
}
69
70
int
71
vgetyn (const char *prompt, va_list ap)
72
0
{
73
0
  int state = 0;
74
0
  int c, resp;
75
0
  va_list aq;
76
  
77
0
  do
78
0
    {
79
0
      switch (state)
80
0
  {
81
0
  case 1:
82
0
    if (c == ' ' || c == '\t')
83
0
      continue;
84
0
    resp = c;
85
0
    state = 2;
86
    /* fall through */
87
0
  case 2:
88
0
    if (c == '\n')
89
0
      {
90
0
        switch (resp)
91
0
    {
92
0
    case 'y':
93
0
    case 'Y':
94
0
      return 1;
95
0
    case 'n':
96
0
    case 'N':
97
0
      return 0;
98
0
    default:
99
      /* TRANSLATORS: Please, don't translate 'y' and 'n'. */
100
0
      fprintf (stdout, "%s\n", _("Please, reply 'y' or 'n'"));
101
0
    }
102
        /* fall through */
103
0
      }
104
0
    else
105
0
      break;
106
    
107
0
  case 0:
108
0
    va_copy (aq, ap);
109
0
    vfprintf (stdout, prompt, aq);
110
0
    va_end (aq);
111
0
    fprintf (stdout, " [y/n]?");
112
0
    fflush (stdout);
113
0
    state = 1;
114
0
    break;
115
0
  }
116
0
    } while ((c = getchar ()) != EOF);
117
0
  exit (EXIT_USAGE);
118
0
}
119
  
120
int
121
getyn (const char *prompt, ...)
122
0
{
123
0
  va_list ap;
124
0
  int rc;
125
  
126
0
  va_start (ap, prompt);
127
0
  rc = vgetyn (prompt, ap);
128
  va_end (ap);
129
0
  return rc;
130
0
}
131